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
31 #include <sys/types.h>
37 #include <sys/mount.h>
38 #include <sys/prctl.h>
39 #include <sys/resource.h>
45 int __clone2(int (*fn
)(void *), void *child_stack_base
,
46 size_t stack_size
, int flags
, void *arg
, ...);
48 #include <sys/socket.h>
52 #include <sys/times.h>
55 #include <sys/statfs.h>
57 #include <sys/sysinfo.h>
58 #include <sys/utsname.h>
59 //#include <sys/user.h>
60 #include <netinet/ip.h>
61 #include <netinet/tcp.h>
62 #include <linux/wireless.h>
63 #include <linux/icmp.h>
64 #include "qemu-common.h"
69 #include <sys/eventfd.h>
72 #include <sys/epoll.h>
75 #include "qemu-xattr.h"
78 #define termios host_termios
79 #define winsize host_winsize
80 #define termio host_termio
81 #define sgttyb host_sgttyb /* same as target */
82 #define tchars host_tchars /* same as target */
83 #define ltchars host_ltchars /* same as target */
85 #include <linux/termios.h>
86 #include <linux/unistd.h>
87 #include <linux/utsname.h>
88 #include <linux/cdrom.h>
89 #include <linux/hdreg.h>
90 #include <linux/soundcard.h>
92 #include <linux/mtio.h>
94 #if defined(CONFIG_FIEMAP)
95 #include <linux/fiemap.h>
99 #include <linux/dm-ioctl.h>
100 #include "linux_loop.h"
101 #include "cpu-uname.h"
105 #if defined(CONFIG_USE_NPTL)
106 #define CLONE_NPTL_FLAGS2 (CLONE_SETTLS | \
107 CLONE_PARENT_SETTID | CLONE_CHILD_SETTID | CLONE_CHILD_CLEARTID)
109 /* XXX: Hardcode the above values. */
110 #define CLONE_NPTL_FLAGS2 0
115 //#include <linux/msdos_fs.h>
116 #define VFAT_IOCTL_READDIR_BOTH _IOR('r', 1, struct linux_dirent [2])
117 #define VFAT_IOCTL_READDIR_SHORT _IOR('r', 2, struct linux_dirent [2])
128 #define _syscall0(type,name) \
129 static type name (void) \
131 return syscall(__NR_##name); \
134 #define _syscall1(type,name,type1,arg1) \
135 static type name (type1 arg1) \
137 return syscall(__NR_##name, arg1); \
140 #define _syscall2(type,name,type1,arg1,type2,arg2) \
141 static type name (type1 arg1,type2 arg2) \
143 return syscall(__NR_##name, arg1, arg2); \
146 #define _syscall3(type,name,type1,arg1,type2,arg2,type3,arg3) \
147 static type name (type1 arg1,type2 arg2,type3 arg3) \
149 return syscall(__NR_##name, arg1, arg2, arg3); \
152 #define _syscall4(type,name,type1,arg1,type2,arg2,type3,arg3,type4,arg4) \
153 static type name (type1 arg1,type2 arg2,type3 arg3,type4 arg4) \
155 return syscall(__NR_##name, arg1, arg2, arg3, arg4); \
158 #define _syscall5(type,name,type1,arg1,type2,arg2,type3,arg3,type4,arg4, \
160 static type name (type1 arg1,type2 arg2,type3 arg3,type4 arg4,type5 arg5) \
162 return syscall(__NR_##name, arg1, arg2, arg3, arg4, arg5); \
166 #define _syscall6(type,name,type1,arg1,type2,arg2,type3,arg3,type4,arg4, \
167 type5,arg5,type6,arg6) \
168 static type name (type1 arg1,type2 arg2,type3 arg3,type4 arg4,type5 arg5, \
171 return syscall(__NR_##name, arg1, arg2, arg3, arg4, arg5, arg6); \
175 #define __NR_sys_uname __NR_uname
176 #define __NR_sys_faccessat __NR_faccessat
177 #define __NR_sys_fchmodat __NR_fchmodat
178 #define __NR_sys_fchownat __NR_fchownat
179 #define __NR_sys_fstatat64 __NR_fstatat64
180 #define __NR_sys_futimesat __NR_futimesat
181 #define __NR_sys_getcwd1 __NR_getcwd
182 #define __NR_sys_getdents __NR_getdents
183 #define __NR_sys_getdents64 __NR_getdents64
184 #define __NR_sys_getpriority __NR_getpriority
185 #define __NR_sys_linkat __NR_linkat
186 #define __NR_sys_mkdirat __NR_mkdirat
187 #define __NR_sys_mknodat __NR_mknodat
188 #define __NR_sys_newfstatat __NR_newfstatat
189 #define __NR_sys_openat __NR_openat
190 #define __NR_sys_readlinkat __NR_readlinkat
191 #define __NR_sys_renameat __NR_renameat
192 #define __NR_sys_rt_sigqueueinfo __NR_rt_sigqueueinfo
193 #define __NR_sys_symlinkat __NR_symlinkat
194 #define __NR_sys_syslog __NR_syslog
195 #define __NR_sys_tgkill __NR_tgkill
196 #define __NR_sys_tkill __NR_tkill
197 #define __NR_sys_unlinkat __NR_unlinkat
198 #define __NR_sys_utimensat __NR_utimensat
199 #define __NR_sys_futex __NR_futex
200 #define __NR_sys_inotify_init __NR_inotify_init
201 #define __NR_sys_inotify_add_watch __NR_inotify_add_watch
202 #define __NR_sys_inotify_rm_watch __NR_inotify_rm_watch
204 #if defined(__alpha__) || defined (__ia64__) || defined(__x86_64__) || \
206 #define __NR__llseek __NR_lseek
210 _syscall0(int, gettid
)
212 /* This is a replacement for the host gettid() and must return a host
214 static int gettid(void) {
218 _syscall3(int, sys_getdents
, uint
, fd
, struct linux_dirent
*, dirp
, uint
, count
);
219 #if defined(TARGET_NR_getdents64) && defined(__NR_getdents64)
220 _syscall3(int, sys_getdents64
, uint
, fd
, struct linux_dirent64
*, dirp
, uint
, count
);
222 #if defined(TARGET_NR__llseek) && defined(__NR_llseek)
223 _syscall5(int, _llseek
, uint
, fd
, ulong
, hi
, ulong
, lo
,
224 loff_t
*, res
, uint
, wh
);
226 _syscall3(int,sys_rt_sigqueueinfo
,int,pid
,int,sig
,siginfo_t
*,uinfo
)
227 _syscall3(int,sys_syslog
,int,type
,char*,bufp
,int,len
)
228 #if defined(TARGET_NR_tgkill) && defined(__NR_tgkill)
229 _syscall3(int,sys_tgkill
,int,tgid
,int,pid
,int,sig
)
231 #if defined(TARGET_NR_tkill) && defined(__NR_tkill)
232 _syscall2(int,sys_tkill
,int,tid
,int,sig
)
234 #ifdef __NR_exit_group
235 _syscall1(int,exit_group
,int,error_code
)
237 #if defined(TARGET_NR_set_tid_address) && defined(__NR_set_tid_address)
238 _syscall1(int,set_tid_address
,int *,tidptr
)
240 #if defined(CONFIG_USE_NPTL)
241 #if defined(TARGET_NR_futex) && defined(__NR_futex)
242 _syscall6(int,sys_futex
,int *,uaddr
,int,op
,int,val
,
243 const struct timespec
*,timeout
,int *,uaddr2
,int,val3
)
246 #define __NR_sys_sched_getaffinity __NR_sched_getaffinity
247 _syscall3(int, sys_sched_getaffinity
, pid_t
, pid
, unsigned int, len
,
248 unsigned long *, user_mask_ptr
);
249 #define __NR_sys_sched_setaffinity __NR_sched_setaffinity
250 _syscall3(int, sys_sched_setaffinity
, pid_t
, pid
, unsigned int, len
,
251 unsigned long *, user_mask_ptr
);
252 _syscall4(int, reboot
, int, magic1
, int, magic2
, unsigned int, cmd
,
255 static bitmask_transtbl fcntl_flags_tbl
[] = {
256 { TARGET_O_ACCMODE
, TARGET_O_WRONLY
, O_ACCMODE
, O_WRONLY
, },
257 { TARGET_O_ACCMODE
, TARGET_O_RDWR
, O_ACCMODE
, O_RDWR
, },
258 { TARGET_O_CREAT
, TARGET_O_CREAT
, O_CREAT
, O_CREAT
, },
259 { TARGET_O_EXCL
, TARGET_O_EXCL
, O_EXCL
, O_EXCL
, },
260 { TARGET_O_NOCTTY
, TARGET_O_NOCTTY
, O_NOCTTY
, O_NOCTTY
, },
261 { TARGET_O_TRUNC
, TARGET_O_TRUNC
, O_TRUNC
, O_TRUNC
, },
262 { TARGET_O_APPEND
, TARGET_O_APPEND
, O_APPEND
, O_APPEND
, },
263 { TARGET_O_NONBLOCK
, TARGET_O_NONBLOCK
, O_NONBLOCK
, O_NONBLOCK
, },
264 { TARGET_O_SYNC
, TARGET_O_DSYNC
, O_SYNC
, O_DSYNC
, },
265 { TARGET_O_SYNC
, TARGET_O_SYNC
, O_SYNC
, O_SYNC
, },
266 { TARGET_FASYNC
, TARGET_FASYNC
, FASYNC
, FASYNC
, },
267 { TARGET_O_DIRECTORY
, TARGET_O_DIRECTORY
, O_DIRECTORY
, O_DIRECTORY
, },
268 { TARGET_O_NOFOLLOW
, TARGET_O_NOFOLLOW
, O_NOFOLLOW
, O_NOFOLLOW
, },
269 #if defined(O_DIRECT)
270 { TARGET_O_DIRECT
, TARGET_O_DIRECT
, O_DIRECT
, O_DIRECT
, },
272 #if defined(O_NOATIME)
273 { TARGET_O_NOATIME
, TARGET_O_NOATIME
, O_NOATIME
, O_NOATIME
},
275 #if defined(O_CLOEXEC)
276 { TARGET_O_CLOEXEC
, TARGET_O_CLOEXEC
, O_CLOEXEC
, O_CLOEXEC
},
279 { TARGET_O_PATH
, TARGET_O_PATH
, O_PATH
, O_PATH
},
281 /* Don't terminate the list prematurely on 64-bit host+guest. */
282 #if TARGET_O_LARGEFILE != 0 || O_LARGEFILE != 0
283 { TARGET_O_LARGEFILE
, TARGET_O_LARGEFILE
, O_LARGEFILE
, O_LARGEFILE
, },
288 #define COPY_UTSNAME_FIELD(dest, src) \
290 /* __NEW_UTS_LEN doesn't include terminating null */ \
291 (void) strncpy((dest), (src), __NEW_UTS_LEN); \
292 (dest)[__NEW_UTS_LEN] = '\0'; \
295 static int sys_uname(struct new_utsname
*buf
)
297 struct utsname uts_buf
;
299 if (uname(&uts_buf
) < 0)
303 * Just in case these have some differences, we
304 * translate utsname to new_utsname (which is the
305 * struct linux kernel uses).
308 memset(buf
, 0, sizeof(*buf
));
309 COPY_UTSNAME_FIELD(buf
->sysname
, uts_buf
.sysname
);
310 COPY_UTSNAME_FIELD(buf
->nodename
, uts_buf
.nodename
);
311 COPY_UTSNAME_FIELD(buf
->release
, uts_buf
.release
);
312 COPY_UTSNAME_FIELD(buf
->version
, uts_buf
.version
);
313 COPY_UTSNAME_FIELD(buf
->machine
, uts_buf
.machine
);
315 COPY_UTSNAME_FIELD(buf
->domainname
, uts_buf
.domainname
);
319 #undef COPY_UTSNAME_FIELD
322 static int sys_getcwd1(char *buf
, size_t size
)
324 if (getcwd(buf
, size
) == NULL
) {
325 /* getcwd() sets errno */
328 return strlen(buf
)+1;
333 * Host system seems to have atfile syscall stubs available. We
334 * now enable them one by one as specified by target syscall_nr.h.
337 #ifdef TARGET_NR_faccessat
338 static int sys_faccessat(int dirfd
, const char *pathname
, int mode
)
340 return (faccessat(dirfd
, pathname
, mode
, 0));
343 #ifdef TARGET_NR_fchmodat
344 static int sys_fchmodat(int dirfd
, const char *pathname
, mode_t mode
)
346 return (fchmodat(dirfd
, pathname
, mode
, 0));
349 #if defined(TARGET_NR_fchownat)
350 static int sys_fchownat(int dirfd
, const char *pathname
, uid_t owner
,
351 gid_t group
, int flags
)
353 return (fchownat(dirfd
, pathname
, owner
, group
, flags
));
356 #ifdef __NR_fstatat64
357 static int sys_fstatat64(int dirfd
, const char *pathname
, struct stat
*buf
,
360 return (fstatat(dirfd
, pathname
, buf
, flags
));
363 #ifdef __NR_newfstatat
364 static int sys_newfstatat(int dirfd
, const char *pathname
, struct stat
*buf
,
367 return (fstatat(dirfd
, pathname
, buf
, flags
));
370 #ifdef TARGET_NR_futimesat
371 static int sys_futimesat(int dirfd
, const char *pathname
,
372 const struct timeval times
[2])
374 return (futimesat(dirfd
, pathname
, times
));
377 #ifdef TARGET_NR_linkat
378 static int sys_linkat(int olddirfd
, const char *oldpath
,
379 int newdirfd
, const char *newpath
, int flags
)
381 return (linkat(olddirfd
, oldpath
, newdirfd
, newpath
, flags
));
384 #ifdef TARGET_NR_mkdirat
385 static int sys_mkdirat(int dirfd
, const char *pathname
, mode_t mode
)
387 return (mkdirat(dirfd
, pathname
, mode
));
390 #ifdef TARGET_NR_mknodat
391 static int sys_mknodat(int dirfd
, const char *pathname
, mode_t mode
,
394 return (mknodat(dirfd
, pathname
, mode
, dev
));
397 #ifdef TARGET_NR_openat
398 static int sys_openat(int dirfd
, const char *pathname
, int flags
, mode_t mode
)
401 * open(2) has extra parameter 'mode' when called with
404 if ((flags
& O_CREAT
) != 0) {
405 return (openat(dirfd
, pathname
, flags
, mode
));
407 return (openat(dirfd
, pathname
, flags
));
410 #ifdef TARGET_NR_readlinkat
411 static int sys_readlinkat(int dirfd
, const char *pathname
, char *buf
, size_t bufsiz
)
413 return (readlinkat(dirfd
, pathname
, buf
, bufsiz
));
416 #ifdef TARGET_NR_renameat
417 static int sys_renameat(int olddirfd
, const char *oldpath
,
418 int newdirfd
, const char *newpath
)
420 return (renameat(olddirfd
, oldpath
, newdirfd
, newpath
));
423 #ifdef TARGET_NR_symlinkat
424 static int sys_symlinkat(const char *oldpath
, int newdirfd
, const char *newpath
)
426 return (symlinkat(oldpath
, newdirfd
, newpath
));
429 #ifdef TARGET_NR_unlinkat
430 static int sys_unlinkat(int dirfd
, const char *pathname
, int flags
)
432 return (unlinkat(dirfd
, pathname
, flags
));
435 #else /* !CONFIG_ATFILE */
438 * Try direct syscalls instead
440 #if defined(TARGET_NR_faccessat) && defined(__NR_faccessat)
441 _syscall3(int,sys_faccessat
,int,dirfd
,const char *,pathname
,int,mode
)
443 #if defined(TARGET_NR_fchmodat) && defined(__NR_fchmodat)
444 _syscall3(int,sys_fchmodat
,int,dirfd
,const char *,pathname
, mode_t
,mode
)
446 #if defined(TARGET_NR_fchownat) && defined(__NR_fchownat)
447 _syscall5(int,sys_fchownat
,int,dirfd
,const char *,pathname
,
448 uid_t
,owner
,gid_t
,group
,int,flags
)
450 #if (defined(TARGET_NR_fstatat64) || defined(TARGET_NR_newfstatat)) && \
451 defined(__NR_fstatat64)
452 _syscall4(int,sys_fstatat64
,int,dirfd
,const char *,pathname
,
453 struct stat
*,buf
,int,flags
)
455 #if defined(TARGET_NR_futimesat) && defined(__NR_futimesat)
456 _syscall3(int,sys_futimesat
,int,dirfd
,const char *,pathname
,
457 const struct timeval
*,times
)
459 #if (defined(TARGET_NR_newfstatat) || defined(TARGET_NR_fstatat64) ) && \
460 defined(__NR_newfstatat)
461 _syscall4(int,sys_newfstatat
,int,dirfd
,const char *,pathname
,
462 struct stat
*,buf
,int,flags
)
464 #if defined(TARGET_NR_linkat) && defined(__NR_linkat)
465 _syscall5(int,sys_linkat
,int,olddirfd
,const char *,oldpath
,
466 int,newdirfd
,const char *,newpath
,int,flags
)
468 #if defined(TARGET_NR_mkdirat) && defined(__NR_mkdirat)
469 _syscall3(int,sys_mkdirat
,int,dirfd
,const char *,pathname
,mode_t
,mode
)
471 #if defined(TARGET_NR_mknodat) && defined(__NR_mknodat)
472 _syscall4(int,sys_mknodat
,int,dirfd
,const char *,pathname
,
473 mode_t
,mode
,dev_t
,dev
)
475 #if defined(TARGET_NR_openat) && defined(__NR_openat)
476 _syscall4(int,sys_openat
,int,dirfd
,const char *,pathname
,int,flags
,mode_t
,mode
)
478 #if defined(TARGET_NR_readlinkat) && defined(__NR_readlinkat)
479 _syscall4(int,sys_readlinkat
,int,dirfd
,const char *,pathname
,
480 char *,buf
,size_t,bufsize
)
482 #if defined(TARGET_NR_renameat) && defined(__NR_renameat)
483 _syscall4(int,sys_renameat
,int,olddirfd
,const char *,oldpath
,
484 int,newdirfd
,const char *,newpath
)
486 #if defined(TARGET_NR_symlinkat) && defined(__NR_symlinkat)
487 _syscall3(int,sys_symlinkat
,const char *,oldpath
,
488 int,newdirfd
,const char *,newpath
)
490 #if defined(TARGET_NR_unlinkat) && defined(__NR_unlinkat)
491 _syscall3(int,sys_unlinkat
,int,dirfd
,const char *,pathname
,int,flags
)
494 #endif /* CONFIG_ATFILE */
496 #ifdef CONFIG_UTIMENSAT
497 static int sys_utimensat(int dirfd
, const char *pathname
,
498 const struct timespec times
[2], int flags
)
500 if (pathname
== NULL
)
501 return futimens(dirfd
, times
);
503 return utimensat(dirfd
, pathname
, times
, flags
);
506 #if defined(TARGET_NR_utimensat) && defined(__NR_utimensat)
507 _syscall4(int,sys_utimensat
,int,dirfd
,const char *,pathname
,
508 const struct timespec
*,tsp
,int,flags
)
510 #endif /* CONFIG_UTIMENSAT */
512 #ifdef CONFIG_INOTIFY
513 #include <sys/inotify.h>
515 #if defined(TARGET_NR_inotify_init) && defined(__NR_inotify_init)
516 static int sys_inotify_init(void)
518 return (inotify_init());
521 #if defined(TARGET_NR_inotify_add_watch) && defined(__NR_inotify_add_watch)
522 static int sys_inotify_add_watch(int fd
,const char *pathname
, int32_t mask
)
524 return (inotify_add_watch(fd
, pathname
, mask
));
527 #if defined(TARGET_NR_inotify_rm_watch) && defined(__NR_inotify_rm_watch)
528 static int sys_inotify_rm_watch(int fd
, int32_t wd
)
530 return (inotify_rm_watch(fd
, wd
));
533 #ifdef CONFIG_INOTIFY1
534 #if defined(TARGET_NR_inotify_init1) && defined(__NR_inotify_init1)
535 static int sys_inotify_init1(int flags
)
537 return (inotify_init1(flags
));
542 /* Userspace can usually survive runtime without inotify */
543 #undef TARGET_NR_inotify_init
544 #undef TARGET_NR_inotify_init1
545 #undef TARGET_NR_inotify_add_watch
546 #undef TARGET_NR_inotify_rm_watch
547 #endif /* CONFIG_INOTIFY */
549 #if defined(TARGET_NR_ppoll)
551 # define __NR_ppoll -1
553 #define __NR_sys_ppoll __NR_ppoll
554 _syscall5(int, sys_ppoll
, struct pollfd
*, fds
, nfds_t
, nfds
,
555 struct timespec
*, timeout
, const __sigset_t
*, sigmask
,
559 #if defined(TARGET_NR_pselect6)
560 #ifndef __NR_pselect6
561 # define __NR_pselect6 -1
563 #define __NR_sys_pselect6 __NR_pselect6
564 _syscall6(int, sys_pselect6
, int, nfds
, fd_set
*, readfds
, fd_set
*, writefds
,
565 fd_set
*, exceptfds
, struct timespec
*, timeout
, void *, sig
);
568 #if defined(TARGET_NR_prlimit64)
569 #ifndef __NR_prlimit64
570 # define __NR_prlimit64 -1
572 #define __NR_sys_prlimit64 __NR_prlimit64
573 /* The glibc rlimit structure may not be that used by the underlying syscall */
574 struct host_rlimit64
{
578 _syscall4(int, sys_prlimit64
, pid_t
, pid
, int, resource
,
579 const struct host_rlimit64
*, new_limit
,
580 struct host_rlimit64
*, old_limit
)
583 extern int personality(int);
584 extern int flock(int, int);
585 extern int setfsuid(int);
586 extern int setfsgid(int);
587 extern int setgroups(int, gid_t
*);
589 /* ARM EABI and MIPS expect 64bit types aligned even on pairs or registers */
591 static inline int regpairs_aligned(void *cpu_env
) {
592 return ((((CPUARMState
*)cpu_env
)->eabi
) == 1) ;
594 #elif defined(TARGET_MIPS)
595 static inline int regpairs_aligned(void *cpu_env
) { return 1; }
597 static inline int regpairs_aligned(void *cpu_env
) { return 0; }
600 #define ERRNO_TABLE_SIZE 1200
602 /* target_to_host_errno_table[] is initialized from
603 * host_to_target_errno_table[] in syscall_init(). */
604 static uint16_t target_to_host_errno_table
[ERRNO_TABLE_SIZE
] = {
608 * This list is the union of errno values overridden in asm-<arch>/errno.h
609 * minus the errnos that are not actually generic to all archs.
611 static uint16_t host_to_target_errno_table
[ERRNO_TABLE_SIZE
] = {
612 [EIDRM
] = TARGET_EIDRM
,
613 [ECHRNG
] = TARGET_ECHRNG
,
614 [EL2NSYNC
] = TARGET_EL2NSYNC
,
615 [EL3HLT
] = TARGET_EL3HLT
,
616 [EL3RST
] = TARGET_EL3RST
,
617 [ELNRNG
] = TARGET_ELNRNG
,
618 [EUNATCH
] = TARGET_EUNATCH
,
619 [ENOCSI
] = TARGET_ENOCSI
,
620 [EL2HLT
] = TARGET_EL2HLT
,
621 [EDEADLK
] = TARGET_EDEADLK
,
622 [ENOLCK
] = TARGET_ENOLCK
,
623 [EBADE
] = TARGET_EBADE
,
624 [EBADR
] = TARGET_EBADR
,
625 [EXFULL
] = TARGET_EXFULL
,
626 [ENOANO
] = TARGET_ENOANO
,
627 [EBADRQC
] = TARGET_EBADRQC
,
628 [EBADSLT
] = TARGET_EBADSLT
,
629 [EBFONT
] = TARGET_EBFONT
,
630 [ENOSTR
] = TARGET_ENOSTR
,
631 [ENODATA
] = TARGET_ENODATA
,
632 [ETIME
] = TARGET_ETIME
,
633 [ENOSR
] = TARGET_ENOSR
,
634 [ENONET
] = TARGET_ENONET
,
635 [ENOPKG
] = TARGET_ENOPKG
,
636 [EREMOTE
] = TARGET_EREMOTE
,
637 [ENOLINK
] = TARGET_ENOLINK
,
638 [EADV
] = TARGET_EADV
,
639 [ESRMNT
] = TARGET_ESRMNT
,
640 [ECOMM
] = TARGET_ECOMM
,
641 [EPROTO
] = TARGET_EPROTO
,
642 [EDOTDOT
] = TARGET_EDOTDOT
,
643 [EMULTIHOP
] = TARGET_EMULTIHOP
,
644 [EBADMSG
] = TARGET_EBADMSG
,
645 [ENAMETOOLONG
] = TARGET_ENAMETOOLONG
,
646 [EOVERFLOW
] = TARGET_EOVERFLOW
,
647 [ENOTUNIQ
] = TARGET_ENOTUNIQ
,
648 [EBADFD
] = TARGET_EBADFD
,
649 [EREMCHG
] = TARGET_EREMCHG
,
650 [ELIBACC
] = TARGET_ELIBACC
,
651 [ELIBBAD
] = TARGET_ELIBBAD
,
652 [ELIBSCN
] = TARGET_ELIBSCN
,
653 [ELIBMAX
] = TARGET_ELIBMAX
,
654 [ELIBEXEC
] = TARGET_ELIBEXEC
,
655 [EILSEQ
] = TARGET_EILSEQ
,
656 [ENOSYS
] = TARGET_ENOSYS
,
657 [ELOOP
] = TARGET_ELOOP
,
658 [ERESTART
] = TARGET_ERESTART
,
659 [ESTRPIPE
] = TARGET_ESTRPIPE
,
660 [ENOTEMPTY
] = TARGET_ENOTEMPTY
,
661 [EUSERS
] = TARGET_EUSERS
,
662 [ENOTSOCK
] = TARGET_ENOTSOCK
,
663 [EDESTADDRREQ
] = TARGET_EDESTADDRREQ
,
664 [EMSGSIZE
] = TARGET_EMSGSIZE
,
665 [EPROTOTYPE
] = TARGET_EPROTOTYPE
,
666 [ENOPROTOOPT
] = TARGET_ENOPROTOOPT
,
667 [EPROTONOSUPPORT
] = TARGET_EPROTONOSUPPORT
,
668 [ESOCKTNOSUPPORT
] = TARGET_ESOCKTNOSUPPORT
,
669 [EOPNOTSUPP
] = TARGET_EOPNOTSUPP
,
670 [EPFNOSUPPORT
] = TARGET_EPFNOSUPPORT
,
671 [EAFNOSUPPORT
] = TARGET_EAFNOSUPPORT
,
672 [EADDRINUSE
] = TARGET_EADDRINUSE
,
673 [EADDRNOTAVAIL
] = TARGET_EADDRNOTAVAIL
,
674 [ENETDOWN
] = TARGET_ENETDOWN
,
675 [ENETUNREACH
] = TARGET_ENETUNREACH
,
676 [ENETRESET
] = TARGET_ENETRESET
,
677 [ECONNABORTED
] = TARGET_ECONNABORTED
,
678 [ECONNRESET
] = TARGET_ECONNRESET
,
679 [ENOBUFS
] = TARGET_ENOBUFS
,
680 [EISCONN
] = TARGET_EISCONN
,
681 [ENOTCONN
] = TARGET_ENOTCONN
,
682 [EUCLEAN
] = TARGET_EUCLEAN
,
683 [ENOTNAM
] = TARGET_ENOTNAM
,
684 [ENAVAIL
] = TARGET_ENAVAIL
,
685 [EISNAM
] = TARGET_EISNAM
,
686 [EREMOTEIO
] = TARGET_EREMOTEIO
,
687 [ESHUTDOWN
] = TARGET_ESHUTDOWN
,
688 [ETOOMANYREFS
] = TARGET_ETOOMANYREFS
,
689 [ETIMEDOUT
] = TARGET_ETIMEDOUT
,
690 [ECONNREFUSED
] = TARGET_ECONNREFUSED
,
691 [EHOSTDOWN
] = TARGET_EHOSTDOWN
,
692 [EHOSTUNREACH
] = TARGET_EHOSTUNREACH
,
693 [EALREADY
] = TARGET_EALREADY
,
694 [EINPROGRESS
] = TARGET_EINPROGRESS
,
695 [ESTALE
] = TARGET_ESTALE
,
696 [ECANCELED
] = TARGET_ECANCELED
,
697 [ENOMEDIUM
] = TARGET_ENOMEDIUM
,
698 [EMEDIUMTYPE
] = TARGET_EMEDIUMTYPE
,
700 [ENOKEY
] = TARGET_ENOKEY
,
703 [EKEYEXPIRED
] = TARGET_EKEYEXPIRED
,
706 [EKEYREVOKED
] = TARGET_EKEYREVOKED
,
709 [EKEYREJECTED
] = TARGET_EKEYREJECTED
,
712 [EOWNERDEAD
] = TARGET_EOWNERDEAD
,
714 #ifdef ENOTRECOVERABLE
715 [ENOTRECOVERABLE
] = TARGET_ENOTRECOVERABLE
,
719 static inline int host_to_target_errno(int err
)
721 if(host_to_target_errno_table
[err
])
722 return host_to_target_errno_table
[err
];
726 static inline int target_to_host_errno(int err
)
728 if (target_to_host_errno_table
[err
])
729 return target_to_host_errno_table
[err
];
733 static inline abi_long
get_errno(abi_long ret
)
736 return -host_to_target_errno(errno
);
741 static inline int is_error(abi_long ret
)
743 return (abi_ulong
)ret
>= (abi_ulong
)(-4096);
746 char *target_strerror(int err
)
748 if ((err
>= ERRNO_TABLE_SIZE
) || (err
< 0)) {
751 return strerror(target_to_host_errno(err
));
754 static abi_ulong target_brk
;
755 static abi_ulong target_original_brk
;
756 static abi_ulong brk_page
;
758 void target_set_brk(abi_ulong new_brk
)
760 target_original_brk
= target_brk
= HOST_PAGE_ALIGN(new_brk
);
761 brk_page
= HOST_PAGE_ALIGN(target_brk
);
764 //#define DEBUGF_BRK(message, args...) do { fprintf(stderr, (message), ## args); } while (0)
765 #define DEBUGF_BRK(message, args...)
767 /* do_brk() must return target values and target errnos. */
768 abi_long
do_brk(abi_ulong new_brk
)
770 abi_long mapped_addr
;
773 DEBUGF_BRK("do_brk(" TARGET_ABI_FMT_lx
") -> ", new_brk
);
776 DEBUGF_BRK(TARGET_ABI_FMT_lx
" (!new_brk)\n", target_brk
);
779 if (new_brk
< target_original_brk
) {
780 DEBUGF_BRK(TARGET_ABI_FMT_lx
" (new_brk < target_original_brk)\n",
785 /* If the new brk is less than the highest page reserved to the
786 * target heap allocation, set it and we're almost done... */
787 if (new_brk
<= brk_page
) {
788 /* Heap contents are initialized to zero, as for anonymous
790 if (new_brk
> target_brk
) {
791 memset(g2h(target_brk
), 0, new_brk
- target_brk
);
793 target_brk
= new_brk
;
794 DEBUGF_BRK(TARGET_ABI_FMT_lx
" (new_brk <= brk_page)\n", target_brk
);
798 /* We need to allocate more memory after the brk... Note that
799 * we don't use MAP_FIXED because that will map over the top of
800 * any existing mapping (like the one with the host libc or qemu
801 * itself); instead we treat "mapped but at wrong address" as
802 * a failure and unmap again.
804 new_alloc_size
= HOST_PAGE_ALIGN(new_brk
- brk_page
);
805 mapped_addr
= get_errno(target_mmap(brk_page
, new_alloc_size
,
806 PROT_READ
|PROT_WRITE
,
807 MAP_ANON
|MAP_PRIVATE
, 0, 0));
809 if (mapped_addr
== brk_page
) {
810 /* Heap contents are initialized to zero, as for anonymous
811 * mapped pages. Technically the new pages are already
812 * initialized to zero since they *are* anonymous mapped
813 * pages, however we have to take care with the contents that
814 * come from the remaining part of the previous page: it may
815 * contains garbage data due to a previous heap usage (grown
817 memset(g2h(target_brk
), 0, brk_page
- target_brk
);
819 target_brk
= new_brk
;
820 brk_page
= HOST_PAGE_ALIGN(target_brk
);
821 DEBUGF_BRK(TARGET_ABI_FMT_lx
" (mapped_addr == brk_page)\n",
824 } else if (mapped_addr
!= -1) {
825 /* Mapped but at wrong address, meaning there wasn't actually
826 * enough space for this brk.
828 target_munmap(mapped_addr
, new_alloc_size
);
830 DEBUGF_BRK(TARGET_ABI_FMT_lx
" (mapped_addr != -1)\n", target_brk
);
833 DEBUGF_BRK(TARGET_ABI_FMT_lx
" (otherwise)\n", target_brk
);
836 #if defined(TARGET_ALPHA)
837 /* We (partially) emulate OSF/1 on Alpha, which requires we
838 return a proper errno, not an unchanged brk value. */
839 return -TARGET_ENOMEM
;
841 /* For everything else, return the previous break. */
845 static inline abi_long
copy_from_user_fdset(fd_set
*fds
,
846 abi_ulong target_fds_addr
,
850 abi_ulong b
, *target_fds
;
852 nw
= (n
+ TARGET_ABI_BITS
- 1) / TARGET_ABI_BITS
;
853 if (!(target_fds
= lock_user(VERIFY_READ
,
855 sizeof(abi_ulong
) * nw
,
857 return -TARGET_EFAULT
;
861 for (i
= 0; i
< nw
; i
++) {
862 /* grab the abi_ulong */
863 __get_user(b
, &target_fds
[i
]);
864 for (j
= 0; j
< TARGET_ABI_BITS
; j
++) {
865 /* check the bit inside the abi_ulong */
872 unlock_user(target_fds
, target_fds_addr
, 0);
877 static inline abi_ulong
copy_from_user_fdset_ptr(fd_set
*fds
, fd_set
**fds_ptr
,
878 abi_ulong target_fds_addr
,
881 if (target_fds_addr
) {
882 if (copy_from_user_fdset(fds
, target_fds_addr
, n
))
883 return -TARGET_EFAULT
;
891 static inline abi_long
copy_to_user_fdset(abi_ulong target_fds_addr
,
897 abi_ulong
*target_fds
;
899 nw
= (n
+ TARGET_ABI_BITS
- 1) / TARGET_ABI_BITS
;
900 if (!(target_fds
= lock_user(VERIFY_WRITE
,
902 sizeof(abi_ulong
) * nw
,
904 return -TARGET_EFAULT
;
907 for (i
= 0; i
< nw
; i
++) {
909 for (j
= 0; j
< TARGET_ABI_BITS
; j
++) {
910 v
|= ((FD_ISSET(k
, fds
) != 0) << j
);
913 __put_user(v
, &target_fds
[i
]);
916 unlock_user(target_fds
, target_fds_addr
, sizeof(abi_ulong
) * nw
);
921 #if defined(__alpha__)
927 static inline abi_long
host_to_target_clock_t(long ticks
)
929 #if HOST_HZ == TARGET_HZ
932 return ((int64_t)ticks
* TARGET_HZ
) / HOST_HZ
;
936 static inline abi_long
host_to_target_rusage(abi_ulong target_addr
,
937 const struct rusage
*rusage
)
939 struct target_rusage
*target_rusage
;
941 if (!lock_user_struct(VERIFY_WRITE
, target_rusage
, target_addr
, 0))
942 return -TARGET_EFAULT
;
943 target_rusage
->ru_utime
.tv_sec
= tswapal(rusage
->ru_utime
.tv_sec
);
944 target_rusage
->ru_utime
.tv_usec
= tswapal(rusage
->ru_utime
.tv_usec
);
945 target_rusage
->ru_stime
.tv_sec
= tswapal(rusage
->ru_stime
.tv_sec
);
946 target_rusage
->ru_stime
.tv_usec
= tswapal(rusage
->ru_stime
.tv_usec
);
947 target_rusage
->ru_maxrss
= tswapal(rusage
->ru_maxrss
);
948 target_rusage
->ru_ixrss
= tswapal(rusage
->ru_ixrss
);
949 target_rusage
->ru_idrss
= tswapal(rusage
->ru_idrss
);
950 target_rusage
->ru_isrss
= tswapal(rusage
->ru_isrss
);
951 target_rusage
->ru_minflt
= tswapal(rusage
->ru_minflt
);
952 target_rusage
->ru_majflt
= tswapal(rusage
->ru_majflt
);
953 target_rusage
->ru_nswap
= tswapal(rusage
->ru_nswap
);
954 target_rusage
->ru_inblock
= tswapal(rusage
->ru_inblock
);
955 target_rusage
->ru_oublock
= tswapal(rusage
->ru_oublock
);
956 target_rusage
->ru_msgsnd
= tswapal(rusage
->ru_msgsnd
);
957 target_rusage
->ru_msgrcv
= tswapal(rusage
->ru_msgrcv
);
958 target_rusage
->ru_nsignals
= tswapal(rusage
->ru_nsignals
);
959 target_rusage
->ru_nvcsw
= tswapal(rusage
->ru_nvcsw
);
960 target_rusage
->ru_nivcsw
= tswapal(rusage
->ru_nivcsw
);
961 unlock_user_struct(target_rusage
, target_addr
, 1);
966 static inline rlim_t
target_to_host_rlim(abi_ulong target_rlim
)
968 abi_ulong target_rlim_swap
;
971 target_rlim_swap
= tswapal(target_rlim
);
972 if (target_rlim_swap
== TARGET_RLIM_INFINITY
)
973 return RLIM_INFINITY
;
975 result
= target_rlim_swap
;
976 if (target_rlim_swap
!= (rlim_t
)result
)
977 return RLIM_INFINITY
;
982 static inline abi_ulong
host_to_target_rlim(rlim_t rlim
)
984 abi_ulong target_rlim_swap
;
987 if (rlim
== RLIM_INFINITY
|| rlim
!= (abi_long
)rlim
)
988 target_rlim_swap
= TARGET_RLIM_INFINITY
;
990 target_rlim_swap
= rlim
;
991 result
= tswapal(target_rlim_swap
);
996 static inline int target_to_host_resource(int code
)
999 case TARGET_RLIMIT_AS
:
1001 case TARGET_RLIMIT_CORE
:
1003 case TARGET_RLIMIT_CPU
:
1005 case TARGET_RLIMIT_DATA
:
1007 case TARGET_RLIMIT_FSIZE
:
1008 return RLIMIT_FSIZE
;
1009 case TARGET_RLIMIT_LOCKS
:
1010 return RLIMIT_LOCKS
;
1011 case TARGET_RLIMIT_MEMLOCK
:
1012 return RLIMIT_MEMLOCK
;
1013 case TARGET_RLIMIT_MSGQUEUE
:
1014 return RLIMIT_MSGQUEUE
;
1015 case TARGET_RLIMIT_NICE
:
1017 case TARGET_RLIMIT_NOFILE
:
1018 return RLIMIT_NOFILE
;
1019 case TARGET_RLIMIT_NPROC
:
1020 return RLIMIT_NPROC
;
1021 case TARGET_RLIMIT_RSS
:
1023 case TARGET_RLIMIT_RTPRIO
:
1024 return RLIMIT_RTPRIO
;
1025 case TARGET_RLIMIT_SIGPENDING
:
1026 return RLIMIT_SIGPENDING
;
1027 case TARGET_RLIMIT_STACK
:
1028 return RLIMIT_STACK
;
1034 static inline abi_long
copy_from_user_timeval(struct timeval
*tv
,
1035 abi_ulong target_tv_addr
)
1037 struct target_timeval
*target_tv
;
1039 if (!lock_user_struct(VERIFY_READ
, target_tv
, target_tv_addr
, 1))
1040 return -TARGET_EFAULT
;
1042 __get_user(tv
->tv_sec
, &target_tv
->tv_sec
);
1043 __get_user(tv
->tv_usec
, &target_tv
->tv_usec
);
1045 unlock_user_struct(target_tv
, target_tv_addr
, 0);
1050 static inline abi_long
copy_to_user_timeval(abi_ulong target_tv_addr
,
1051 const struct timeval
*tv
)
1053 struct target_timeval
*target_tv
;
1055 if (!lock_user_struct(VERIFY_WRITE
, target_tv
, target_tv_addr
, 0))
1056 return -TARGET_EFAULT
;
1058 __put_user(tv
->tv_sec
, &target_tv
->tv_sec
);
1059 __put_user(tv
->tv_usec
, &target_tv
->tv_usec
);
1061 unlock_user_struct(target_tv
, target_tv_addr
, 1);
1066 #if defined(TARGET_NR_mq_open) && defined(__NR_mq_open)
1069 static inline abi_long
copy_from_user_mq_attr(struct mq_attr
*attr
,
1070 abi_ulong target_mq_attr_addr
)
1072 struct target_mq_attr
*target_mq_attr
;
1074 if (!lock_user_struct(VERIFY_READ
, target_mq_attr
,
1075 target_mq_attr_addr
, 1))
1076 return -TARGET_EFAULT
;
1078 __get_user(attr
->mq_flags
, &target_mq_attr
->mq_flags
);
1079 __get_user(attr
->mq_maxmsg
, &target_mq_attr
->mq_maxmsg
);
1080 __get_user(attr
->mq_msgsize
, &target_mq_attr
->mq_msgsize
);
1081 __get_user(attr
->mq_curmsgs
, &target_mq_attr
->mq_curmsgs
);
1083 unlock_user_struct(target_mq_attr
, target_mq_attr_addr
, 0);
1088 static inline abi_long
copy_to_user_mq_attr(abi_ulong target_mq_attr_addr
,
1089 const struct mq_attr
*attr
)
1091 struct target_mq_attr
*target_mq_attr
;
1093 if (!lock_user_struct(VERIFY_WRITE
, target_mq_attr
,
1094 target_mq_attr_addr
, 0))
1095 return -TARGET_EFAULT
;
1097 __put_user(attr
->mq_flags
, &target_mq_attr
->mq_flags
);
1098 __put_user(attr
->mq_maxmsg
, &target_mq_attr
->mq_maxmsg
);
1099 __put_user(attr
->mq_msgsize
, &target_mq_attr
->mq_msgsize
);
1100 __put_user(attr
->mq_curmsgs
, &target_mq_attr
->mq_curmsgs
);
1102 unlock_user_struct(target_mq_attr
, target_mq_attr_addr
, 1);
1108 #if defined(TARGET_NR_select) || defined(TARGET_NR__newselect)
1109 /* do_select() must return target values and target errnos. */
1110 static abi_long
do_select(int n
,
1111 abi_ulong rfd_addr
, abi_ulong wfd_addr
,
1112 abi_ulong efd_addr
, abi_ulong target_tv_addr
)
1114 fd_set rfds
, wfds
, efds
;
1115 fd_set
*rfds_ptr
, *wfds_ptr
, *efds_ptr
;
1116 struct timeval tv
, *tv_ptr
;
1119 ret
= copy_from_user_fdset_ptr(&rfds
, &rfds_ptr
, rfd_addr
, n
);
1123 ret
= copy_from_user_fdset_ptr(&wfds
, &wfds_ptr
, wfd_addr
, n
);
1127 ret
= copy_from_user_fdset_ptr(&efds
, &efds_ptr
, efd_addr
, n
);
1132 if (target_tv_addr
) {
1133 if (copy_from_user_timeval(&tv
, target_tv_addr
))
1134 return -TARGET_EFAULT
;
1140 ret
= get_errno(select(n
, rfds_ptr
, wfds_ptr
, efds_ptr
, tv_ptr
));
1142 if (!is_error(ret
)) {
1143 if (rfd_addr
&& copy_to_user_fdset(rfd_addr
, &rfds
, n
))
1144 return -TARGET_EFAULT
;
1145 if (wfd_addr
&& copy_to_user_fdset(wfd_addr
, &wfds
, n
))
1146 return -TARGET_EFAULT
;
1147 if (efd_addr
&& copy_to_user_fdset(efd_addr
, &efds
, n
))
1148 return -TARGET_EFAULT
;
1150 if (target_tv_addr
&& copy_to_user_timeval(target_tv_addr
, &tv
))
1151 return -TARGET_EFAULT
;
1158 static abi_long
do_pipe2(int host_pipe
[], int flags
)
1161 return pipe2(host_pipe
, flags
);
1167 static abi_long
do_pipe(void *cpu_env
, abi_ulong pipedes
,
1168 int flags
, int is_pipe2
)
1172 ret
= flags
? do_pipe2(host_pipe
, flags
) : pipe(host_pipe
);
1175 return get_errno(ret
);
1177 /* Several targets have special calling conventions for the original
1178 pipe syscall, but didn't replicate this into the pipe2 syscall. */
1180 #if defined(TARGET_ALPHA)
1181 ((CPUAlphaState
*)cpu_env
)->ir
[IR_A4
] = host_pipe
[1];
1182 return host_pipe
[0];
1183 #elif defined(TARGET_MIPS)
1184 ((CPUMIPSState
*)cpu_env
)->active_tc
.gpr
[3] = host_pipe
[1];
1185 return host_pipe
[0];
1186 #elif defined(TARGET_SH4)
1187 ((CPUSH4State
*)cpu_env
)->gregs
[1] = host_pipe
[1];
1188 return host_pipe
[0];
1192 if (put_user_s32(host_pipe
[0], pipedes
)
1193 || put_user_s32(host_pipe
[1], pipedes
+ sizeof(host_pipe
[0])))
1194 return -TARGET_EFAULT
;
1195 return get_errno(ret
);
1198 static inline abi_long
target_to_host_ip_mreq(struct ip_mreqn
*mreqn
,
1199 abi_ulong target_addr
,
1202 struct target_ip_mreqn
*target_smreqn
;
1204 target_smreqn
= lock_user(VERIFY_READ
, target_addr
, len
, 1);
1206 return -TARGET_EFAULT
;
1207 mreqn
->imr_multiaddr
.s_addr
= target_smreqn
->imr_multiaddr
.s_addr
;
1208 mreqn
->imr_address
.s_addr
= target_smreqn
->imr_address
.s_addr
;
1209 if (len
== sizeof(struct target_ip_mreqn
))
1210 mreqn
->imr_ifindex
= tswapal(target_smreqn
->imr_ifindex
);
1211 unlock_user(target_smreqn
, target_addr
, 0);
1216 static inline abi_long
target_to_host_sockaddr(struct sockaddr
*addr
,
1217 abi_ulong target_addr
,
1220 const socklen_t unix_maxlen
= sizeof (struct sockaddr_un
);
1221 sa_family_t sa_family
;
1222 struct target_sockaddr
*target_saddr
;
1224 target_saddr
= lock_user(VERIFY_READ
, target_addr
, len
, 1);
1226 return -TARGET_EFAULT
;
1228 sa_family
= tswap16(target_saddr
->sa_family
);
1230 /* Oops. The caller might send a incomplete sun_path; sun_path
1231 * must be terminated by \0 (see the manual page), but
1232 * unfortunately it is quite common to specify sockaddr_un
1233 * length as "strlen(x->sun_path)" while it should be
1234 * "strlen(...) + 1". We'll fix that here if needed.
1235 * Linux kernel has a similar feature.
1238 if (sa_family
== AF_UNIX
) {
1239 if (len
< unix_maxlen
&& len
> 0) {
1240 char *cp
= (char*)target_saddr
;
1242 if ( cp
[len
-1] && !cp
[len
] )
1245 if (len
> unix_maxlen
)
1249 memcpy(addr
, target_saddr
, len
);
1250 addr
->sa_family
= sa_family
;
1251 unlock_user(target_saddr
, target_addr
, 0);
1256 static inline abi_long
host_to_target_sockaddr(abi_ulong target_addr
,
1257 struct sockaddr
*addr
,
1260 struct target_sockaddr
*target_saddr
;
1262 target_saddr
= lock_user(VERIFY_WRITE
, target_addr
, len
, 0);
1264 return -TARGET_EFAULT
;
1265 memcpy(target_saddr
, addr
, len
);
1266 target_saddr
->sa_family
= tswap16(addr
->sa_family
);
1267 unlock_user(target_saddr
, target_addr
, len
);
1272 static inline abi_long
target_to_host_cmsg(struct msghdr
*msgh
,
1273 struct target_msghdr
*target_msgh
)
1275 struct cmsghdr
*cmsg
= CMSG_FIRSTHDR(msgh
);
1276 abi_long msg_controllen
;
1277 abi_ulong target_cmsg_addr
;
1278 struct target_cmsghdr
*target_cmsg
;
1279 socklen_t space
= 0;
1281 msg_controllen
= tswapal(target_msgh
->msg_controllen
);
1282 if (msg_controllen
< sizeof (struct target_cmsghdr
))
1284 target_cmsg_addr
= tswapal(target_msgh
->msg_control
);
1285 target_cmsg
= lock_user(VERIFY_READ
, target_cmsg_addr
, msg_controllen
, 1);
1287 return -TARGET_EFAULT
;
1289 while (cmsg
&& target_cmsg
) {
1290 void *data
= CMSG_DATA(cmsg
);
1291 void *target_data
= TARGET_CMSG_DATA(target_cmsg
);
1293 int len
= tswapal(target_cmsg
->cmsg_len
)
1294 - TARGET_CMSG_ALIGN(sizeof (struct target_cmsghdr
));
1296 space
+= CMSG_SPACE(len
);
1297 if (space
> msgh
->msg_controllen
) {
1298 space
-= CMSG_SPACE(len
);
1299 gemu_log("Host cmsg overflow\n");
1303 cmsg
->cmsg_level
= tswap32(target_cmsg
->cmsg_level
);
1304 cmsg
->cmsg_type
= tswap32(target_cmsg
->cmsg_type
);
1305 cmsg
->cmsg_len
= CMSG_LEN(len
);
1307 if (cmsg
->cmsg_level
!= TARGET_SOL_SOCKET
|| cmsg
->cmsg_type
!= SCM_RIGHTS
) {
1308 gemu_log("Unsupported ancillary data: %d/%d\n", cmsg
->cmsg_level
, cmsg
->cmsg_type
);
1309 memcpy(data
, target_data
, len
);
1311 int *fd
= (int *)data
;
1312 int *target_fd
= (int *)target_data
;
1313 int i
, numfds
= len
/ sizeof(int);
1315 for (i
= 0; i
< numfds
; i
++)
1316 fd
[i
] = tswap32(target_fd
[i
]);
1319 cmsg
= CMSG_NXTHDR(msgh
, cmsg
);
1320 target_cmsg
= TARGET_CMSG_NXTHDR(target_msgh
, target_cmsg
);
1322 unlock_user(target_cmsg
, target_cmsg_addr
, 0);
1324 msgh
->msg_controllen
= space
;
1328 static inline abi_long
host_to_target_cmsg(struct target_msghdr
*target_msgh
,
1329 struct msghdr
*msgh
)
1331 struct cmsghdr
*cmsg
= CMSG_FIRSTHDR(msgh
);
1332 abi_long msg_controllen
;
1333 abi_ulong target_cmsg_addr
;
1334 struct target_cmsghdr
*target_cmsg
;
1335 socklen_t space
= 0;
1337 msg_controllen
= tswapal(target_msgh
->msg_controllen
);
1338 if (msg_controllen
< sizeof (struct target_cmsghdr
))
1340 target_cmsg_addr
= tswapal(target_msgh
->msg_control
);
1341 target_cmsg
= lock_user(VERIFY_WRITE
, target_cmsg_addr
, msg_controllen
, 0);
1343 return -TARGET_EFAULT
;
1345 while (cmsg
&& target_cmsg
) {
1346 void *data
= CMSG_DATA(cmsg
);
1347 void *target_data
= TARGET_CMSG_DATA(target_cmsg
);
1349 int len
= cmsg
->cmsg_len
- CMSG_ALIGN(sizeof (struct cmsghdr
));
1351 space
+= TARGET_CMSG_SPACE(len
);
1352 if (space
> msg_controllen
) {
1353 space
-= TARGET_CMSG_SPACE(len
);
1354 gemu_log("Target cmsg overflow\n");
1358 target_cmsg
->cmsg_level
= tswap32(cmsg
->cmsg_level
);
1359 target_cmsg
->cmsg_type
= tswap32(cmsg
->cmsg_type
);
1360 target_cmsg
->cmsg_len
= tswapal(TARGET_CMSG_LEN(len
));
1362 if ((cmsg
->cmsg_level
== TARGET_SOL_SOCKET
) &&
1363 (cmsg
->cmsg_type
== SCM_RIGHTS
)) {
1364 int *fd
= (int *)data
;
1365 int *target_fd
= (int *)target_data
;
1366 int i
, numfds
= len
/ sizeof(int);
1368 for (i
= 0; i
< numfds
; i
++)
1369 target_fd
[i
] = tswap32(fd
[i
]);
1370 } else if ((cmsg
->cmsg_level
== TARGET_SOL_SOCKET
) &&
1371 (cmsg
->cmsg_type
== SO_TIMESTAMP
) &&
1372 (len
== sizeof(struct timeval
))) {
1373 /* copy struct timeval to target */
1374 struct timeval
*tv
= (struct timeval
*)data
;
1375 struct target_timeval
*target_tv
=
1376 (struct target_timeval
*)target_data
;
1378 target_tv
->tv_sec
= tswapal(tv
->tv_sec
);
1379 target_tv
->tv_usec
= tswapal(tv
->tv_usec
);
1381 gemu_log("Unsupported ancillary data: %d/%d\n",
1382 cmsg
->cmsg_level
, cmsg
->cmsg_type
);
1383 memcpy(target_data
, data
, len
);
1386 cmsg
= CMSG_NXTHDR(msgh
, cmsg
);
1387 target_cmsg
= TARGET_CMSG_NXTHDR(target_msgh
, target_cmsg
);
1389 unlock_user(target_cmsg
, target_cmsg_addr
, space
);
1391 target_msgh
->msg_controllen
= tswapal(space
);
1395 /* do_setsockopt() Must return target values and target errnos. */
1396 static abi_long
do_setsockopt(int sockfd
, int level
, int optname
,
1397 abi_ulong optval_addr
, socklen_t optlen
)
1401 struct ip_mreqn
*ip_mreq
;
1402 struct ip_mreq_source
*ip_mreq_source
;
1406 /* TCP options all take an 'int' value. */
1407 if (optlen
< sizeof(uint32_t))
1408 return -TARGET_EINVAL
;
1410 if (get_user_u32(val
, optval_addr
))
1411 return -TARGET_EFAULT
;
1412 ret
= get_errno(setsockopt(sockfd
, level
, optname
, &val
, sizeof(val
)));
1419 case IP_ROUTER_ALERT
:
1423 case IP_MTU_DISCOVER
:
1429 case IP_MULTICAST_TTL
:
1430 case IP_MULTICAST_LOOP
:
1432 if (optlen
>= sizeof(uint32_t)) {
1433 if (get_user_u32(val
, optval_addr
))
1434 return -TARGET_EFAULT
;
1435 } else if (optlen
>= 1) {
1436 if (get_user_u8(val
, optval_addr
))
1437 return -TARGET_EFAULT
;
1439 ret
= get_errno(setsockopt(sockfd
, level
, optname
, &val
, sizeof(val
)));
1441 case IP_ADD_MEMBERSHIP
:
1442 case IP_DROP_MEMBERSHIP
:
1443 if (optlen
< sizeof (struct target_ip_mreq
) ||
1444 optlen
> sizeof (struct target_ip_mreqn
))
1445 return -TARGET_EINVAL
;
1447 ip_mreq
= (struct ip_mreqn
*) alloca(optlen
);
1448 target_to_host_ip_mreq(ip_mreq
, optval_addr
, optlen
);
1449 ret
= get_errno(setsockopt(sockfd
, level
, optname
, ip_mreq
, optlen
));
1452 case IP_BLOCK_SOURCE
:
1453 case IP_UNBLOCK_SOURCE
:
1454 case IP_ADD_SOURCE_MEMBERSHIP
:
1455 case IP_DROP_SOURCE_MEMBERSHIP
:
1456 if (optlen
!= sizeof (struct target_ip_mreq_source
))
1457 return -TARGET_EINVAL
;
1459 ip_mreq_source
= lock_user(VERIFY_READ
, optval_addr
, optlen
, 1);
1460 ret
= get_errno(setsockopt(sockfd
, level
, optname
, ip_mreq_source
, optlen
));
1461 unlock_user (ip_mreq_source
, optval_addr
, 0);
1471 /* struct icmp_filter takes an u32 value */
1472 if (optlen
< sizeof(uint32_t)) {
1473 return -TARGET_EINVAL
;
1476 if (get_user_u32(val
, optval_addr
)) {
1477 return -TARGET_EFAULT
;
1479 ret
= get_errno(setsockopt(sockfd
, level
, optname
,
1480 &val
, sizeof(val
)));
1487 case TARGET_SOL_SOCKET
:
1489 /* Options with 'int' argument. */
1490 case TARGET_SO_DEBUG
:
1493 case TARGET_SO_REUSEADDR
:
1494 optname
= SO_REUSEADDR
;
1496 case TARGET_SO_TYPE
:
1499 case TARGET_SO_ERROR
:
1502 case TARGET_SO_DONTROUTE
:
1503 optname
= SO_DONTROUTE
;
1505 case TARGET_SO_BROADCAST
:
1506 optname
= SO_BROADCAST
;
1508 case TARGET_SO_SNDBUF
:
1509 optname
= SO_SNDBUF
;
1511 case TARGET_SO_RCVBUF
:
1512 optname
= SO_RCVBUF
;
1514 case TARGET_SO_KEEPALIVE
:
1515 optname
= SO_KEEPALIVE
;
1517 case TARGET_SO_OOBINLINE
:
1518 optname
= SO_OOBINLINE
;
1520 case TARGET_SO_NO_CHECK
:
1521 optname
= SO_NO_CHECK
;
1523 case TARGET_SO_PRIORITY
:
1524 optname
= SO_PRIORITY
;
1527 case TARGET_SO_BSDCOMPAT
:
1528 optname
= SO_BSDCOMPAT
;
1531 case TARGET_SO_PASSCRED
:
1532 optname
= SO_PASSCRED
;
1534 case TARGET_SO_TIMESTAMP
:
1535 optname
= SO_TIMESTAMP
;
1537 case TARGET_SO_RCVLOWAT
:
1538 optname
= SO_RCVLOWAT
;
1540 case TARGET_SO_RCVTIMEO
:
1541 optname
= SO_RCVTIMEO
;
1543 case TARGET_SO_SNDTIMEO
:
1544 optname
= SO_SNDTIMEO
;
1550 if (optlen
< sizeof(uint32_t))
1551 return -TARGET_EINVAL
;
1553 if (get_user_u32(val
, optval_addr
))
1554 return -TARGET_EFAULT
;
1555 ret
= get_errno(setsockopt(sockfd
, SOL_SOCKET
, optname
, &val
, sizeof(val
)));
1559 gemu_log("Unsupported setsockopt level=%d optname=%d\n", level
, optname
);
1560 ret
= -TARGET_ENOPROTOOPT
;
1565 /* do_getsockopt() Must return target values and target errnos. */
1566 static abi_long
do_getsockopt(int sockfd
, int level
, int optname
,
1567 abi_ulong optval_addr
, abi_ulong optlen
)
1574 case TARGET_SOL_SOCKET
:
1577 /* These don't just return a single integer */
1578 case TARGET_SO_LINGER
:
1579 case TARGET_SO_RCVTIMEO
:
1580 case TARGET_SO_SNDTIMEO
:
1581 case TARGET_SO_PEERNAME
:
1583 case TARGET_SO_PEERCRED
: {
1586 struct target_ucred
*tcr
;
1588 if (get_user_u32(len
, optlen
)) {
1589 return -TARGET_EFAULT
;
1592 return -TARGET_EINVAL
;
1596 ret
= get_errno(getsockopt(sockfd
, level
, SO_PEERCRED
,
1604 if (!lock_user_struct(VERIFY_WRITE
, tcr
, optval_addr
, 0)) {
1605 return -TARGET_EFAULT
;
1607 __put_user(cr
.pid
, &tcr
->pid
);
1608 __put_user(cr
.uid
, &tcr
->uid
);
1609 __put_user(cr
.gid
, &tcr
->gid
);
1610 unlock_user_struct(tcr
, optval_addr
, 1);
1611 if (put_user_u32(len
, optlen
)) {
1612 return -TARGET_EFAULT
;
1616 /* Options with 'int' argument. */
1617 case TARGET_SO_DEBUG
:
1620 case TARGET_SO_REUSEADDR
:
1621 optname
= SO_REUSEADDR
;
1623 case TARGET_SO_TYPE
:
1626 case TARGET_SO_ERROR
:
1629 case TARGET_SO_DONTROUTE
:
1630 optname
= SO_DONTROUTE
;
1632 case TARGET_SO_BROADCAST
:
1633 optname
= SO_BROADCAST
;
1635 case TARGET_SO_SNDBUF
:
1636 optname
= SO_SNDBUF
;
1638 case TARGET_SO_RCVBUF
:
1639 optname
= SO_RCVBUF
;
1641 case TARGET_SO_KEEPALIVE
:
1642 optname
= SO_KEEPALIVE
;
1644 case TARGET_SO_OOBINLINE
:
1645 optname
= SO_OOBINLINE
;
1647 case TARGET_SO_NO_CHECK
:
1648 optname
= SO_NO_CHECK
;
1650 case TARGET_SO_PRIORITY
:
1651 optname
= SO_PRIORITY
;
1654 case TARGET_SO_BSDCOMPAT
:
1655 optname
= SO_BSDCOMPAT
;
1658 case TARGET_SO_PASSCRED
:
1659 optname
= SO_PASSCRED
;
1661 case TARGET_SO_TIMESTAMP
:
1662 optname
= SO_TIMESTAMP
;
1664 case TARGET_SO_RCVLOWAT
:
1665 optname
= SO_RCVLOWAT
;
1672 /* TCP options all take an 'int' value. */
1674 if (get_user_u32(len
, optlen
))
1675 return -TARGET_EFAULT
;
1677 return -TARGET_EINVAL
;
1679 ret
= get_errno(getsockopt(sockfd
, level
, optname
, &val
, &lv
));
1685 if (put_user_u32(val
, optval_addr
))
1686 return -TARGET_EFAULT
;
1688 if (put_user_u8(val
, optval_addr
))
1689 return -TARGET_EFAULT
;
1691 if (put_user_u32(len
, optlen
))
1692 return -TARGET_EFAULT
;
1699 case IP_ROUTER_ALERT
:
1703 case IP_MTU_DISCOVER
:
1709 case IP_MULTICAST_TTL
:
1710 case IP_MULTICAST_LOOP
:
1711 if (get_user_u32(len
, optlen
))
1712 return -TARGET_EFAULT
;
1714 return -TARGET_EINVAL
;
1716 ret
= get_errno(getsockopt(sockfd
, level
, optname
, &val
, &lv
));
1719 if (len
< sizeof(int) && len
> 0 && val
>= 0 && val
< 255) {
1721 if (put_user_u32(len
, optlen
)
1722 || put_user_u8(val
, optval_addr
))
1723 return -TARGET_EFAULT
;
1725 if (len
> sizeof(int))
1727 if (put_user_u32(len
, optlen
)
1728 || put_user_u32(val
, optval_addr
))
1729 return -TARGET_EFAULT
;
1733 ret
= -TARGET_ENOPROTOOPT
;
1739 gemu_log("getsockopt level=%d optname=%d not yet supported\n",
1741 ret
= -TARGET_EOPNOTSUPP
;
1748 * lock_iovec()/unlock_iovec() have a return code of 0 for success where
1749 * other lock functions have a return code of 0 for failure.
1751 static abi_long
lock_iovec(int type
, struct iovec
*vec
, abi_ulong target_addr
,
1752 int count
, int copy
)
1754 struct target_iovec
*target_vec
;
1758 target_vec
= lock_user(VERIFY_READ
, target_addr
, count
* sizeof(struct target_iovec
), 1);
1760 return -TARGET_EFAULT
;
1761 for(i
= 0;i
< count
; i
++) {
1762 base
= tswapal(target_vec
[i
].iov_base
);
1763 vec
[i
].iov_len
= tswapal(target_vec
[i
].iov_len
);
1764 if (vec
[i
].iov_len
!= 0) {
1765 vec
[i
].iov_base
= lock_user(type
, base
, vec
[i
].iov_len
, copy
);
1766 /* Don't check lock_user return value. We must call writev even
1767 if a element has invalid base address. */
1769 /* zero length pointer is ignored */
1770 vec
[i
].iov_base
= NULL
;
1773 unlock_user (target_vec
, target_addr
, 0);
1777 static abi_long
unlock_iovec(struct iovec
*vec
, abi_ulong target_addr
,
1778 int count
, int copy
)
1780 struct target_iovec
*target_vec
;
1784 target_vec
= lock_user(VERIFY_READ
, target_addr
, count
* sizeof(struct target_iovec
), 1);
1786 return -TARGET_EFAULT
;
1787 for(i
= 0;i
< count
; i
++) {
1788 if (target_vec
[i
].iov_base
) {
1789 base
= tswapal(target_vec
[i
].iov_base
);
1790 unlock_user(vec
[i
].iov_base
, base
, copy
? vec
[i
].iov_len
: 0);
1793 unlock_user (target_vec
, target_addr
, 0);
1798 /* do_socket() Must return target values and target errnos. */
1799 static abi_long
do_socket(int domain
, int type
, int protocol
)
1801 #if defined(TARGET_MIPS)
1803 case TARGET_SOCK_DGRAM
:
1806 case TARGET_SOCK_STREAM
:
1809 case TARGET_SOCK_RAW
:
1812 case TARGET_SOCK_RDM
:
1815 case TARGET_SOCK_SEQPACKET
:
1816 type
= SOCK_SEQPACKET
;
1818 case TARGET_SOCK_PACKET
:
1823 if (domain
== PF_NETLINK
)
1824 return -EAFNOSUPPORT
; /* do not NETLINK socket connections possible */
1825 return get_errno(socket(domain
, type
, protocol
));
1828 /* do_bind() Must return target values and target errnos. */
1829 static abi_long
do_bind(int sockfd
, abi_ulong target_addr
,
1835 if ((int)addrlen
< 0) {
1836 return -TARGET_EINVAL
;
1839 addr
= alloca(addrlen
+1);
1841 ret
= target_to_host_sockaddr(addr
, target_addr
, addrlen
);
1845 return get_errno(bind(sockfd
, addr
, addrlen
));
1848 /* do_connect() Must return target values and target errnos. */
1849 static abi_long
do_connect(int sockfd
, abi_ulong target_addr
,
1855 if ((int)addrlen
< 0) {
1856 return -TARGET_EINVAL
;
1859 addr
= alloca(addrlen
);
1861 ret
= target_to_host_sockaddr(addr
, target_addr
, addrlen
);
1865 return get_errno(connect(sockfd
, addr
, addrlen
));
1868 /* do_sendrecvmsg() Must return target values and target errnos. */
1869 static abi_long
do_sendrecvmsg(int fd
, abi_ulong target_msg
,
1870 int flags
, int send
)
1873 struct target_msghdr
*msgp
;
1877 abi_ulong target_vec
;
1880 if (!lock_user_struct(send
? VERIFY_READ
: VERIFY_WRITE
,
1884 return -TARGET_EFAULT
;
1885 if (msgp
->msg_name
) {
1886 msg
.msg_namelen
= tswap32(msgp
->msg_namelen
);
1887 msg
.msg_name
= alloca(msg
.msg_namelen
);
1888 ret
= target_to_host_sockaddr(msg
.msg_name
, tswapal(msgp
->msg_name
),
1891 unlock_user_struct(msgp
, target_msg
, send
? 0 : 1);
1895 msg
.msg_name
= NULL
;
1896 msg
.msg_namelen
= 0;
1898 msg
.msg_controllen
= 2 * tswapal(msgp
->msg_controllen
);
1899 msg
.msg_control
= alloca(msg
.msg_controllen
);
1900 msg
.msg_flags
= tswap32(msgp
->msg_flags
);
1902 count
= tswapal(msgp
->msg_iovlen
);
1903 vec
= alloca(count
* sizeof(struct iovec
));
1904 target_vec
= tswapal(msgp
->msg_iov
);
1905 lock_iovec(send
? VERIFY_READ
: VERIFY_WRITE
, vec
, target_vec
, count
, send
);
1906 msg
.msg_iovlen
= count
;
1910 ret
= target_to_host_cmsg(&msg
, msgp
);
1912 ret
= get_errno(sendmsg(fd
, &msg
, flags
));
1914 ret
= get_errno(recvmsg(fd
, &msg
, flags
));
1915 if (!is_error(ret
)) {
1917 ret
= host_to_target_cmsg(msgp
, &msg
);
1918 if (!is_error(ret
)) {
1919 msgp
->msg_namelen
= tswap32(msg
.msg_namelen
);
1920 if (msg
.msg_name
!= NULL
) {
1921 ret
= host_to_target_sockaddr(tswapal(msgp
->msg_name
),
1922 msg
.msg_name
, msg
.msg_namelen
);
1934 unlock_iovec(vec
, target_vec
, count
, !send
);
1935 unlock_user_struct(msgp
, target_msg
, send
? 0 : 1);
1939 /* do_accept() Must return target values and target errnos. */
1940 static abi_long
do_accept(int fd
, abi_ulong target_addr
,
1941 abi_ulong target_addrlen_addr
)
1947 if (target_addr
== 0)
1948 return get_errno(accept(fd
, NULL
, NULL
));
1950 /* linux returns EINVAL if addrlen pointer is invalid */
1951 if (get_user_u32(addrlen
, target_addrlen_addr
))
1952 return -TARGET_EINVAL
;
1954 if ((int)addrlen
< 0) {
1955 return -TARGET_EINVAL
;
1958 if (!access_ok(VERIFY_WRITE
, target_addr
, addrlen
))
1959 return -TARGET_EINVAL
;
1961 addr
= alloca(addrlen
);
1963 ret
= get_errno(accept(fd
, addr
, &addrlen
));
1964 if (!is_error(ret
)) {
1965 host_to_target_sockaddr(target_addr
, addr
, addrlen
);
1966 if (put_user_u32(addrlen
, target_addrlen_addr
))
1967 ret
= -TARGET_EFAULT
;
1972 /* do_getpeername() Must return target values and target errnos. */
1973 static abi_long
do_getpeername(int fd
, abi_ulong target_addr
,
1974 abi_ulong target_addrlen_addr
)
1980 if (get_user_u32(addrlen
, target_addrlen_addr
))
1981 return -TARGET_EFAULT
;
1983 if ((int)addrlen
< 0) {
1984 return -TARGET_EINVAL
;
1987 if (!access_ok(VERIFY_WRITE
, target_addr
, addrlen
))
1988 return -TARGET_EFAULT
;
1990 addr
= alloca(addrlen
);
1992 ret
= get_errno(getpeername(fd
, addr
, &addrlen
));
1993 if (!is_error(ret
)) {
1994 host_to_target_sockaddr(target_addr
, addr
, addrlen
);
1995 if (put_user_u32(addrlen
, target_addrlen_addr
))
1996 ret
= -TARGET_EFAULT
;
2001 /* do_getsockname() Must return target values and target errnos. */
2002 static abi_long
do_getsockname(int fd
, abi_ulong target_addr
,
2003 abi_ulong target_addrlen_addr
)
2009 if (get_user_u32(addrlen
, target_addrlen_addr
))
2010 return -TARGET_EFAULT
;
2012 if ((int)addrlen
< 0) {
2013 return -TARGET_EINVAL
;
2016 if (!access_ok(VERIFY_WRITE
, target_addr
, addrlen
))
2017 return -TARGET_EFAULT
;
2019 addr
= alloca(addrlen
);
2021 ret
= get_errno(getsockname(fd
, addr
, &addrlen
));
2022 if (!is_error(ret
)) {
2023 host_to_target_sockaddr(target_addr
, addr
, addrlen
);
2024 if (put_user_u32(addrlen
, target_addrlen_addr
))
2025 ret
= -TARGET_EFAULT
;
2030 /* do_socketpair() Must return target values and target errnos. */
2031 static abi_long
do_socketpair(int domain
, int type
, int protocol
,
2032 abi_ulong target_tab_addr
)
2037 ret
= get_errno(socketpair(domain
, type
, protocol
, tab
));
2038 if (!is_error(ret
)) {
2039 if (put_user_s32(tab
[0], target_tab_addr
)
2040 || put_user_s32(tab
[1], target_tab_addr
+ sizeof(tab
[0])))
2041 ret
= -TARGET_EFAULT
;
2046 /* do_sendto() Must return target values and target errnos. */
2047 static abi_long
do_sendto(int fd
, abi_ulong msg
, size_t len
, int flags
,
2048 abi_ulong target_addr
, socklen_t addrlen
)
2054 if ((int)addrlen
< 0) {
2055 return -TARGET_EINVAL
;
2058 host_msg
= lock_user(VERIFY_READ
, msg
, len
, 1);
2060 return -TARGET_EFAULT
;
2062 addr
= alloca(addrlen
);
2063 ret
= target_to_host_sockaddr(addr
, target_addr
, addrlen
);
2065 unlock_user(host_msg
, msg
, 0);
2068 ret
= get_errno(sendto(fd
, host_msg
, len
, flags
, addr
, addrlen
));
2070 ret
= get_errno(send(fd
, host_msg
, len
, flags
));
2072 unlock_user(host_msg
, msg
, 0);
2076 /* do_recvfrom() Must return target values and target errnos. */
2077 static abi_long
do_recvfrom(int fd
, abi_ulong msg
, size_t len
, int flags
,
2078 abi_ulong target_addr
,
2079 abi_ulong target_addrlen
)
2086 host_msg
= lock_user(VERIFY_WRITE
, msg
, len
, 0);
2088 return -TARGET_EFAULT
;
2090 if (get_user_u32(addrlen
, target_addrlen
)) {
2091 ret
= -TARGET_EFAULT
;
2094 if ((int)addrlen
< 0) {
2095 ret
= -TARGET_EINVAL
;
2098 addr
= alloca(addrlen
);
2099 ret
= get_errno(recvfrom(fd
, host_msg
, len
, flags
, addr
, &addrlen
));
2101 addr
= NULL
; /* To keep compiler quiet. */
2102 ret
= get_errno(qemu_recv(fd
, host_msg
, len
, flags
));
2104 if (!is_error(ret
)) {
2106 host_to_target_sockaddr(target_addr
, addr
, addrlen
);
2107 if (put_user_u32(addrlen
, target_addrlen
)) {
2108 ret
= -TARGET_EFAULT
;
2112 unlock_user(host_msg
, msg
, len
);
2115 unlock_user(host_msg
, msg
, 0);
2120 #ifdef TARGET_NR_socketcall
2121 /* do_socketcall() Must return target values and target errnos. */
2122 static abi_long
do_socketcall(int num
, abi_ulong vptr
)
2125 const int n
= sizeof(abi_ulong
);
2130 abi_ulong domain
, type
, protocol
;
2132 if (get_user_ual(domain
, vptr
)
2133 || get_user_ual(type
, vptr
+ n
)
2134 || get_user_ual(protocol
, vptr
+ 2 * n
))
2135 return -TARGET_EFAULT
;
2137 ret
= do_socket(domain
, type
, protocol
);
2143 abi_ulong target_addr
;
2146 if (get_user_ual(sockfd
, vptr
)
2147 || get_user_ual(target_addr
, vptr
+ n
)
2148 || get_user_ual(addrlen
, vptr
+ 2 * n
))
2149 return -TARGET_EFAULT
;
2151 ret
= do_bind(sockfd
, target_addr
, addrlen
);
2154 case SOCKOP_connect
:
2157 abi_ulong target_addr
;
2160 if (get_user_ual(sockfd
, vptr
)
2161 || get_user_ual(target_addr
, vptr
+ n
)
2162 || get_user_ual(addrlen
, vptr
+ 2 * n
))
2163 return -TARGET_EFAULT
;
2165 ret
= do_connect(sockfd
, target_addr
, addrlen
);
2170 abi_ulong sockfd
, backlog
;
2172 if (get_user_ual(sockfd
, vptr
)
2173 || get_user_ual(backlog
, vptr
+ n
))
2174 return -TARGET_EFAULT
;
2176 ret
= get_errno(listen(sockfd
, backlog
));
2182 abi_ulong target_addr
, target_addrlen
;
2184 if (get_user_ual(sockfd
, vptr
)
2185 || get_user_ual(target_addr
, vptr
+ n
)
2186 || get_user_ual(target_addrlen
, vptr
+ 2 * n
))
2187 return -TARGET_EFAULT
;
2189 ret
= do_accept(sockfd
, target_addr
, target_addrlen
);
2192 case SOCKOP_getsockname
:
2195 abi_ulong target_addr
, target_addrlen
;
2197 if (get_user_ual(sockfd
, vptr
)
2198 || get_user_ual(target_addr
, vptr
+ n
)
2199 || get_user_ual(target_addrlen
, vptr
+ 2 * n
))
2200 return -TARGET_EFAULT
;
2202 ret
= do_getsockname(sockfd
, target_addr
, target_addrlen
);
2205 case SOCKOP_getpeername
:
2208 abi_ulong target_addr
, target_addrlen
;
2210 if (get_user_ual(sockfd
, vptr
)
2211 || get_user_ual(target_addr
, vptr
+ n
)
2212 || get_user_ual(target_addrlen
, vptr
+ 2 * n
))
2213 return -TARGET_EFAULT
;
2215 ret
= do_getpeername(sockfd
, target_addr
, target_addrlen
);
2218 case SOCKOP_socketpair
:
2220 abi_ulong domain
, type
, protocol
;
2223 if (get_user_ual(domain
, vptr
)
2224 || get_user_ual(type
, vptr
+ n
)
2225 || get_user_ual(protocol
, vptr
+ 2 * n
)
2226 || get_user_ual(tab
, vptr
+ 3 * n
))
2227 return -TARGET_EFAULT
;
2229 ret
= do_socketpair(domain
, type
, protocol
, tab
);
2239 if (get_user_ual(sockfd
, vptr
)
2240 || get_user_ual(msg
, vptr
+ n
)
2241 || get_user_ual(len
, vptr
+ 2 * n
)
2242 || get_user_ual(flags
, vptr
+ 3 * n
))
2243 return -TARGET_EFAULT
;
2245 ret
= do_sendto(sockfd
, msg
, len
, flags
, 0, 0);
2255 if (get_user_ual(sockfd
, vptr
)
2256 || get_user_ual(msg
, vptr
+ n
)
2257 || get_user_ual(len
, vptr
+ 2 * n
)
2258 || get_user_ual(flags
, vptr
+ 3 * n
))
2259 return -TARGET_EFAULT
;
2261 ret
= do_recvfrom(sockfd
, msg
, len
, flags
, 0, 0);
2273 if (get_user_ual(sockfd
, vptr
)
2274 || get_user_ual(msg
, vptr
+ n
)
2275 || get_user_ual(len
, vptr
+ 2 * n
)
2276 || get_user_ual(flags
, vptr
+ 3 * n
)
2277 || get_user_ual(addr
, vptr
+ 4 * n
)
2278 || get_user_ual(addrlen
, vptr
+ 5 * n
))
2279 return -TARGET_EFAULT
;
2281 ret
= do_sendto(sockfd
, msg
, len
, flags
, addr
, addrlen
);
2284 case SOCKOP_recvfrom
:
2293 if (get_user_ual(sockfd
, vptr
)
2294 || get_user_ual(msg
, vptr
+ n
)
2295 || get_user_ual(len
, vptr
+ 2 * n
)
2296 || get_user_ual(flags
, vptr
+ 3 * n
)
2297 || get_user_ual(addr
, vptr
+ 4 * n
)
2298 || get_user_ual(addrlen
, vptr
+ 5 * n
))
2299 return -TARGET_EFAULT
;
2301 ret
= do_recvfrom(sockfd
, msg
, len
, flags
, addr
, addrlen
);
2304 case SOCKOP_shutdown
:
2306 abi_ulong sockfd
, how
;
2308 if (get_user_ual(sockfd
, vptr
)
2309 || get_user_ual(how
, vptr
+ n
))
2310 return -TARGET_EFAULT
;
2312 ret
= get_errno(shutdown(sockfd
, how
));
2315 case SOCKOP_sendmsg
:
2316 case SOCKOP_recvmsg
:
2319 abi_ulong target_msg
;
2322 if (get_user_ual(fd
, vptr
)
2323 || get_user_ual(target_msg
, vptr
+ n
)
2324 || get_user_ual(flags
, vptr
+ 2 * n
))
2325 return -TARGET_EFAULT
;
2327 ret
= do_sendrecvmsg(fd
, target_msg
, flags
,
2328 (num
== SOCKOP_sendmsg
));
2331 case SOCKOP_setsockopt
:
2339 if (get_user_ual(sockfd
, vptr
)
2340 || get_user_ual(level
, vptr
+ n
)
2341 || get_user_ual(optname
, vptr
+ 2 * n
)
2342 || get_user_ual(optval
, vptr
+ 3 * n
)
2343 || get_user_ual(optlen
, vptr
+ 4 * n
))
2344 return -TARGET_EFAULT
;
2346 ret
= do_setsockopt(sockfd
, level
, optname
, optval
, optlen
);
2349 case SOCKOP_getsockopt
:
2357 if (get_user_ual(sockfd
, vptr
)
2358 || get_user_ual(level
, vptr
+ n
)
2359 || get_user_ual(optname
, vptr
+ 2 * n
)
2360 || get_user_ual(optval
, vptr
+ 3 * n
)
2361 || get_user_ual(optlen
, vptr
+ 4 * n
))
2362 return -TARGET_EFAULT
;
2364 ret
= do_getsockopt(sockfd
, level
, optname
, optval
, optlen
);
2368 gemu_log("Unsupported socketcall: %d\n", num
);
2369 ret
= -TARGET_ENOSYS
;
2376 #define N_SHM_REGIONS 32
2378 static struct shm_region
{
2381 } shm_regions
[N_SHM_REGIONS
];
2383 struct target_ipc_perm
2390 unsigned short int mode
;
2391 unsigned short int __pad1
;
2392 unsigned short int __seq
;
2393 unsigned short int __pad2
;
2394 abi_ulong __unused1
;
2395 abi_ulong __unused2
;
2398 struct target_semid_ds
2400 struct target_ipc_perm sem_perm
;
2401 abi_ulong sem_otime
;
2402 abi_ulong __unused1
;
2403 abi_ulong sem_ctime
;
2404 abi_ulong __unused2
;
2405 abi_ulong sem_nsems
;
2406 abi_ulong __unused3
;
2407 abi_ulong __unused4
;
2410 static inline abi_long
target_to_host_ipc_perm(struct ipc_perm
*host_ip
,
2411 abi_ulong target_addr
)
2413 struct target_ipc_perm
*target_ip
;
2414 struct target_semid_ds
*target_sd
;
2416 if (!lock_user_struct(VERIFY_READ
, target_sd
, target_addr
, 1))
2417 return -TARGET_EFAULT
;
2418 target_ip
= &(target_sd
->sem_perm
);
2419 host_ip
->__key
= tswapal(target_ip
->__key
);
2420 host_ip
->uid
= tswapal(target_ip
->uid
);
2421 host_ip
->gid
= tswapal(target_ip
->gid
);
2422 host_ip
->cuid
= tswapal(target_ip
->cuid
);
2423 host_ip
->cgid
= tswapal(target_ip
->cgid
);
2424 host_ip
->mode
= tswap16(target_ip
->mode
);
2425 unlock_user_struct(target_sd
, target_addr
, 0);
2429 static inline abi_long
host_to_target_ipc_perm(abi_ulong target_addr
,
2430 struct ipc_perm
*host_ip
)
2432 struct target_ipc_perm
*target_ip
;
2433 struct target_semid_ds
*target_sd
;
2435 if (!lock_user_struct(VERIFY_WRITE
, target_sd
, target_addr
, 0))
2436 return -TARGET_EFAULT
;
2437 target_ip
= &(target_sd
->sem_perm
);
2438 target_ip
->__key
= tswapal(host_ip
->__key
);
2439 target_ip
->uid
= tswapal(host_ip
->uid
);
2440 target_ip
->gid
= tswapal(host_ip
->gid
);
2441 target_ip
->cuid
= tswapal(host_ip
->cuid
);
2442 target_ip
->cgid
= tswapal(host_ip
->cgid
);
2443 target_ip
->mode
= tswap16(host_ip
->mode
);
2444 unlock_user_struct(target_sd
, target_addr
, 1);
2448 static inline abi_long
target_to_host_semid_ds(struct semid_ds
*host_sd
,
2449 abi_ulong target_addr
)
2451 struct target_semid_ds
*target_sd
;
2453 if (!lock_user_struct(VERIFY_READ
, target_sd
, target_addr
, 1))
2454 return -TARGET_EFAULT
;
2455 if (target_to_host_ipc_perm(&(host_sd
->sem_perm
),target_addr
))
2456 return -TARGET_EFAULT
;
2457 host_sd
->sem_nsems
= tswapal(target_sd
->sem_nsems
);
2458 host_sd
->sem_otime
= tswapal(target_sd
->sem_otime
);
2459 host_sd
->sem_ctime
= tswapal(target_sd
->sem_ctime
);
2460 unlock_user_struct(target_sd
, target_addr
, 0);
2464 static inline abi_long
host_to_target_semid_ds(abi_ulong target_addr
,
2465 struct semid_ds
*host_sd
)
2467 struct target_semid_ds
*target_sd
;
2469 if (!lock_user_struct(VERIFY_WRITE
, target_sd
, target_addr
, 0))
2470 return -TARGET_EFAULT
;
2471 if (host_to_target_ipc_perm(target_addr
,&(host_sd
->sem_perm
)))
2472 return -TARGET_EFAULT
;
2473 target_sd
->sem_nsems
= tswapal(host_sd
->sem_nsems
);
2474 target_sd
->sem_otime
= tswapal(host_sd
->sem_otime
);
2475 target_sd
->sem_ctime
= tswapal(host_sd
->sem_ctime
);
2476 unlock_user_struct(target_sd
, target_addr
, 1);
2480 struct target_seminfo
{
2493 static inline abi_long
host_to_target_seminfo(abi_ulong target_addr
,
2494 struct seminfo
*host_seminfo
)
2496 struct target_seminfo
*target_seminfo
;
2497 if (!lock_user_struct(VERIFY_WRITE
, target_seminfo
, target_addr
, 0))
2498 return -TARGET_EFAULT
;
2499 __put_user(host_seminfo
->semmap
, &target_seminfo
->semmap
);
2500 __put_user(host_seminfo
->semmni
, &target_seminfo
->semmni
);
2501 __put_user(host_seminfo
->semmns
, &target_seminfo
->semmns
);
2502 __put_user(host_seminfo
->semmnu
, &target_seminfo
->semmnu
);
2503 __put_user(host_seminfo
->semmsl
, &target_seminfo
->semmsl
);
2504 __put_user(host_seminfo
->semopm
, &target_seminfo
->semopm
);
2505 __put_user(host_seminfo
->semume
, &target_seminfo
->semume
);
2506 __put_user(host_seminfo
->semusz
, &target_seminfo
->semusz
);
2507 __put_user(host_seminfo
->semvmx
, &target_seminfo
->semvmx
);
2508 __put_user(host_seminfo
->semaem
, &target_seminfo
->semaem
);
2509 unlock_user_struct(target_seminfo
, target_addr
, 1);
2515 struct semid_ds
*buf
;
2516 unsigned short *array
;
2517 struct seminfo
*__buf
;
2520 union target_semun
{
2527 static inline abi_long
target_to_host_semarray(int semid
, unsigned short **host_array
,
2528 abi_ulong target_addr
)
2531 unsigned short *array
;
2533 struct semid_ds semid_ds
;
2536 semun
.buf
= &semid_ds
;
2538 ret
= semctl(semid
, 0, IPC_STAT
, semun
);
2540 return get_errno(ret
);
2542 nsems
= semid_ds
.sem_nsems
;
2544 *host_array
= malloc(nsems
*sizeof(unsigned short));
2545 array
= lock_user(VERIFY_READ
, target_addr
,
2546 nsems
*sizeof(unsigned short), 1);
2548 return -TARGET_EFAULT
;
2550 for(i
=0; i
<nsems
; i
++) {
2551 __get_user((*host_array
)[i
], &array
[i
]);
2553 unlock_user(array
, target_addr
, 0);
2558 static inline abi_long
host_to_target_semarray(int semid
, abi_ulong target_addr
,
2559 unsigned short **host_array
)
2562 unsigned short *array
;
2564 struct semid_ds semid_ds
;
2567 semun
.buf
= &semid_ds
;
2569 ret
= semctl(semid
, 0, IPC_STAT
, semun
);
2571 return get_errno(ret
);
2573 nsems
= semid_ds
.sem_nsems
;
2575 array
= lock_user(VERIFY_WRITE
, target_addr
,
2576 nsems
*sizeof(unsigned short), 0);
2578 return -TARGET_EFAULT
;
2580 for(i
=0; i
<nsems
; i
++) {
2581 __put_user((*host_array
)[i
], &array
[i
]);
2584 unlock_user(array
, target_addr
, 1);
2589 static inline abi_long
do_semctl(int semid
, int semnum
, int cmd
,
2590 union target_semun target_su
)
2593 struct semid_ds dsarg
;
2594 unsigned short *array
= NULL
;
2595 struct seminfo seminfo
;
2596 abi_long ret
= -TARGET_EINVAL
;
2603 arg
.val
= tswap32(target_su
.val
);
2604 ret
= get_errno(semctl(semid
, semnum
, cmd
, arg
));
2605 target_su
.val
= tswap32(arg
.val
);
2609 err
= target_to_host_semarray(semid
, &array
, target_su
.array
);
2613 ret
= get_errno(semctl(semid
, semnum
, cmd
, arg
));
2614 err
= host_to_target_semarray(semid
, target_su
.array
, &array
);
2621 err
= target_to_host_semid_ds(&dsarg
, target_su
.buf
);
2625 ret
= get_errno(semctl(semid
, semnum
, cmd
, arg
));
2626 err
= host_to_target_semid_ds(target_su
.buf
, &dsarg
);
2632 arg
.__buf
= &seminfo
;
2633 ret
= get_errno(semctl(semid
, semnum
, cmd
, arg
));
2634 err
= host_to_target_seminfo(target_su
.__buf
, &seminfo
);
2642 ret
= get_errno(semctl(semid
, semnum
, cmd
, NULL
));
2649 struct target_sembuf
{
2650 unsigned short sem_num
;
2655 static inline abi_long
target_to_host_sembuf(struct sembuf
*host_sembuf
,
2656 abi_ulong target_addr
,
2659 struct target_sembuf
*target_sembuf
;
2662 target_sembuf
= lock_user(VERIFY_READ
, target_addr
,
2663 nsops
*sizeof(struct target_sembuf
), 1);
2665 return -TARGET_EFAULT
;
2667 for(i
=0; i
<nsops
; i
++) {
2668 __get_user(host_sembuf
[i
].sem_num
, &target_sembuf
[i
].sem_num
);
2669 __get_user(host_sembuf
[i
].sem_op
, &target_sembuf
[i
].sem_op
);
2670 __get_user(host_sembuf
[i
].sem_flg
, &target_sembuf
[i
].sem_flg
);
2673 unlock_user(target_sembuf
, target_addr
, 0);
2678 static inline abi_long
do_semop(int semid
, abi_long ptr
, unsigned nsops
)
2680 struct sembuf sops
[nsops
];
2682 if (target_to_host_sembuf(sops
, ptr
, nsops
))
2683 return -TARGET_EFAULT
;
2685 return semop(semid
, sops
, nsops
);
2688 struct target_msqid_ds
2690 struct target_ipc_perm msg_perm
;
2691 abi_ulong msg_stime
;
2692 #if TARGET_ABI_BITS == 32
2693 abi_ulong __unused1
;
2695 abi_ulong msg_rtime
;
2696 #if TARGET_ABI_BITS == 32
2697 abi_ulong __unused2
;
2699 abi_ulong msg_ctime
;
2700 #if TARGET_ABI_BITS == 32
2701 abi_ulong __unused3
;
2703 abi_ulong __msg_cbytes
;
2705 abi_ulong msg_qbytes
;
2706 abi_ulong msg_lspid
;
2707 abi_ulong msg_lrpid
;
2708 abi_ulong __unused4
;
2709 abi_ulong __unused5
;
2712 static inline abi_long
target_to_host_msqid_ds(struct msqid_ds
*host_md
,
2713 abi_ulong target_addr
)
2715 struct target_msqid_ds
*target_md
;
2717 if (!lock_user_struct(VERIFY_READ
, target_md
, target_addr
, 1))
2718 return -TARGET_EFAULT
;
2719 if (target_to_host_ipc_perm(&(host_md
->msg_perm
),target_addr
))
2720 return -TARGET_EFAULT
;
2721 host_md
->msg_stime
= tswapal(target_md
->msg_stime
);
2722 host_md
->msg_rtime
= tswapal(target_md
->msg_rtime
);
2723 host_md
->msg_ctime
= tswapal(target_md
->msg_ctime
);
2724 host_md
->__msg_cbytes
= tswapal(target_md
->__msg_cbytes
);
2725 host_md
->msg_qnum
= tswapal(target_md
->msg_qnum
);
2726 host_md
->msg_qbytes
= tswapal(target_md
->msg_qbytes
);
2727 host_md
->msg_lspid
= tswapal(target_md
->msg_lspid
);
2728 host_md
->msg_lrpid
= tswapal(target_md
->msg_lrpid
);
2729 unlock_user_struct(target_md
, target_addr
, 0);
2733 static inline abi_long
host_to_target_msqid_ds(abi_ulong target_addr
,
2734 struct msqid_ds
*host_md
)
2736 struct target_msqid_ds
*target_md
;
2738 if (!lock_user_struct(VERIFY_WRITE
, target_md
, target_addr
, 0))
2739 return -TARGET_EFAULT
;
2740 if (host_to_target_ipc_perm(target_addr
,&(host_md
->msg_perm
)))
2741 return -TARGET_EFAULT
;
2742 target_md
->msg_stime
= tswapal(host_md
->msg_stime
);
2743 target_md
->msg_rtime
= tswapal(host_md
->msg_rtime
);
2744 target_md
->msg_ctime
= tswapal(host_md
->msg_ctime
);
2745 target_md
->__msg_cbytes
= tswapal(host_md
->__msg_cbytes
);
2746 target_md
->msg_qnum
= tswapal(host_md
->msg_qnum
);
2747 target_md
->msg_qbytes
= tswapal(host_md
->msg_qbytes
);
2748 target_md
->msg_lspid
= tswapal(host_md
->msg_lspid
);
2749 target_md
->msg_lrpid
= tswapal(host_md
->msg_lrpid
);
2750 unlock_user_struct(target_md
, target_addr
, 1);
2754 struct target_msginfo
{
2762 unsigned short int msgseg
;
2765 static inline abi_long
host_to_target_msginfo(abi_ulong target_addr
,
2766 struct msginfo
*host_msginfo
)
2768 struct target_msginfo
*target_msginfo
;
2769 if (!lock_user_struct(VERIFY_WRITE
, target_msginfo
, target_addr
, 0))
2770 return -TARGET_EFAULT
;
2771 __put_user(host_msginfo
->msgpool
, &target_msginfo
->msgpool
);
2772 __put_user(host_msginfo
->msgmap
, &target_msginfo
->msgmap
);
2773 __put_user(host_msginfo
->msgmax
, &target_msginfo
->msgmax
);
2774 __put_user(host_msginfo
->msgmnb
, &target_msginfo
->msgmnb
);
2775 __put_user(host_msginfo
->msgmni
, &target_msginfo
->msgmni
);
2776 __put_user(host_msginfo
->msgssz
, &target_msginfo
->msgssz
);
2777 __put_user(host_msginfo
->msgtql
, &target_msginfo
->msgtql
);
2778 __put_user(host_msginfo
->msgseg
, &target_msginfo
->msgseg
);
2779 unlock_user_struct(target_msginfo
, target_addr
, 1);
2783 static inline abi_long
do_msgctl(int msgid
, int cmd
, abi_long ptr
)
2785 struct msqid_ds dsarg
;
2786 struct msginfo msginfo
;
2787 abi_long ret
= -TARGET_EINVAL
;
2795 if (target_to_host_msqid_ds(&dsarg
,ptr
))
2796 return -TARGET_EFAULT
;
2797 ret
= get_errno(msgctl(msgid
, cmd
, &dsarg
));
2798 if (host_to_target_msqid_ds(ptr
,&dsarg
))
2799 return -TARGET_EFAULT
;
2802 ret
= get_errno(msgctl(msgid
, cmd
, NULL
));
2806 ret
= get_errno(msgctl(msgid
, cmd
, (struct msqid_ds
*)&msginfo
));
2807 if (host_to_target_msginfo(ptr
, &msginfo
))
2808 return -TARGET_EFAULT
;
2815 struct target_msgbuf
{
2820 static inline abi_long
do_msgsnd(int msqid
, abi_long msgp
,
2821 unsigned int msgsz
, int msgflg
)
2823 struct target_msgbuf
*target_mb
;
2824 struct msgbuf
*host_mb
;
2827 if (!lock_user_struct(VERIFY_READ
, target_mb
, msgp
, 0))
2828 return -TARGET_EFAULT
;
2829 host_mb
= malloc(msgsz
+sizeof(long));
2830 host_mb
->mtype
= (abi_long
) tswapal(target_mb
->mtype
);
2831 memcpy(host_mb
->mtext
, target_mb
->mtext
, msgsz
);
2832 ret
= get_errno(msgsnd(msqid
, host_mb
, msgsz
, msgflg
));
2834 unlock_user_struct(target_mb
, msgp
, 0);
2839 static inline abi_long
do_msgrcv(int msqid
, abi_long msgp
,
2840 unsigned int msgsz
, abi_long msgtyp
,
2843 struct target_msgbuf
*target_mb
;
2845 struct msgbuf
*host_mb
;
2848 if (!lock_user_struct(VERIFY_WRITE
, target_mb
, msgp
, 0))
2849 return -TARGET_EFAULT
;
2851 host_mb
= g_malloc(msgsz
+sizeof(long));
2852 ret
= get_errno(msgrcv(msqid
, host_mb
, msgsz
, tswapal(msgtyp
), msgflg
));
2855 abi_ulong target_mtext_addr
= msgp
+ sizeof(abi_ulong
);
2856 target_mtext
= lock_user(VERIFY_WRITE
, target_mtext_addr
, ret
, 0);
2857 if (!target_mtext
) {
2858 ret
= -TARGET_EFAULT
;
2861 memcpy(target_mb
->mtext
, host_mb
->mtext
, ret
);
2862 unlock_user(target_mtext
, target_mtext_addr
, ret
);
2865 target_mb
->mtype
= tswapal(host_mb
->mtype
);
2869 unlock_user_struct(target_mb
, msgp
, 1);
2874 struct target_shmid_ds
2876 struct target_ipc_perm shm_perm
;
2877 abi_ulong shm_segsz
;
2878 abi_ulong shm_atime
;
2879 #if TARGET_ABI_BITS == 32
2880 abi_ulong __unused1
;
2882 abi_ulong shm_dtime
;
2883 #if TARGET_ABI_BITS == 32
2884 abi_ulong __unused2
;
2886 abi_ulong shm_ctime
;
2887 #if TARGET_ABI_BITS == 32
2888 abi_ulong __unused3
;
2892 abi_ulong shm_nattch
;
2893 unsigned long int __unused4
;
2894 unsigned long int __unused5
;
2897 static inline abi_long
target_to_host_shmid_ds(struct shmid_ds
*host_sd
,
2898 abi_ulong target_addr
)
2900 struct target_shmid_ds
*target_sd
;
2902 if (!lock_user_struct(VERIFY_READ
, target_sd
, target_addr
, 1))
2903 return -TARGET_EFAULT
;
2904 if (target_to_host_ipc_perm(&(host_sd
->shm_perm
), target_addr
))
2905 return -TARGET_EFAULT
;
2906 __get_user(host_sd
->shm_segsz
, &target_sd
->shm_segsz
);
2907 __get_user(host_sd
->shm_atime
, &target_sd
->shm_atime
);
2908 __get_user(host_sd
->shm_dtime
, &target_sd
->shm_dtime
);
2909 __get_user(host_sd
->shm_ctime
, &target_sd
->shm_ctime
);
2910 __get_user(host_sd
->shm_cpid
, &target_sd
->shm_cpid
);
2911 __get_user(host_sd
->shm_lpid
, &target_sd
->shm_lpid
);
2912 __get_user(host_sd
->shm_nattch
, &target_sd
->shm_nattch
);
2913 unlock_user_struct(target_sd
, target_addr
, 0);
2917 static inline abi_long
host_to_target_shmid_ds(abi_ulong target_addr
,
2918 struct shmid_ds
*host_sd
)
2920 struct target_shmid_ds
*target_sd
;
2922 if (!lock_user_struct(VERIFY_WRITE
, target_sd
, target_addr
, 0))
2923 return -TARGET_EFAULT
;
2924 if (host_to_target_ipc_perm(target_addr
, &(host_sd
->shm_perm
)))
2925 return -TARGET_EFAULT
;
2926 __put_user(host_sd
->shm_segsz
, &target_sd
->shm_segsz
);
2927 __put_user(host_sd
->shm_atime
, &target_sd
->shm_atime
);
2928 __put_user(host_sd
->shm_dtime
, &target_sd
->shm_dtime
);
2929 __put_user(host_sd
->shm_ctime
, &target_sd
->shm_ctime
);
2930 __put_user(host_sd
->shm_cpid
, &target_sd
->shm_cpid
);
2931 __put_user(host_sd
->shm_lpid
, &target_sd
->shm_lpid
);
2932 __put_user(host_sd
->shm_nattch
, &target_sd
->shm_nattch
);
2933 unlock_user_struct(target_sd
, target_addr
, 1);
2937 struct target_shminfo
{
2945 static inline abi_long
host_to_target_shminfo(abi_ulong target_addr
,
2946 struct shminfo
*host_shminfo
)
2948 struct target_shminfo
*target_shminfo
;
2949 if (!lock_user_struct(VERIFY_WRITE
, target_shminfo
, target_addr
, 0))
2950 return -TARGET_EFAULT
;
2951 __put_user(host_shminfo
->shmmax
, &target_shminfo
->shmmax
);
2952 __put_user(host_shminfo
->shmmin
, &target_shminfo
->shmmin
);
2953 __put_user(host_shminfo
->shmmni
, &target_shminfo
->shmmni
);
2954 __put_user(host_shminfo
->shmseg
, &target_shminfo
->shmseg
);
2955 __put_user(host_shminfo
->shmall
, &target_shminfo
->shmall
);
2956 unlock_user_struct(target_shminfo
, target_addr
, 1);
2960 struct target_shm_info
{
2965 abi_ulong swap_attempts
;
2966 abi_ulong swap_successes
;
2969 static inline abi_long
host_to_target_shm_info(abi_ulong target_addr
,
2970 struct shm_info
*host_shm_info
)
2972 struct target_shm_info
*target_shm_info
;
2973 if (!lock_user_struct(VERIFY_WRITE
, target_shm_info
, target_addr
, 0))
2974 return -TARGET_EFAULT
;
2975 __put_user(host_shm_info
->used_ids
, &target_shm_info
->used_ids
);
2976 __put_user(host_shm_info
->shm_tot
, &target_shm_info
->shm_tot
);
2977 __put_user(host_shm_info
->shm_rss
, &target_shm_info
->shm_rss
);
2978 __put_user(host_shm_info
->shm_swp
, &target_shm_info
->shm_swp
);
2979 __put_user(host_shm_info
->swap_attempts
, &target_shm_info
->swap_attempts
);
2980 __put_user(host_shm_info
->swap_successes
, &target_shm_info
->swap_successes
);
2981 unlock_user_struct(target_shm_info
, target_addr
, 1);
2985 static inline abi_long
do_shmctl(int shmid
, int cmd
, abi_long buf
)
2987 struct shmid_ds dsarg
;
2988 struct shminfo shminfo
;
2989 struct shm_info shm_info
;
2990 abi_long ret
= -TARGET_EINVAL
;
2998 if (target_to_host_shmid_ds(&dsarg
, buf
))
2999 return -TARGET_EFAULT
;
3000 ret
= get_errno(shmctl(shmid
, cmd
, &dsarg
));
3001 if (host_to_target_shmid_ds(buf
, &dsarg
))
3002 return -TARGET_EFAULT
;
3005 ret
= get_errno(shmctl(shmid
, cmd
, (struct shmid_ds
*)&shminfo
));
3006 if (host_to_target_shminfo(buf
, &shminfo
))
3007 return -TARGET_EFAULT
;
3010 ret
= get_errno(shmctl(shmid
, cmd
, (struct shmid_ds
*)&shm_info
));
3011 if (host_to_target_shm_info(buf
, &shm_info
))
3012 return -TARGET_EFAULT
;
3017 ret
= get_errno(shmctl(shmid
, cmd
, NULL
));
3024 static inline abi_ulong
do_shmat(int shmid
, abi_ulong shmaddr
, int shmflg
)
3028 struct shmid_ds shm_info
;
3031 /* find out the length of the shared memory segment */
3032 ret
= get_errno(shmctl(shmid
, IPC_STAT
, &shm_info
));
3033 if (is_error(ret
)) {
3034 /* can't get length, bail out */
3041 host_raddr
= shmat(shmid
, (void *)g2h(shmaddr
), shmflg
);
3043 abi_ulong mmap_start
;
3045 mmap_start
= mmap_find_vma(0, shm_info
.shm_segsz
);
3047 if (mmap_start
== -1) {
3049 host_raddr
= (void *)-1;
3051 host_raddr
= shmat(shmid
, g2h(mmap_start
), shmflg
| SHM_REMAP
);
3054 if (host_raddr
== (void *)-1) {
3056 return get_errno((long)host_raddr
);
3058 raddr
=h2g((unsigned long)host_raddr
);
3060 page_set_flags(raddr
, raddr
+ shm_info
.shm_segsz
,
3061 PAGE_VALID
| PAGE_READ
|
3062 ((shmflg
& SHM_RDONLY
)? 0 : PAGE_WRITE
));
3064 for (i
= 0; i
< N_SHM_REGIONS
; i
++) {
3065 if (shm_regions
[i
].start
== 0) {
3066 shm_regions
[i
].start
= raddr
;
3067 shm_regions
[i
].size
= shm_info
.shm_segsz
;
3077 static inline abi_long
do_shmdt(abi_ulong shmaddr
)
3081 for (i
= 0; i
< N_SHM_REGIONS
; ++i
) {
3082 if (shm_regions
[i
].start
== shmaddr
) {
3083 shm_regions
[i
].start
= 0;
3084 page_set_flags(shmaddr
, shmaddr
+ shm_regions
[i
].size
, 0);
3089 return get_errno(shmdt(g2h(shmaddr
)));
3092 #ifdef TARGET_NR_ipc
3093 /* ??? This only works with linear mappings. */
3094 /* do_ipc() must return target values and target errnos. */
3095 static abi_long
do_ipc(unsigned int call
, int first
,
3096 int second
, int third
,
3097 abi_long ptr
, abi_long fifth
)
3102 version
= call
>> 16;
3107 ret
= do_semop(first
, ptr
, second
);
3111 ret
= get_errno(semget(first
, second
, third
));
3115 ret
= do_semctl(first
, second
, third
, (union target_semun
)(abi_ulong
) ptr
);
3119 ret
= get_errno(msgget(first
, second
));
3123 ret
= do_msgsnd(first
, ptr
, second
, third
);
3127 ret
= do_msgctl(first
, second
, ptr
);
3134 struct target_ipc_kludge
{
3139 if (!lock_user_struct(VERIFY_READ
, tmp
, ptr
, 1)) {
3140 ret
= -TARGET_EFAULT
;
3144 ret
= do_msgrcv(first
, tmp
->msgp
, second
, tmp
->msgtyp
, third
);
3146 unlock_user_struct(tmp
, ptr
, 0);
3150 ret
= do_msgrcv(first
, ptr
, second
, fifth
, third
);
3159 raddr
= do_shmat(first
, ptr
, second
);
3160 if (is_error(raddr
))
3161 return get_errno(raddr
);
3162 if (put_user_ual(raddr
, third
))
3163 return -TARGET_EFAULT
;
3167 ret
= -TARGET_EINVAL
;
3172 ret
= do_shmdt(ptr
);
3176 /* IPC_* flag values are the same on all linux platforms */
3177 ret
= get_errno(shmget(first
, second
, third
));
3180 /* IPC_* and SHM_* command values are the same on all linux platforms */
3182 ret
= do_shmctl(first
, second
, third
);
3185 gemu_log("Unsupported ipc call: %d (version %d)\n", call
, version
);
3186 ret
= -TARGET_ENOSYS
;
3193 /* kernel structure types definitions */
3195 #define STRUCT(name, ...) STRUCT_ ## name,
3196 #define STRUCT_SPECIAL(name) STRUCT_ ## name,
3198 #include "syscall_types.h"
3201 #undef STRUCT_SPECIAL
3203 #define STRUCT(name, ...) static const argtype struct_ ## name ## _def[] = { __VA_ARGS__, TYPE_NULL };
3204 #define STRUCT_SPECIAL(name)
3205 #include "syscall_types.h"
3207 #undef STRUCT_SPECIAL
3209 typedef struct IOCTLEntry IOCTLEntry
;
3211 typedef abi_long
do_ioctl_fn(const IOCTLEntry
*ie
, uint8_t *buf_temp
,
3212 int fd
, abi_long cmd
, abi_long arg
);
3215 unsigned int target_cmd
;
3216 unsigned int host_cmd
;
3219 do_ioctl_fn
*do_ioctl
;
3220 const argtype arg_type
[5];
3223 #define IOC_R 0x0001
3224 #define IOC_W 0x0002
3225 #define IOC_RW (IOC_R | IOC_W)
3227 #define MAX_STRUCT_SIZE 4096
3229 #ifdef CONFIG_FIEMAP
3230 /* So fiemap access checks don't overflow on 32 bit systems.
3231 * This is very slightly smaller than the limit imposed by
3232 * the underlying kernel.
3234 #define FIEMAP_MAX_EXTENTS ((UINT_MAX - sizeof(struct fiemap)) \
3235 / sizeof(struct fiemap_extent))
3237 static abi_long
do_ioctl_fs_ioc_fiemap(const IOCTLEntry
*ie
, uint8_t *buf_temp
,
3238 int fd
, abi_long cmd
, abi_long arg
)
3240 /* The parameter for this ioctl is a struct fiemap followed
3241 * by an array of struct fiemap_extent whose size is set
3242 * in fiemap->fm_extent_count. The array is filled in by the
3245 int target_size_in
, target_size_out
;
3247 const argtype
*arg_type
= ie
->arg_type
;
3248 const argtype extent_arg_type
[] = { MK_STRUCT(STRUCT_fiemap_extent
) };
3251 int i
, extent_size
= thunk_type_size(extent_arg_type
, 0);
3255 assert(arg_type
[0] == TYPE_PTR
);
3256 assert(ie
->access
== IOC_RW
);
3258 target_size_in
= thunk_type_size(arg_type
, 0);
3259 argptr
= lock_user(VERIFY_READ
, arg
, target_size_in
, 1);
3261 return -TARGET_EFAULT
;
3263 thunk_convert(buf_temp
, argptr
, arg_type
, THUNK_HOST
);
3264 unlock_user(argptr
, arg
, 0);
3265 fm
= (struct fiemap
*)buf_temp
;
3266 if (fm
->fm_extent_count
> FIEMAP_MAX_EXTENTS
) {
3267 return -TARGET_EINVAL
;
3270 outbufsz
= sizeof (*fm
) +
3271 (sizeof(struct fiemap_extent
) * fm
->fm_extent_count
);
3273 if (outbufsz
> MAX_STRUCT_SIZE
) {
3274 /* We can't fit all the extents into the fixed size buffer.
3275 * Allocate one that is large enough and use it instead.
3277 fm
= malloc(outbufsz
);
3279 return -TARGET_ENOMEM
;
3281 memcpy(fm
, buf_temp
, sizeof(struct fiemap
));
3284 ret
= get_errno(ioctl(fd
, ie
->host_cmd
, fm
));
3285 if (!is_error(ret
)) {
3286 target_size_out
= target_size_in
;
3287 /* An extent_count of 0 means we were only counting the extents
3288 * so there are no structs to copy
3290 if (fm
->fm_extent_count
!= 0) {
3291 target_size_out
+= fm
->fm_mapped_extents
* extent_size
;
3293 argptr
= lock_user(VERIFY_WRITE
, arg
, target_size_out
, 0);
3295 ret
= -TARGET_EFAULT
;
3297 /* Convert the struct fiemap */
3298 thunk_convert(argptr
, fm
, arg_type
, THUNK_TARGET
);
3299 if (fm
->fm_extent_count
!= 0) {
3300 p
= argptr
+ target_size_in
;
3301 /* ...and then all the struct fiemap_extents */
3302 for (i
= 0; i
< fm
->fm_mapped_extents
; i
++) {
3303 thunk_convert(p
, &fm
->fm_extents
[i
], extent_arg_type
,
3308 unlock_user(argptr
, arg
, target_size_out
);
3318 static abi_long
do_ioctl_ifconf(const IOCTLEntry
*ie
, uint8_t *buf_temp
,
3319 int fd
, abi_long cmd
, abi_long arg
)
3321 const argtype
*arg_type
= ie
->arg_type
;
3325 struct ifconf
*host_ifconf
;
3327 const argtype ifreq_arg_type
[] = { MK_STRUCT(STRUCT_sockaddr_ifreq
) };
3328 int target_ifreq_size
;
3333 abi_long target_ifc_buf
;
3337 assert(arg_type
[0] == TYPE_PTR
);
3338 assert(ie
->access
== IOC_RW
);
3341 target_size
= thunk_type_size(arg_type
, 0);
3343 argptr
= lock_user(VERIFY_READ
, arg
, target_size
, 1);
3345 return -TARGET_EFAULT
;
3346 thunk_convert(buf_temp
, argptr
, arg_type
, THUNK_HOST
);
3347 unlock_user(argptr
, arg
, 0);
3349 host_ifconf
= (struct ifconf
*)(unsigned long)buf_temp
;
3350 target_ifc_len
= host_ifconf
->ifc_len
;
3351 target_ifc_buf
= (abi_long
)(unsigned long)host_ifconf
->ifc_buf
;
3353 target_ifreq_size
= thunk_type_size(ifreq_arg_type
, 0);
3354 nb_ifreq
= target_ifc_len
/ target_ifreq_size
;
3355 host_ifc_len
= nb_ifreq
* sizeof(struct ifreq
);
3357 outbufsz
= sizeof(*host_ifconf
) + host_ifc_len
;
3358 if (outbufsz
> MAX_STRUCT_SIZE
) {
3359 /* We can't fit all the extents into the fixed size buffer.
3360 * Allocate one that is large enough and use it instead.
3362 host_ifconf
= malloc(outbufsz
);
3364 return -TARGET_ENOMEM
;
3366 memcpy(host_ifconf
, buf_temp
, sizeof(*host_ifconf
));
3369 host_ifc_buf
= (char*)host_ifconf
+ sizeof(*host_ifconf
);
3371 host_ifconf
->ifc_len
= host_ifc_len
;
3372 host_ifconf
->ifc_buf
= host_ifc_buf
;
3374 ret
= get_errno(ioctl(fd
, ie
->host_cmd
, host_ifconf
));
3375 if (!is_error(ret
)) {
3376 /* convert host ifc_len to target ifc_len */
3378 nb_ifreq
= host_ifconf
->ifc_len
/ sizeof(struct ifreq
);
3379 target_ifc_len
= nb_ifreq
* target_ifreq_size
;
3380 host_ifconf
->ifc_len
= target_ifc_len
;
3382 /* restore target ifc_buf */
3384 host_ifconf
->ifc_buf
= (char *)(unsigned long)target_ifc_buf
;
3386 /* copy struct ifconf to target user */
3388 argptr
= lock_user(VERIFY_WRITE
, arg
, target_size
, 0);
3390 return -TARGET_EFAULT
;
3391 thunk_convert(argptr
, host_ifconf
, arg_type
, THUNK_TARGET
);
3392 unlock_user(argptr
, arg
, target_size
);
3394 /* copy ifreq[] to target user */
3396 argptr
= lock_user(VERIFY_WRITE
, target_ifc_buf
, target_ifc_len
, 0);
3397 for (i
= 0; i
< nb_ifreq
; i
++) {
3398 thunk_convert(argptr
+ i
* target_ifreq_size
,
3399 host_ifc_buf
+ i
* sizeof(struct ifreq
),
3400 ifreq_arg_type
, THUNK_TARGET
);
3402 unlock_user(argptr
, target_ifc_buf
, target_ifc_len
);
3412 static abi_long
do_ioctl_dm(const IOCTLEntry
*ie
, uint8_t *buf_temp
, int fd
,
3413 abi_long cmd
, abi_long arg
)
3416 struct dm_ioctl
*host_dm
;
3417 abi_long guest_data
;
3418 uint32_t guest_data_size
;
3420 const argtype
*arg_type
= ie
->arg_type
;
3422 void *big_buf
= NULL
;
3426 target_size
= thunk_type_size(arg_type
, 0);
3427 argptr
= lock_user(VERIFY_READ
, arg
, target_size
, 1);
3429 ret
= -TARGET_EFAULT
;
3432 thunk_convert(buf_temp
, argptr
, arg_type
, THUNK_HOST
);
3433 unlock_user(argptr
, arg
, 0);
3435 /* buf_temp is too small, so fetch things into a bigger buffer */
3436 big_buf
= g_malloc0(((struct dm_ioctl
*)buf_temp
)->data_size
* 2);
3437 memcpy(big_buf
, buf_temp
, target_size
);
3441 guest_data
= arg
+ host_dm
->data_start
;
3442 if ((guest_data
- arg
) < 0) {
3446 guest_data_size
= host_dm
->data_size
- host_dm
->data_start
;
3447 host_data
= (char*)host_dm
+ host_dm
->data_start
;
3449 argptr
= lock_user(VERIFY_READ
, guest_data
, guest_data_size
, 1);
3450 switch (ie
->host_cmd
) {
3452 case DM_LIST_DEVICES
:
3455 case DM_DEV_SUSPEND
:
3458 case DM_TABLE_STATUS
:
3459 case DM_TABLE_CLEAR
:
3461 case DM_LIST_VERSIONS
:
3465 case DM_DEV_SET_GEOMETRY
:
3466 /* data contains only strings */
3467 memcpy(host_data
, argptr
, guest_data_size
);
3470 memcpy(host_data
, argptr
, guest_data_size
);
3471 *(uint64_t*)host_data
= tswap64(*(uint64_t*)argptr
);
3475 void *gspec
= argptr
;
3476 void *cur_data
= host_data
;
3477 const argtype arg_type
[] = { MK_STRUCT(STRUCT_dm_target_spec
) };
3478 int spec_size
= thunk_type_size(arg_type
, 0);
3481 for (i
= 0; i
< host_dm
->target_count
; i
++) {
3482 struct dm_target_spec
*spec
= cur_data
;
3486 thunk_convert(spec
, gspec
, arg_type
, THUNK_HOST
);
3487 slen
= strlen((char*)gspec
+ spec_size
) + 1;
3489 spec
->next
= sizeof(*spec
) + slen
;
3490 strcpy((char*)&spec
[1], gspec
+ spec_size
);
3492 cur_data
+= spec
->next
;
3497 ret
= -TARGET_EINVAL
;
3500 unlock_user(argptr
, guest_data
, 0);
3502 ret
= get_errno(ioctl(fd
, ie
->host_cmd
, buf_temp
));
3503 if (!is_error(ret
)) {
3504 guest_data
= arg
+ host_dm
->data_start
;
3505 guest_data_size
= host_dm
->data_size
- host_dm
->data_start
;
3506 argptr
= lock_user(VERIFY_WRITE
, guest_data
, guest_data_size
, 0);
3507 switch (ie
->host_cmd
) {
3512 case DM_DEV_SUSPEND
:
3515 case DM_TABLE_CLEAR
:
3517 case DM_DEV_SET_GEOMETRY
:
3518 /* no return data */
3520 case DM_LIST_DEVICES
:
3522 struct dm_name_list
*nl
= (void*)host_dm
+ host_dm
->data_start
;
3523 uint32_t remaining_data
= guest_data_size
;
3524 void *cur_data
= argptr
;
3525 const argtype arg_type
[] = { MK_STRUCT(STRUCT_dm_name_list
) };
3526 int nl_size
= 12; /* can't use thunk_size due to alignment */
3529 uint32_t next
= nl
->next
;
3531 nl
->next
= nl_size
+ (strlen(nl
->name
) + 1);
3533 if (remaining_data
< nl
->next
) {
3534 host_dm
->flags
|= DM_BUFFER_FULL_FLAG
;
3537 thunk_convert(cur_data
, nl
, arg_type
, THUNK_TARGET
);
3538 strcpy(cur_data
+ nl_size
, nl
->name
);
3539 cur_data
+= nl
->next
;
3540 remaining_data
-= nl
->next
;
3544 nl
= (void*)nl
+ next
;
3549 case DM_TABLE_STATUS
:
3551 struct dm_target_spec
*spec
= (void*)host_dm
+ host_dm
->data_start
;
3552 void *cur_data
= argptr
;
3553 const argtype arg_type
[] = { MK_STRUCT(STRUCT_dm_target_spec
) };
3554 int spec_size
= thunk_type_size(arg_type
, 0);
3557 for (i
= 0; i
< host_dm
->target_count
; i
++) {
3558 uint32_t next
= spec
->next
;
3559 int slen
= strlen((char*)&spec
[1]) + 1;
3560 spec
->next
= (cur_data
- argptr
) + spec_size
+ slen
;
3561 if (guest_data_size
< spec
->next
) {
3562 host_dm
->flags
|= DM_BUFFER_FULL_FLAG
;
3565 thunk_convert(cur_data
, spec
, arg_type
, THUNK_TARGET
);
3566 strcpy(cur_data
+ spec_size
, (char*)&spec
[1]);
3567 cur_data
= argptr
+ spec
->next
;
3568 spec
= (void*)host_dm
+ host_dm
->data_start
+ next
;
3574 void *hdata
= (void*)host_dm
+ host_dm
->data_start
;
3575 int count
= *(uint32_t*)hdata
;
3576 uint64_t *hdev
= hdata
+ 8;
3577 uint64_t *gdev
= argptr
+ 8;
3580 *(uint32_t*)argptr
= tswap32(count
);
3581 for (i
= 0; i
< count
; i
++) {
3582 *gdev
= tswap64(*hdev
);
3588 case DM_LIST_VERSIONS
:
3590 struct dm_target_versions
*vers
= (void*)host_dm
+ host_dm
->data_start
;
3591 uint32_t remaining_data
= guest_data_size
;
3592 void *cur_data
= argptr
;
3593 const argtype arg_type
[] = { MK_STRUCT(STRUCT_dm_target_versions
) };
3594 int vers_size
= thunk_type_size(arg_type
, 0);
3597 uint32_t next
= vers
->next
;
3599 vers
->next
= vers_size
+ (strlen(vers
->name
) + 1);
3601 if (remaining_data
< vers
->next
) {
3602 host_dm
->flags
|= DM_BUFFER_FULL_FLAG
;
3605 thunk_convert(cur_data
, vers
, arg_type
, THUNK_TARGET
);
3606 strcpy(cur_data
+ vers_size
, vers
->name
);
3607 cur_data
+= vers
->next
;
3608 remaining_data
-= vers
->next
;
3612 vers
= (void*)vers
+ next
;
3617 ret
= -TARGET_EINVAL
;
3620 unlock_user(argptr
, guest_data
, guest_data_size
);
3622 argptr
= lock_user(VERIFY_WRITE
, arg
, target_size
, 0);
3624 ret
= -TARGET_EFAULT
;
3627 thunk_convert(argptr
, buf_temp
, arg_type
, THUNK_TARGET
);
3628 unlock_user(argptr
, arg
, target_size
);
3637 static IOCTLEntry ioctl_entries
[] = {
3638 #define IOCTL(cmd, access, ...) \
3639 { TARGET_ ## cmd, cmd, #cmd, access, 0, { __VA_ARGS__ } },
3640 #define IOCTL_SPECIAL(cmd, access, dofn, ...) \
3641 { TARGET_ ## cmd, cmd, #cmd, access, dofn, { __VA_ARGS__ } },
3646 /* ??? Implement proper locking for ioctls. */
3647 /* do_ioctl() Must return target values and target errnos. */
3648 static abi_long
do_ioctl(int fd
, abi_long cmd
, abi_long arg
)
3650 const IOCTLEntry
*ie
;
3651 const argtype
*arg_type
;
3653 uint8_t buf_temp
[MAX_STRUCT_SIZE
];
3659 if (ie
->target_cmd
== 0) {
3660 gemu_log("Unsupported ioctl: cmd=0x%04lx\n", (long)cmd
);
3661 return -TARGET_ENOSYS
;
3663 if (ie
->target_cmd
== cmd
)
3667 arg_type
= ie
->arg_type
;
3669 gemu_log("ioctl: cmd=0x%04lx (%s)\n", (long)cmd
, ie
->name
);
3672 return ie
->do_ioctl(ie
, buf_temp
, fd
, cmd
, arg
);
3675 switch(arg_type
[0]) {
3678 ret
= get_errno(ioctl(fd
, ie
->host_cmd
));
3683 ret
= get_errno(ioctl(fd
, ie
->host_cmd
, arg
));
3687 target_size
= thunk_type_size(arg_type
, 0);
3688 switch(ie
->access
) {
3690 ret
= get_errno(ioctl(fd
, ie
->host_cmd
, buf_temp
));
3691 if (!is_error(ret
)) {
3692 argptr
= lock_user(VERIFY_WRITE
, arg
, target_size
, 0);
3694 return -TARGET_EFAULT
;
3695 thunk_convert(argptr
, buf_temp
, arg_type
, THUNK_TARGET
);
3696 unlock_user(argptr
, arg
, target_size
);
3700 argptr
= lock_user(VERIFY_READ
, arg
, target_size
, 1);
3702 return -TARGET_EFAULT
;
3703 thunk_convert(buf_temp
, argptr
, arg_type
, THUNK_HOST
);
3704 unlock_user(argptr
, arg
, 0);
3705 ret
= get_errno(ioctl(fd
, ie
->host_cmd
, buf_temp
));
3709 argptr
= lock_user(VERIFY_READ
, arg
, target_size
, 1);
3711 return -TARGET_EFAULT
;
3712 thunk_convert(buf_temp
, argptr
, arg_type
, THUNK_HOST
);
3713 unlock_user(argptr
, arg
, 0);
3714 ret
= get_errno(ioctl(fd
, ie
->host_cmd
, buf_temp
));
3715 if (!is_error(ret
)) {
3716 argptr
= lock_user(VERIFY_WRITE
, arg
, target_size
, 0);
3718 return -TARGET_EFAULT
;
3719 thunk_convert(argptr
, buf_temp
, arg_type
, THUNK_TARGET
);
3720 unlock_user(argptr
, arg
, target_size
);
3726 gemu_log("Unsupported ioctl type: cmd=0x%04lx type=%d\n",
3727 (long)cmd
, arg_type
[0]);
3728 ret
= -TARGET_ENOSYS
;
3734 static const bitmask_transtbl iflag_tbl
[] = {
3735 { TARGET_IGNBRK
, TARGET_IGNBRK
, IGNBRK
, IGNBRK
},
3736 { TARGET_BRKINT
, TARGET_BRKINT
, BRKINT
, BRKINT
},
3737 { TARGET_IGNPAR
, TARGET_IGNPAR
, IGNPAR
, IGNPAR
},
3738 { TARGET_PARMRK
, TARGET_PARMRK
, PARMRK
, PARMRK
},
3739 { TARGET_INPCK
, TARGET_INPCK
, INPCK
, INPCK
},
3740 { TARGET_ISTRIP
, TARGET_ISTRIP
, ISTRIP
, ISTRIP
},
3741 { TARGET_INLCR
, TARGET_INLCR
, INLCR
, INLCR
},
3742 { TARGET_IGNCR
, TARGET_IGNCR
, IGNCR
, IGNCR
},
3743 { TARGET_ICRNL
, TARGET_ICRNL
, ICRNL
, ICRNL
},
3744 { TARGET_IUCLC
, TARGET_IUCLC
, IUCLC
, IUCLC
},
3745 { TARGET_IXON
, TARGET_IXON
, IXON
, IXON
},
3746 { TARGET_IXANY
, TARGET_IXANY
, IXANY
, IXANY
},
3747 { TARGET_IXOFF
, TARGET_IXOFF
, IXOFF
, IXOFF
},
3748 { TARGET_IMAXBEL
, TARGET_IMAXBEL
, IMAXBEL
, IMAXBEL
},
3752 static const bitmask_transtbl oflag_tbl
[] = {
3753 { TARGET_OPOST
, TARGET_OPOST
, OPOST
, OPOST
},
3754 { TARGET_OLCUC
, TARGET_OLCUC
, OLCUC
, OLCUC
},
3755 { TARGET_ONLCR
, TARGET_ONLCR
, ONLCR
, ONLCR
},
3756 { TARGET_OCRNL
, TARGET_OCRNL
, OCRNL
, OCRNL
},
3757 { TARGET_ONOCR
, TARGET_ONOCR
, ONOCR
, ONOCR
},
3758 { TARGET_ONLRET
, TARGET_ONLRET
, ONLRET
, ONLRET
},
3759 { TARGET_OFILL
, TARGET_OFILL
, OFILL
, OFILL
},
3760 { TARGET_OFDEL
, TARGET_OFDEL
, OFDEL
, OFDEL
},
3761 { TARGET_NLDLY
, TARGET_NL0
, NLDLY
, NL0
},
3762 { TARGET_NLDLY
, TARGET_NL1
, NLDLY
, NL1
},
3763 { TARGET_CRDLY
, TARGET_CR0
, CRDLY
, CR0
},
3764 { TARGET_CRDLY
, TARGET_CR1
, CRDLY
, CR1
},
3765 { TARGET_CRDLY
, TARGET_CR2
, CRDLY
, CR2
},
3766 { TARGET_CRDLY
, TARGET_CR3
, CRDLY
, CR3
},
3767 { TARGET_TABDLY
, TARGET_TAB0
, TABDLY
, TAB0
},
3768 { TARGET_TABDLY
, TARGET_TAB1
, TABDLY
, TAB1
},
3769 { TARGET_TABDLY
, TARGET_TAB2
, TABDLY
, TAB2
},
3770 { TARGET_TABDLY
, TARGET_TAB3
, TABDLY
, TAB3
},
3771 { TARGET_BSDLY
, TARGET_BS0
, BSDLY
, BS0
},
3772 { TARGET_BSDLY
, TARGET_BS1
, BSDLY
, BS1
},
3773 { TARGET_VTDLY
, TARGET_VT0
, VTDLY
, VT0
},
3774 { TARGET_VTDLY
, TARGET_VT1
, VTDLY
, VT1
},
3775 { TARGET_FFDLY
, TARGET_FF0
, FFDLY
, FF0
},
3776 { TARGET_FFDLY
, TARGET_FF1
, FFDLY
, FF1
},
3780 static const bitmask_transtbl cflag_tbl
[] = {
3781 { TARGET_CBAUD
, TARGET_B0
, CBAUD
, B0
},
3782 { TARGET_CBAUD
, TARGET_B50
, CBAUD
, B50
},
3783 { TARGET_CBAUD
, TARGET_B75
, CBAUD
, B75
},
3784 { TARGET_CBAUD
, TARGET_B110
, CBAUD
, B110
},
3785 { TARGET_CBAUD
, TARGET_B134
, CBAUD
, B134
},
3786 { TARGET_CBAUD
, TARGET_B150
, CBAUD
, B150
},
3787 { TARGET_CBAUD
, TARGET_B200
, CBAUD
, B200
},
3788 { TARGET_CBAUD
, TARGET_B300
, CBAUD
, B300
},
3789 { TARGET_CBAUD
, TARGET_B600
, CBAUD
, B600
},
3790 { TARGET_CBAUD
, TARGET_B1200
, CBAUD
, B1200
},
3791 { TARGET_CBAUD
, TARGET_B1800
, CBAUD
, B1800
},
3792 { TARGET_CBAUD
, TARGET_B2400
, CBAUD
, B2400
},
3793 { TARGET_CBAUD
, TARGET_B4800
, CBAUD
, B4800
},
3794 { TARGET_CBAUD
, TARGET_B9600
, CBAUD
, B9600
},
3795 { TARGET_CBAUD
, TARGET_B19200
, CBAUD
, B19200
},
3796 { TARGET_CBAUD
, TARGET_B38400
, CBAUD
, B38400
},
3797 { TARGET_CBAUD
, TARGET_B57600
, CBAUD
, B57600
},
3798 { TARGET_CBAUD
, TARGET_B115200
, CBAUD
, B115200
},
3799 { TARGET_CBAUD
, TARGET_B230400
, CBAUD
, B230400
},
3800 { TARGET_CBAUD
, TARGET_B460800
, CBAUD
, B460800
},
3801 { TARGET_CSIZE
, TARGET_CS5
, CSIZE
, CS5
},
3802 { TARGET_CSIZE
, TARGET_CS6
, CSIZE
, CS6
},
3803 { TARGET_CSIZE
, TARGET_CS7
, CSIZE
, CS7
},
3804 { TARGET_CSIZE
, TARGET_CS8
, CSIZE
, CS8
},
3805 { TARGET_CSTOPB
, TARGET_CSTOPB
, CSTOPB
, CSTOPB
},
3806 { TARGET_CREAD
, TARGET_CREAD
, CREAD
, CREAD
},
3807 { TARGET_PARENB
, TARGET_PARENB
, PARENB
, PARENB
},
3808 { TARGET_PARODD
, TARGET_PARODD
, PARODD
, PARODD
},
3809 { TARGET_HUPCL
, TARGET_HUPCL
, HUPCL
, HUPCL
},
3810 { TARGET_CLOCAL
, TARGET_CLOCAL
, CLOCAL
, CLOCAL
},
3811 { TARGET_CRTSCTS
, TARGET_CRTSCTS
, CRTSCTS
, CRTSCTS
},
3815 static const bitmask_transtbl lflag_tbl
[] = {
3816 { TARGET_ISIG
, TARGET_ISIG
, ISIG
, ISIG
},
3817 { TARGET_ICANON
, TARGET_ICANON
, ICANON
, ICANON
},
3818 { TARGET_XCASE
, TARGET_XCASE
, XCASE
, XCASE
},
3819 { TARGET_ECHO
, TARGET_ECHO
, ECHO
, ECHO
},
3820 { TARGET_ECHOE
, TARGET_ECHOE
, ECHOE
, ECHOE
},
3821 { TARGET_ECHOK
, TARGET_ECHOK
, ECHOK
, ECHOK
},
3822 { TARGET_ECHONL
, TARGET_ECHONL
, ECHONL
, ECHONL
},
3823 { TARGET_NOFLSH
, TARGET_NOFLSH
, NOFLSH
, NOFLSH
},
3824 { TARGET_TOSTOP
, TARGET_TOSTOP
, TOSTOP
, TOSTOP
},
3825 { TARGET_ECHOCTL
, TARGET_ECHOCTL
, ECHOCTL
, ECHOCTL
},
3826 { TARGET_ECHOPRT
, TARGET_ECHOPRT
, ECHOPRT
, ECHOPRT
},
3827 { TARGET_ECHOKE
, TARGET_ECHOKE
, ECHOKE
, ECHOKE
},
3828 { TARGET_FLUSHO
, TARGET_FLUSHO
, FLUSHO
, FLUSHO
},
3829 { TARGET_PENDIN
, TARGET_PENDIN
, PENDIN
, PENDIN
},
3830 { TARGET_IEXTEN
, TARGET_IEXTEN
, IEXTEN
, IEXTEN
},
3834 static void target_to_host_termios (void *dst
, const void *src
)
3836 struct host_termios
*host
= dst
;
3837 const struct target_termios
*target
= src
;
3840 target_to_host_bitmask(tswap32(target
->c_iflag
), iflag_tbl
);
3842 target_to_host_bitmask(tswap32(target
->c_oflag
), oflag_tbl
);
3844 target_to_host_bitmask(tswap32(target
->c_cflag
), cflag_tbl
);
3846 target_to_host_bitmask(tswap32(target
->c_lflag
), lflag_tbl
);
3847 host
->c_line
= target
->c_line
;
3849 memset(host
->c_cc
, 0, sizeof(host
->c_cc
));
3850 host
->c_cc
[VINTR
] = target
->c_cc
[TARGET_VINTR
];
3851 host
->c_cc
[VQUIT
] = target
->c_cc
[TARGET_VQUIT
];
3852 host
->c_cc
[VERASE
] = target
->c_cc
[TARGET_VERASE
];
3853 host
->c_cc
[VKILL
] = target
->c_cc
[TARGET_VKILL
];
3854 host
->c_cc
[VEOF
] = target
->c_cc
[TARGET_VEOF
];
3855 host
->c_cc
[VTIME
] = target
->c_cc
[TARGET_VTIME
];
3856 host
->c_cc
[VMIN
] = target
->c_cc
[TARGET_VMIN
];
3857 host
->c_cc
[VSWTC
] = target
->c_cc
[TARGET_VSWTC
];
3858 host
->c_cc
[VSTART
] = target
->c_cc
[TARGET_VSTART
];
3859 host
->c_cc
[VSTOP
] = target
->c_cc
[TARGET_VSTOP
];
3860 host
->c_cc
[VSUSP
] = target
->c_cc
[TARGET_VSUSP
];
3861 host
->c_cc
[VEOL
] = target
->c_cc
[TARGET_VEOL
];
3862 host
->c_cc
[VREPRINT
] = target
->c_cc
[TARGET_VREPRINT
];
3863 host
->c_cc
[VDISCARD
] = target
->c_cc
[TARGET_VDISCARD
];
3864 host
->c_cc
[VWERASE
] = target
->c_cc
[TARGET_VWERASE
];
3865 host
->c_cc
[VLNEXT
] = target
->c_cc
[TARGET_VLNEXT
];
3866 host
->c_cc
[VEOL2
] = target
->c_cc
[TARGET_VEOL2
];
3869 static void host_to_target_termios (void *dst
, const void *src
)
3871 struct target_termios
*target
= dst
;
3872 const struct host_termios
*host
= src
;
3875 tswap32(host_to_target_bitmask(host
->c_iflag
, iflag_tbl
));
3877 tswap32(host_to_target_bitmask(host
->c_oflag
, oflag_tbl
));
3879 tswap32(host_to_target_bitmask(host
->c_cflag
, cflag_tbl
));
3881 tswap32(host_to_target_bitmask(host
->c_lflag
, lflag_tbl
));
3882 target
->c_line
= host
->c_line
;
3884 memset(target
->c_cc
, 0, sizeof(target
->c_cc
));
3885 target
->c_cc
[TARGET_VINTR
] = host
->c_cc
[VINTR
];
3886 target
->c_cc
[TARGET_VQUIT
] = host
->c_cc
[VQUIT
];
3887 target
->c_cc
[TARGET_VERASE
] = host
->c_cc
[VERASE
];
3888 target
->c_cc
[TARGET_VKILL
] = host
->c_cc
[VKILL
];
3889 target
->c_cc
[TARGET_VEOF
] = host
->c_cc
[VEOF
];
3890 target
->c_cc
[TARGET_VTIME
] = host
->c_cc
[VTIME
];
3891 target
->c_cc
[TARGET_VMIN
] = host
->c_cc
[VMIN
];
3892 target
->c_cc
[TARGET_VSWTC
] = host
->c_cc
[VSWTC
];
3893 target
->c_cc
[TARGET_VSTART
] = host
->c_cc
[VSTART
];
3894 target
->c_cc
[TARGET_VSTOP
] = host
->c_cc
[VSTOP
];
3895 target
->c_cc
[TARGET_VSUSP
] = host
->c_cc
[VSUSP
];
3896 target
->c_cc
[TARGET_VEOL
] = host
->c_cc
[VEOL
];
3897 target
->c_cc
[TARGET_VREPRINT
] = host
->c_cc
[VREPRINT
];
3898 target
->c_cc
[TARGET_VDISCARD
] = host
->c_cc
[VDISCARD
];
3899 target
->c_cc
[TARGET_VWERASE
] = host
->c_cc
[VWERASE
];
3900 target
->c_cc
[TARGET_VLNEXT
] = host
->c_cc
[VLNEXT
];
3901 target
->c_cc
[TARGET_VEOL2
] = host
->c_cc
[VEOL2
];
3904 static const StructEntry struct_termios_def
= {
3905 .convert
= { host_to_target_termios
, target_to_host_termios
},
3906 .size
= { sizeof(struct target_termios
), sizeof(struct host_termios
) },
3907 .align
= { __alignof__(struct target_termios
), __alignof__(struct host_termios
) },
3910 static bitmask_transtbl mmap_flags_tbl
[] = {
3911 { TARGET_MAP_SHARED
, TARGET_MAP_SHARED
, MAP_SHARED
, MAP_SHARED
},
3912 { TARGET_MAP_PRIVATE
, TARGET_MAP_PRIVATE
, MAP_PRIVATE
, MAP_PRIVATE
},
3913 { TARGET_MAP_FIXED
, TARGET_MAP_FIXED
, MAP_FIXED
, MAP_FIXED
},
3914 { TARGET_MAP_ANONYMOUS
, TARGET_MAP_ANONYMOUS
, MAP_ANONYMOUS
, MAP_ANONYMOUS
},
3915 { TARGET_MAP_GROWSDOWN
, TARGET_MAP_GROWSDOWN
, MAP_GROWSDOWN
, MAP_GROWSDOWN
},
3916 { TARGET_MAP_DENYWRITE
, TARGET_MAP_DENYWRITE
, MAP_DENYWRITE
, MAP_DENYWRITE
},
3917 { TARGET_MAP_EXECUTABLE
, TARGET_MAP_EXECUTABLE
, MAP_EXECUTABLE
, MAP_EXECUTABLE
},
3918 { TARGET_MAP_LOCKED
, TARGET_MAP_LOCKED
, MAP_LOCKED
, MAP_LOCKED
},
3922 #if defined(TARGET_I386)
3924 /* NOTE: there is really one LDT for all the threads */
3925 static uint8_t *ldt_table
;
3927 static abi_long
read_ldt(abi_ulong ptr
, unsigned long bytecount
)
3934 size
= TARGET_LDT_ENTRIES
* TARGET_LDT_ENTRY_SIZE
;
3935 if (size
> bytecount
)
3937 p
= lock_user(VERIFY_WRITE
, ptr
, size
, 0);
3939 return -TARGET_EFAULT
;
3940 /* ??? Should this by byteswapped? */
3941 memcpy(p
, ldt_table
, size
);
3942 unlock_user(p
, ptr
, size
);
3946 /* XXX: add locking support */
3947 static abi_long
write_ldt(CPUX86State
*env
,
3948 abi_ulong ptr
, unsigned long bytecount
, int oldmode
)
3950 struct target_modify_ldt_ldt_s ldt_info
;
3951 struct target_modify_ldt_ldt_s
*target_ldt_info
;
3952 int seg_32bit
, contents
, read_exec_only
, limit_in_pages
;
3953 int seg_not_present
, useable
, lm
;
3954 uint32_t *lp
, entry_1
, entry_2
;
3956 if (bytecount
!= sizeof(ldt_info
))
3957 return -TARGET_EINVAL
;
3958 if (!lock_user_struct(VERIFY_READ
, target_ldt_info
, ptr
, 1))
3959 return -TARGET_EFAULT
;
3960 ldt_info
.entry_number
= tswap32(target_ldt_info
->entry_number
);
3961 ldt_info
.base_addr
= tswapal(target_ldt_info
->base_addr
);
3962 ldt_info
.limit
= tswap32(target_ldt_info
->limit
);
3963 ldt_info
.flags
= tswap32(target_ldt_info
->flags
);
3964 unlock_user_struct(target_ldt_info
, ptr
, 0);
3966 if (ldt_info
.entry_number
>= TARGET_LDT_ENTRIES
)
3967 return -TARGET_EINVAL
;
3968 seg_32bit
= ldt_info
.flags
& 1;
3969 contents
= (ldt_info
.flags
>> 1) & 3;
3970 read_exec_only
= (ldt_info
.flags
>> 3) & 1;
3971 limit_in_pages
= (ldt_info
.flags
>> 4) & 1;
3972 seg_not_present
= (ldt_info
.flags
>> 5) & 1;
3973 useable
= (ldt_info
.flags
>> 6) & 1;
3977 lm
= (ldt_info
.flags
>> 7) & 1;
3979 if (contents
== 3) {
3981 return -TARGET_EINVAL
;
3982 if (seg_not_present
== 0)
3983 return -TARGET_EINVAL
;
3985 /* allocate the LDT */
3987 env
->ldt
.base
= target_mmap(0,
3988 TARGET_LDT_ENTRIES
* TARGET_LDT_ENTRY_SIZE
,
3989 PROT_READ
|PROT_WRITE
,
3990 MAP_ANONYMOUS
|MAP_PRIVATE
, -1, 0);
3991 if (env
->ldt
.base
== -1)
3992 return -TARGET_ENOMEM
;
3993 memset(g2h(env
->ldt
.base
), 0,
3994 TARGET_LDT_ENTRIES
* TARGET_LDT_ENTRY_SIZE
);
3995 env
->ldt
.limit
= 0xffff;
3996 ldt_table
= g2h(env
->ldt
.base
);
3999 /* NOTE: same code as Linux kernel */
4000 /* Allow LDTs to be cleared by the user. */
4001 if (ldt_info
.base_addr
== 0 && ldt_info
.limit
== 0) {
4004 read_exec_only
== 1 &&
4006 limit_in_pages
== 0 &&
4007 seg_not_present
== 1 &&
4015 entry_1
= ((ldt_info
.base_addr
& 0x0000ffff) << 16) |
4016 (ldt_info
.limit
& 0x0ffff);
4017 entry_2
= (ldt_info
.base_addr
& 0xff000000) |
4018 ((ldt_info
.base_addr
& 0x00ff0000) >> 16) |
4019 (ldt_info
.limit
& 0xf0000) |
4020 ((read_exec_only
^ 1) << 9) |
4022 ((seg_not_present
^ 1) << 15) |
4024 (limit_in_pages
<< 23) |
4028 entry_2
|= (useable
<< 20);
4030 /* Install the new entry ... */
4032 lp
= (uint32_t *)(ldt_table
+ (ldt_info
.entry_number
<< 3));
4033 lp
[0] = tswap32(entry_1
);
4034 lp
[1] = tswap32(entry_2
);
4038 /* specific and weird i386 syscalls */
4039 static abi_long
do_modify_ldt(CPUX86State
*env
, int func
, abi_ulong ptr
,
4040 unsigned long bytecount
)
4046 ret
= read_ldt(ptr
, bytecount
);
4049 ret
= write_ldt(env
, ptr
, bytecount
, 1);
4052 ret
= write_ldt(env
, ptr
, bytecount
, 0);
4055 ret
= -TARGET_ENOSYS
;
4061 #if defined(TARGET_I386) && defined(TARGET_ABI32)
4062 static abi_long
do_set_thread_area(CPUX86State
*env
, abi_ulong ptr
)
4064 uint64_t *gdt_table
= g2h(env
->gdt
.base
);
4065 struct target_modify_ldt_ldt_s ldt_info
;
4066 struct target_modify_ldt_ldt_s
*target_ldt_info
;
4067 int seg_32bit
, contents
, read_exec_only
, limit_in_pages
;
4068 int seg_not_present
, useable
, lm
;
4069 uint32_t *lp
, entry_1
, entry_2
;
4072 lock_user_struct(VERIFY_WRITE
, target_ldt_info
, ptr
, 1);
4073 if (!target_ldt_info
)
4074 return -TARGET_EFAULT
;
4075 ldt_info
.entry_number
= tswap32(target_ldt_info
->entry_number
);
4076 ldt_info
.base_addr
= tswapal(target_ldt_info
->base_addr
);
4077 ldt_info
.limit
= tswap32(target_ldt_info
->limit
);
4078 ldt_info
.flags
= tswap32(target_ldt_info
->flags
);
4079 if (ldt_info
.entry_number
== -1) {
4080 for (i
=TARGET_GDT_ENTRY_TLS_MIN
; i
<=TARGET_GDT_ENTRY_TLS_MAX
; i
++) {
4081 if (gdt_table
[i
] == 0) {
4082 ldt_info
.entry_number
= i
;
4083 target_ldt_info
->entry_number
= tswap32(i
);
4088 unlock_user_struct(target_ldt_info
, ptr
, 1);
4090 if (ldt_info
.entry_number
< TARGET_GDT_ENTRY_TLS_MIN
||
4091 ldt_info
.entry_number
> TARGET_GDT_ENTRY_TLS_MAX
)
4092 return -TARGET_EINVAL
;
4093 seg_32bit
= ldt_info
.flags
& 1;
4094 contents
= (ldt_info
.flags
>> 1) & 3;
4095 read_exec_only
= (ldt_info
.flags
>> 3) & 1;
4096 limit_in_pages
= (ldt_info
.flags
>> 4) & 1;
4097 seg_not_present
= (ldt_info
.flags
>> 5) & 1;
4098 useable
= (ldt_info
.flags
>> 6) & 1;
4102 lm
= (ldt_info
.flags
>> 7) & 1;
4105 if (contents
== 3) {
4106 if (seg_not_present
== 0)
4107 return -TARGET_EINVAL
;
4110 /* NOTE: same code as Linux kernel */
4111 /* Allow LDTs to be cleared by the user. */
4112 if (ldt_info
.base_addr
== 0 && ldt_info
.limit
== 0) {
4113 if ((contents
== 0 &&
4114 read_exec_only
== 1 &&
4116 limit_in_pages
== 0 &&
4117 seg_not_present
== 1 &&
4125 entry_1
= ((ldt_info
.base_addr
& 0x0000ffff) << 16) |
4126 (ldt_info
.limit
& 0x0ffff);
4127 entry_2
= (ldt_info
.base_addr
& 0xff000000) |
4128 ((ldt_info
.base_addr
& 0x00ff0000) >> 16) |
4129 (ldt_info
.limit
& 0xf0000) |
4130 ((read_exec_only
^ 1) << 9) |
4132 ((seg_not_present
^ 1) << 15) |
4134 (limit_in_pages
<< 23) |
4139 /* Install the new entry ... */
4141 lp
= (uint32_t *)(gdt_table
+ ldt_info
.entry_number
);
4142 lp
[0] = tswap32(entry_1
);
4143 lp
[1] = tswap32(entry_2
);
4147 static abi_long
do_get_thread_area(CPUX86State
*env
, abi_ulong ptr
)
4149 struct target_modify_ldt_ldt_s
*target_ldt_info
;
4150 uint64_t *gdt_table
= g2h(env
->gdt
.base
);
4151 uint32_t base_addr
, limit
, flags
;
4152 int seg_32bit
, contents
, read_exec_only
, limit_in_pages
, idx
;
4153 int seg_not_present
, useable
, lm
;
4154 uint32_t *lp
, entry_1
, entry_2
;
4156 lock_user_struct(VERIFY_WRITE
, target_ldt_info
, ptr
, 1);
4157 if (!target_ldt_info
)
4158 return -TARGET_EFAULT
;
4159 idx
= tswap32(target_ldt_info
->entry_number
);
4160 if (idx
< TARGET_GDT_ENTRY_TLS_MIN
||
4161 idx
> TARGET_GDT_ENTRY_TLS_MAX
) {
4162 unlock_user_struct(target_ldt_info
, ptr
, 1);
4163 return -TARGET_EINVAL
;
4165 lp
= (uint32_t *)(gdt_table
+ idx
);
4166 entry_1
= tswap32(lp
[0]);
4167 entry_2
= tswap32(lp
[1]);
4169 read_exec_only
= ((entry_2
>> 9) & 1) ^ 1;
4170 contents
= (entry_2
>> 10) & 3;
4171 seg_not_present
= ((entry_2
>> 15) & 1) ^ 1;
4172 seg_32bit
= (entry_2
>> 22) & 1;
4173 limit_in_pages
= (entry_2
>> 23) & 1;
4174 useable
= (entry_2
>> 20) & 1;
4178 lm
= (entry_2
>> 21) & 1;
4180 flags
= (seg_32bit
<< 0) | (contents
<< 1) |
4181 (read_exec_only
<< 3) | (limit_in_pages
<< 4) |
4182 (seg_not_present
<< 5) | (useable
<< 6) | (lm
<< 7);
4183 limit
= (entry_1
& 0xffff) | (entry_2
& 0xf0000);
4184 base_addr
= (entry_1
>> 16) |
4185 (entry_2
& 0xff000000) |
4186 ((entry_2
& 0xff) << 16);
4187 target_ldt_info
->base_addr
= tswapal(base_addr
);
4188 target_ldt_info
->limit
= tswap32(limit
);
4189 target_ldt_info
->flags
= tswap32(flags
);
4190 unlock_user_struct(target_ldt_info
, ptr
, 1);
4193 #endif /* TARGET_I386 && TARGET_ABI32 */
4195 #ifndef TARGET_ABI32
4196 static abi_long
do_arch_prctl(CPUX86State
*env
, int code
, abi_ulong addr
)
4203 case TARGET_ARCH_SET_GS
:
4204 case TARGET_ARCH_SET_FS
:
4205 if (code
== TARGET_ARCH_SET_GS
)
4209 cpu_x86_load_seg(env
, idx
, 0);
4210 env
->segs
[idx
].base
= addr
;
4212 case TARGET_ARCH_GET_GS
:
4213 case TARGET_ARCH_GET_FS
:
4214 if (code
== TARGET_ARCH_GET_GS
)
4218 val
= env
->segs
[idx
].base
;
4219 if (put_user(val
, addr
, abi_ulong
))
4220 ret
= -TARGET_EFAULT
;
4223 ret
= -TARGET_EINVAL
;
4230 #endif /* defined(TARGET_I386) */
4232 #define NEW_STACK_SIZE 0x40000
4234 #if defined(CONFIG_USE_NPTL)
4236 static pthread_mutex_t clone_lock
= PTHREAD_MUTEX_INITIALIZER
;
4239 pthread_mutex_t mutex
;
4240 pthread_cond_t cond
;
4243 abi_ulong child_tidptr
;
4244 abi_ulong parent_tidptr
;
4248 static void *clone_func(void *arg
)
4250 new_thread_info
*info
= arg
;
4256 ts
= (TaskState
*)thread_env
->opaque
;
4257 info
->tid
= gettid();
4258 env
->host_tid
= info
->tid
;
4260 if (info
->child_tidptr
)
4261 put_user_u32(info
->tid
, info
->child_tidptr
);
4262 if (info
->parent_tidptr
)
4263 put_user_u32(info
->tid
, info
->parent_tidptr
);
4264 /* Enable signals. */
4265 sigprocmask(SIG_SETMASK
, &info
->sigmask
, NULL
);
4266 /* Signal to the parent that we're ready. */
4267 pthread_mutex_lock(&info
->mutex
);
4268 pthread_cond_broadcast(&info
->cond
);
4269 pthread_mutex_unlock(&info
->mutex
);
4270 /* Wait until the parent has finshed initializing the tls state. */
4271 pthread_mutex_lock(&clone_lock
);
4272 pthread_mutex_unlock(&clone_lock
);
4279 static int clone_func(void *arg
)
4281 CPUArchState
*env
= arg
;
4288 /* do_fork() Must return host values and target errnos (unlike most
4289 do_*() functions). */
4290 static int do_fork(CPUArchState
*env
, unsigned int flags
, abi_ulong newsp
,
4291 abi_ulong parent_tidptr
, target_ulong newtls
,
4292 abi_ulong child_tidptr
)
4296 CPUArchState
*new_env
;
4297 #if defined(CONFIG_USE_NPTL)
4298 unsigned int nptl_flags
;
4304 /* Emulate vfork() with fork() */
4305 if (flags
& CLONE_VFORK
)
4306 flags
&= ~(CLONE_VFORK
| CLONE_VM
);
4308 if (flags
& CLONE_VM
) {
4309 TaskState
*parent_ts
= (TaskState
*)env
->opaque
;
4310 #if defined(CONFIG_USE_NPTL)
4311 new_thread_info info
;
4312 pthread_attr_t attr
;
4314 ts
= g_malloc0(sizeof(TaskState
));
4315 init_task_state(ts
);
4316 /* we create a new CPU instance. */
4317 new_env
= cpu_copy(env
);
4318 #if defined(TARGET_I386) || defined(TARGET_SPARC) || defined(TARGET_PPC)
4319 cpu_reset(ENV_GET_CPU(new_env
));
4321 /* Init regs that differ from the parent. */
4322 cpu_clone_regs(new_env
, newsp
);
4323 new_env
->opaque
= ts
;
4324 ts
->bprm
= parent_ts
->bprm
;
4325 ts
->info
= parent_ts
->info
;
4326 #if defined(CONFIG_USE_NPTL)
4328 flags
&= ~CLONE_NPTL_FLAGS2
;
4330 if (nptl_flags
& CLONE_CHILD_CLEARTID
) {
4331 ts
->child_tidptr
= child_tidptr
;
4334 if (nptl_flags
& CLONE_SETTLS
)
4335 cpu_set_tls (new_env
, newtls
);
4337 /* Grab a mutex so that thread setup appears atomic. */
4338 pthread_mutex_lock(&clone_lock
);
4340 memset(&info
, 0, sizeof(info
));
4341 pthread_mutex_init(&info
.mutex
, NULL
);
4342 pthread_mutex_lock(&info
.mutex
);
4343 pthread_cond_init(&info
.cond
, NULL
);
4345 if (nptl_flags
& CLONE_CHILD_SETTID
)
4346 info
.child_tidptr
= child_tidptr
;
4347 if (nptl_flags
& CLONE_PARENT_SETTID
)
4348 info
.parent_tidptr
= parent_tidptr
;
4350 ret
= pthread_attr_init(&attr
);
4351 ret
= pthread_attr_setstacksize(&attr
, NEW_STACK_SIZE
);
4352 ret
= pthread_attr_setdetachstate(&attr
, PTHREAD_CREATE_DETACHED
);
4353 /* It is not safe to deliver signals until the child has finished
4354 initializing, so temporarily block all signals. */
4355 sigfillset(&sigmask
);
4356 sigprocmask(SIG_BLOCK
, &sigmask
, &info
.sigmask
);
4358 ret
= pthread_create(&info
.thread
, &attr
, clone_func
, &info
);
4359 /* TODO: Free new CPU state if thread creation failed. */
4361 sigprocmask(SIG_SETMASK
, &info
.sigmask
, NULL
);
4362 pthread_attr_destroy(&attr
);
4364 /* Wait for the child to initialize. */
4365 pthread_cond_wait(&info
.cond
, &info
.mutex
);
4367 if (flags
& CLONE_PARENT_SETTID
)
4368 put_user_u32(ret
, parent_tidptr
);
4372 pthread_mutex_unlock(&info
.mutex
);
4373 pthread_cond_destroy(&info
.cond
);
4374 pthread_mutex_destroy(&info
.mutex
);
4375 pthread_mutex_unlock(&clone_lock
);
4377 if (flags
& CLONE_NPTL_FLAGS2
)
4379 /* This is probably going to die very quickly, but do it anyway. */
4380 new_stack
= g_malloc0 (NEW_STACK_SIZE
);
4382 ret
= __clone2(clone_func
, new_stack
, NEW_STACK_SIZE
, flags
, new_env
);
4384 ret
= clone(clone_func
, new_stack
+ NEW_STACK_SIZE
, flags
, new_env
);
4388 /* if no CLONE_VM, we consider it is a fork */
4389 if ((flags
& ~(CSIGNAL
| CLONE_NPTL_FLAGS2
)) != 0)
4394 /* Child Process. */
4395 cpu_clone_regs(env
, newsp
);
4397 #if defined(CONFIG_USE_NPTL)
4398 /* There is a race condition here. The parent process could
4399 theoretically read the TID in the child process before the child
4400 tid is set. This would require using either ptrace
4401 (not implemented) or having *_tidptr to point at a shared memory
4402 mapping. We can't repeat the spinlock hack used above because
4403 the child process gets its own copy of the lock. */
4404 if (flags
& CLONE_CHILD_SETTID
)
4405 put_user_u32(gettid(), child_tidptr
);
4406 if (flags
& CLONE_PARENT_SETTID
)
4407 put_user_u32(gettid(), parent_tidptr
);
4408 ts
= (TaskState
*)env
->opaque
;
4409 if (flags
& CLONE_SETTLS
)
4410 cpu_set_tls (env
, newtls
);
4411 if (flags
& CLONE_CHILD_CLEARTID
)
4412 ts
->child_tidptr
= child_tidptr
;
4421 /* warning : doesn't handle linux specific flags... */
4422 static int target_to_host_fcntl_cmd(int cmd
)
4425 case TARGET_F_DUPFD
:
4426 case TARGET_F_GETFD
:
4427 case TARGET_F_SETFD
:
4428 case TARGET_F_GETFL
:
4429 case TARGET_F_SETFL
:
4431 case TARGET_F_GETLK
:
4433 case TARGET_F_SETLK
:
4435 case TARGET_F_SETLKW
:
4437 case TARGET_F_GETOWN
:
4439 case TARGET_F_SETOWN
:
4441 case TARGET_F_GETSIG
:
4443 case TARGET_F_SETSIG
:
4445 #if TARGET_ABI_BITS == 32
4446 case TARGET_F_GETLK64
:
4448 case TARGET_F_SETLK64
:
4450 case TARGET_F_SETLKW64
:
4453 case TARGET_F_SETLEASE
:
4455 case TARGET_F_GETLEASE
:
4457 #ifdef F_DUPFD_CLOEXEC
4458 case TARGET_F_DUPFD_CLOEXEC
:
4459 return F_DUPFD_CLOEXEC
;
4461 case TARGET_F_NOTIFY
:
4464 return -TARGET_EINVAL
;
4466 return -TARGET_EINVAL
;
4469 static abi_long
do_fcntl(int fd
, int cmd
, abi_ulong arg
)
4472 struct target_flock
*target_fl
;
4473 struct flock64 fl64
;
4474 struct target_flock64
*target_fl64
;
4476 int host_cmd
= target_to_host_fcntl_cmd(cmd
);
4478 if (host_cmd
== -TARGET_EINVAL
)
4482 case TARGET_F_GETLK
:
4483 if (!lock_user_struct(VERIFY_READ
, target_fl
, arg
, 1))
4484 return -TARGET_EFAULT
;
4485 fl
.l_type
= tswap16(target_fl
->l_type
);
4486 fl
.l_whence
= tswap16(target_fl
->l_whence
);
4487 fl
.l_start
= tswapal(target_fl
->l_start
);
4488 fl
.l_len
= tswapal(target_fl
->l_len
);
4489 fl
.l_pid
= tswap32(target_fl
->l_pid
);
4490 unlock_user_struct(target_fl
, arg
, 0);
4491 ret
= get_errno(fcntl(fd
, host_cmd
, &fl
));
4493 if (!lock_user_struct(VERIFY_WRITE
, target_fl
, arg
, 0))
4494 return -TARGET_EFAULT
;
4495 target_fl
->l_type
= tswap16(fl
.l_type
);
4496 target_fl
->l_whence
= tswap16(fl
.l_whence
);
4497 target_fl
->l_start
= tswapal(fl
.l_start
);
4498 target_fl
->l_len
= tswapal(fl
.l_len
);
4499 target_fl
->l_pid
= tswap32(fl
.l_pid
);
4500 unlock_user_struct(target_fl
, arg
, 1);
4504 case TARGET_F_SETLK
:
4505 case TARGET_F_SETLKW
:
4506 if (!lock_user_struct(VERIFY_READ
, target_fl
, arg
, 1))
4507 return -TARGET_EFAULT
;
4508 fl
.l_type
= tswap16(target_fl
->l_type
);
4509 fl
.l_whence
= tswap16(target_fl
->l_whence
);
4510 fl
.l_start
= tswapal(target_fl
->l_start
);
4511 fl
.l_len
= tswapal(target_fl
->l_len
);
4512 fl
.l_pid
= tswap32(target_fl
->l_pid
);
4513 unlock_user_struct(target_fl
, arg
, 0);
4514 ret
= get_errno(fcntl(fd
, host_cmd
, &fl
));
4517 case TARGET_F_GETLK64
:
4518 if (!lock_user_struct(VERIFY_READ
, target_fl64
, arg
, 1))
4519 return -TARGET_EFAULT
;
4520 fl64
.l_type
= tswap16(target_fl64
->l_type
) >> 1;
4521 fl64
.l_whence
= tswap16(target_fl64
->l_whence
);
4522 fl64
.l_start
= tswap64(target_fl64
->l_start
);
4523 fl64
.l_len
= tswap64(target_fl64
->l_len
);
4524 fl64
.l_pid
= tswap32(target_fl64
->l_pid
);
4525 unlock_user_struct(target_fl64
, arg
, 0);
4526 ret
= get_errno(fcntl(fd
, host_cmd
, &fl64
));
4528 if (!lock_user_struct(VERIFY_WRITE
, target_fl64
, arg
, 0))
4529 return -TARGET_EFAULT
;
4530 target_fl64
->l_type
= tswap16(fl64
.l_type
) >> 1;
4531 target_fl64
->l_whence
= tswap16(fl64
.l_whence
);
4532 target_fl64
->l_start
= tswap64(fl64
.l_start
);
4533 target_fl64
->l_len
= tswap64(fl64
.l_len
);
4534 target_fl64
->l_pid
= tswap32(fl64
.l_pid
);
4535 unlock_user_struct(target_fl64
, arg
, 1);
4538 case TARGET_F_SETLK64
:
4539 case TARGET_F_SETLKW64
:
4540 if (!lock_user_struct(VERIFY_READ
, target_fl64
, arg
, 1))
4541 return -TARGET_EFAULT
;
4542 fl64
.l_type
= tswap16(target_fl64
->l_type
) >> 1;
4543 fl64
.l_whence
= tswap16(target_fl64
->l_whence
);
4544 fl64
.l_start
= tswap64(target_fl64
->l_start
);
4545 fl64
.l_len
= tswap64(target_fl64
->l_len
);
4546 fl64
.l_pid
= tswap32(target_fl64
->l_pid
);
4547 unlock_user_struct(target_fl64
, arg
, 0);
4548 ret
= get_errno(fcntl(fd
, host_cmd
, &fl64
));
4551 case TARGET_F_GETFL
:
4552 ret
= get_errno(fcntl(fd
, host_cmd
, arg
));
4554 ret
= host_to_target_bitmask(ret
, fcntl_flags_tbl
);
4558 case TARGET_F_SETFL
:
4559 ret
= get_errno(fcntl(fd
, host_cmd
, target_to_host_bitmask(arg
, fcntl_flags_tbl
)));
4562 case TARGET_F_SETOWN
:
4563 case TARGET_F_GETOWN
:
4564 case TARGET_F_SETSIG
:
4565 case TARGET_F_GETSIG
:
4566 case TARGET_F_SETLEASE
:
4567 case TARGET_F_GETLEASE
:
4568 ret
= get_errno(fcntl(fd
, host_cmd
, arg
));
4572 ret
= get_errno(fcntl(fd
, cmd
, arg
));
4580 static inline int high2lowuid(int uid
)
4588 static inline int high2lowgid(int gid
)
4596 static inline int low2highuid(int uid
)
4598 if ((int16_t)uid
== -1)
4604 static inline int low2highgid(int gid
)
4606 if ((int16_t)gid
== -1)
4611 static inline int tswapid(int id
)
4615 #else /* !USE_UID16 */
4616 static inline int high2lowuid(int uid
)
4620 static inline int high2lowgid(int gid
)
4624 static inline int low2highuid(int uid
)
4628 static inline int low2highgid(int gid
)
4632 static inline int tswapid(int id
)
4636 #endif /* USE_UID16 */
4638 void syscall_init(void)
4641 const argtype
*arg_type
;
4645 #define STRUCT(name, ...) thunk_register_struct(STRUCT_ ## name, #name, struct_ ## name ## _def);
4646 #define STRUCT_SPECIAL(name) thunk_register_struct_direct(STRUCT_ ## name, #name, &struct_ ## name ## _def);
4647 #include "syscall_types.h"
4649 #undef STRUCT_SPECIAL
4651 /* Build target_to_host_errno_table[] table from
4652 * host_to_target_errno_table[]. */
4653 for (i
= 0; i
< ERRNO_TABLE_SIZE
; i
++) {
4654 target_to_host_errno_table
[host_to_target_errno_table
[i
]] = i
;
4657 /* we patch the ioctl size if necessary. We rely on the fact that
4658 no ioctl has all the bits at '1' in the size field */
4660 while (ie
->target_cmd
!= 0) {
4661 if (((ie
->target_cmd
>> TARGET_IOC_SIZESHIFT
) & TARGET_IOC_SIZEMASK
) ==
4662 TARGET_IOC_SIZEMASK
) {
4663 arg_type
= ie
->arg_type
;
4664 if (arg_type
[0] != TYPE_PTR
) {
4665 fprintf(stderr
, "cannot patch size for ioctl 0x%x\n",
4670 size
= thunk_type_size(arg_type
, 0);
4671 ie
->target_cmd
= (ie
->target_cmd
&
4672 ~(TARGET_IOC_SIZEMASK
<< TARGET_IOC_SIZESHIFT
)) |
4673 (size
<< TARGET_IOC_SIZESHIFT
);
4676 /* automatic consistency check if same arch */
4677 #if (defined(__i386__) && defined(TARGET_I386) && defined(TARGET_ABI32)) || \
4678 (defined(__x86_64__) && defined(TARGET_X86_64))
4679 if (unlikely(ie
->target_cmd
!= ie
->host_cmd
)) {
4680 fprintf(stderr
, "ERROR: ioctl(%s): target=0x%x host=0x%x\n",
4681 ie
->name
, ie
->target_cmd
, ie
->host_cmd
);
4688 #if TARGET_ABI_BITS == 32
4689 static inline uint64_t target_offset64(uint32_t word0
, uint32_t word1
)
4691 #ifdef TARGET_WORDS_BIGENDIAN
4692 return ((uint64_t)word0
<< 32) | word1
;
4694 return ((uint64_t)word1
<< 32) | word0
;
4697 #else /* TARGET_ABI_BITS == 32 */
4698 static inline uint64_t target_offset64(uint64_t word0
, uint64_t word1
)
4702 #endif /* TARGET_ABI_BITS != 32 */
4704 #ifdef TARGET_NR_truncate64
4705 static inline abi_long
target_truncate64(void *cpu_env
, const char *arg1
,
4710 if (regpairs_aligned(cpu_env
)) {
4714 return get_errno(truncate64(arg1
, target_offset64(arg2
, arg3
)));
4718 #ifdef TARGET_NR_ftruncate64
4719 static inline abi_long
target_ftruncate64(void *cpu_env
, abi_long arg1
,
4724 if (regpairs_aligned(cpu_env
)) {
4728 return get_errno(ftruncate64(arg1
, target_offset64(arg2
, arg3
)));
4732 static inline abi_long
target_to_host_timespec(struct timespec
*host_ts
,
4733 abi_ulong target_addr
)
4735 struct target_timespec
*target_ts
;
4737 if (!lock_user_struct(VERIFY_READ
, target_ts
, target_addr
, 1))
4738 return -TARGET_EFAULT
;
4739 host_ts
->tv_sec
= tswapal(target_ts
->tv_sec
);
4740 host_ts
->tv_nsec
= tswapal(target_ts
->tv_nsec
);
4741 unlock_user_struct(target_ts
, target_addr
, 0);
4745 static inline abi_long
host_to_target_timespec(abi_ulong target_addr
,
4746 struct timespec
*host_ts
)
4748 struct target_timespec
*target_ts
;
4750 if (!lock_user_struct(VERIFY_WRITE
, target_ts
, target_addr
, 0))
4751 return -TARGET_EFAULT
;
4752 target_ts
->tv_sec
= tswapal(host_ts
->tv_sec
);
4753 target_ts
->tv_nsec
= tswapal(host_ts
->tv_nsec
);
4754 unlock_user_struct(target_ts
, target_addr
, 1);
4758 #if defined(TARGET_NR_stat64) || defined(TARGET_NR_newfstatat)
4759 static inline abi_long
host_to_target_stat64(void *cpu_env
,
4760 abi_ulong target_addr
,
4761 struct stat
*host_st
)
4764 if (((CPUARMState
*)cpu_env
)->eabi
) {
4765 struct target_eabi_stat64
*target_st
;
4767 if (!lock_user_struct(VERIFY_WRITE
, target_st
, target_addr
, 0))
4768 return -TARGET_EFAULT
;
4769 memset(target_st
, 0, sizeof(struct target_eabi_stat64
));
4770 __put_user(host_st
->st_dev
, &target_st
->st_dev
);
4771 __put_user(host_st
->st_ino
, &target_st
->st_ino
);
4772 #ifdef TARGET_STAT64_HAS_BROKEN_ST_INO
4773 __put_user(host_st
->st_ino
, &target_st
->__st_ino
);
4775 __put_user(host_st
->st_mode
, &target_st
->st_mode
);
4776 __put_user(host_st
->st_nlink
, &target_st
->st_nlink
);
4777 __put_user(host_st
->st_uid
, &target_st
->st_uid
);
4778 __put_user(host_st
->st_gid
, &target_st
->st_gid
);
4779 __put_user(host_st
->st_rdev
, &target_st
->st_rdev
);
4780 __put_user(host_st
->st_size
, &target_st
->st_size
);
4781 __put_user(host_st
->st_blksize
, &target_st
->st_blksize
);
4782 __put_user(host_st
->st_blocks
, &target_st
->st_blocks
);
4783 __put_user(host_st
->st_atime
, &target_st
->target_st_atime
);
4784 __put_user(host_st
->st_mtime
, &target_st
->target_st_mtime
);
4785 __put_user(host_st
->st_ctime
, &target_st
->target_st_ctime
);
4786 unlock_user_struct(target_st
, target_addr
, 1);
4790 #if TARGET_ABI_BITS == 64 && !defined(TARGET_ALPHA)
4791 struct target_stat
*target_st
;
4793 struct target_stat64
*target_st
;
4796 if (!lock_user_struct(VERIFY_WRITE
, target_st
, target_addr
, 0))
4797 return -TARGET_EFAULT
;
4798 memset(target_st
, 0, sizeof(*target_st
));
4799 __put_user(host_st
->st_dev
, &target_st
->st_dev
);
4800 __put_user(host_st
->st_ino
, &target_st
->st_ino
);
4801 #ifdef TARGET_STAT64_HAS_BROKEN_ST_INO
4802 __put_user(host_st
->st_ino
, &target_st
->__st_ino
);
4804 __put_user(host_st
->st_mode
, &target_st
->st_mode
);
4805 __put_user(host_st
->st_nlink
, &target_st
->st_nlink
);
4806 __put_user(host_st
->st_uid
, &target_st
->st_uid
);
4807 __put_user(host_st
->st_gid
, &target_st
->st_gid
);
4808 __put_user(host_st
->st_rdev
, &target_st
->st_rdev
);
4809 /* XXX: better use of kernel struct */
4810 __put_user(host_st
->st_size
, &target_st
->st_size
);
4811 __put_user(host_st
->st_blksize
, &target_st
->st_blksize
);
4812 __put_user(host_st
->st_blocks
, &target_st
->st_blocks
);
4813 __put_user(host_st
->st_atime
, &target_st
->target_st_atime
);
4814 __put_user(host_st
->st_mtime
, &target_st
->target_st_mtime
);
4815 __put_user(host_st
->st_ctime
, &target_st
->target_st_ctime
);
4816 unlock_user_struct(target_st
, target_addr
, 1);
4823 #if defined(CONFIG_USE_NPTL)
4824 /* ??? Using host futex calls even when target atomic operations
4825 are not really atomic probably breaks things. However implementing
4826 futexes locally would make futexes shared between multiple processes
4827 tricky. However they're probably useless because guest atomic
4828 operations won't work either. */
4829 static int do_futex(target_ulong uaddr
, int op
, int val
, target_ulong timeout
,
4830 target_ulong uaddr2
, int val3
)
4832 struct timespec ts
, *pts
;
4835 /* ??? We assume FUTEX_* constants are the same on both host
4837 #ifdef FUTEX_CMD_MASK
4838 base_op
= op
& FUTEX_CMD_MASK
;
4846 target_to_host_timespec(pts
, timeout
);
4850 return get_errno(sys_futex(g2h(uaddr
), op
, tswap32(val
),
4853 return get_errno(sys_futex(g2h(uaddr
), op
, val
, NULL
, NULL
, 0));
4855 return get_errno(sys_futex(g2h(uaddr
), op
, val
, NULL
, NULL
, 0));
4857 case FUTEX_CMP_REQUEUE
:
4859 /* For FUTEX_REQUEUE, FUTEX_CMP_REQUEUE, and FUTEX_WAKE_OP, the
4860 TIMEOUT parameter is interpreted as a uint32_t by the kernel.
4861 But the prototype takes a `struct timespec *'; insert casts
4862 to satisfy the compiler. We do not need to tswap TIMEOUT
4863 since it's not compared to guest memory. */
4864 pts
= (struct timespec
*)(uintptr_t) timeout
;
4865 return get_errno(sys_futex(g2h(uaddr
), op
, val
, pts
,
4867 (base_op
== FUTEX_CMP_REQUEUE
4871 return -TARGET_ENOSYS
;
4876 /* Map host to target signal numbers for the wait family of syscalls.
4877 Assume all other status bits are the same. */
4878 static int host_to_target_waitstatus(int status
)
4880 if (WIFSIGNALED(status
)) {
4881 return host_to_target_signal(WTERMSIG(status
)) | (status
& ~0x7f);
4883 if (WIFSTOPPED(status
)) {
4884 return (host_to_target_signal(WSTOPSIG(status
)) << 8)
4890 int get_osversion(void)
4892 static int osversion
;
4893 struct new_utsname buf
;
4898 if (qemu_uname_release
&& *qemu_uname_release
) {
4899 s
= qemu_uname_release
;
4901 if (sys_uname(&buf
))
4906 for (i
= 0; i
< 3; i
++) {
4908 while (*s
>= '0' && *s
<= '9') {
4913 tmp
= (tmp
<< 8) + n
;
4922 static int open_self_maps(void *cpu_env
, int fd
)
4924 #if defined(TARGET_ARM) || defined(TARGET_M68K) || defined(TARGET_UNICORE32)
4925 TaskState
*ts
= ((CPUArchState
*)cpu_env
)->opaque
;
4932 fp
= fopen("/proc/self/maps", "r");
4937 while ((read
= getline(&line
, &len
, fp
)) != -1) {
4938 int fields
, dev_maj
, dev_min
, inode
;
4939 uint64_t min
, max
, offset
;
4940 char flag_r
, flag_w
, flag_x
, flag_p
;
4941 char path
[512] = "";
4942 fields
= sscanf(line
, "%"PRIx64
"-%"PRIx64
" %c%c%c%c %"PRIx64
" %x:%x %d"
4943 " %512s", &min
, &max
, &flag_r
, &flag_w
, &flag_x
,
4944 &flag_p
, &offset
, &dev_maj
, &dev_min
, &inode
, path
);
4946 if ((fields
< 10) || (fields
> 11)) {
4949 if (!strncmp(path
, "[stack]", 7)) {
4952 if (h2g_valid(min
) && h2g_valid(max
)) {
4953 dprintf(fd
, TARGET_ABI_FMT_lx
"-" TARGET_ABI_FMT_lx
4954 " %c%c%c%c %08" PRIx64
" %02x:%02x %d%s%s\n",
4955 h2g(min
), h2g(max
), flag_r
, flag_w
,
4956 flag_x
, flag_p
, offset
, dev_maj
, dev_min
, inode
,
4957 path
[0] ? " " : "", path
);
4964 #if defined(TARGET_ARM) || defined(TARGET_M68K) || defined(TARGET_UNICORE32)
4965 dprintf(fd
, "%08llx-%08llx rw-p %08llx 00:00 0 [stack]\n",
4966 (unsigned long long)ts
->info
->stack_limit
,
4967 (unsigned long long)(ts
->stack_base
+ (TARGET_PAGE_SIZE
- 1))
4969 (unsigned long long)0);
4975 static int open_self_stat(void *cpu_env
, int fd
)
4977 TaskState
*ts
= ((CPUArchState
*)cpu_env
)->opaque
;
4978 abi_ulong start_stack
= ts
->info
->start_stack
;
4981 for (i
= 0; i
< 44; i
++) {
4989 snprintf(buf
, sizeof(buf
), "%"PRId64
" ", val
);
4990 } else if (i
== 1) {
4992 snprintf(buf
, sizeof(buf
), "(%s) ", ts
->bprm
->argv
[0]);
4993 } else if (i
== 27) {
4996 snprintf(buf
, sizeof(buf
), "%"PRId64
" ", val
);
4998 /* for the rest, there is MasterCard */
4999 snprintf(buf
, sizeof(buf
), "0%c", i
== 43 ? '\n' : ' ');
5003 if (write(fd
, buf
, len
) != len
) {
5011 static int open_self_auxv(void *cpu_env
, int fd
)
5013 TaskState
*ts
= ((CPUArchState
*)cpu_env
)->opaque
;
5014 abi_ulong auxv
= ts
->info
->saved_auxv
;
5015 abi_ulong len
= ts
->info
->auxv_len
;
5019 * Auxiliary vector is stored in target process stack.
5020 * read in whole auxv vector and copy it to file
5022 ptr
= lock_user(VERIFY_READ
, auxv
, len
, 0);
5026 r
= write(fd
, ptr
, len
);
5033 lseek(fd
, 0, SEEK_SET
);
5034 unlock_user(ptr
, auxv
, len
);
5040 static int do_open(void *cpu_env
, const char *pathname
, int flags
, mode_t mode
)
5043 const char *filename
;
5044 int (*fill
)(void *cpu_env
, int fd
);
5046 const struct fake_open
*fake_open
;
5047 static const struct fake_open fakes
[] = {
5048 { "/proc/self/maps", open_self_maps
},
5049 { "/proc/self/stat", open_self_stat
},
5050 { "/proc/self/auxv", open_self_auxv
},
5054 for (fake_open
= fakes
; fake_open
->filename
; fake_open
++) {
5055 if (!strncmp(pathname
, fake_open
->filename
,
5056 strlen(fake_open
->filename
))) {
5061 if (fake_open
->filename
) {
5063 char filename
[PATH_MAX
];
5066 /* create temporary file to map stat to */
5067 tmpdir
= getenv("TMPDIR");
5070 snprintf(filename
, sizeof(filename
), "%s/qemu-open.XXXXXX", tmpdir
);
5071 fd
= mkstemp(filename
);
5077 if ((r
= fake_open
->fill(cpu_env
, fd
))) {
5081 lseek(fd
, 0, SEEK_SET
);
5086 return get_errno(open(path(pathname
), flags
, mode
));
5089 /* do_syscall() should always have a single exit point at the end so
5090 that actions, such as logging of syscall results, can be performed.
5091 All errnos that do_syscall() returns must be -TARGET_<errcode>. */
5092 abi_long
do_syscall(void *cpu_env
, int num
, abi_long arg1
,
5093 abi_long arg2
, abi_long arg3
, abi_long arg4
,
5094 abi_long arg5
, abi_long arg6
, abi_long arg7
,
5103 gemu_log("syscall %d", num
);
5106 print_syscall(num
, arg1
, arg2
, arg3
, arg4
, arg5
, arg6
);
5109 case TARGET_NR_exit
:
5110 #ifdef CONFIG_USE_NPTL
5111 /* In old applications this may be used to implement _exit(2).
5112 However in threaded applictions it is used for thread termination,
5113 and _exit_group is used for application termination.
5114 Do thread termination if we have more then one thread. */
5115 /* FIXME: This probably breaks if a signal arrives. We should probably
5116 be disabling signals. */
5117 if (first_cpu
->next_cpu
) {
5119 CPUArchState
**lastp
;
5125 while (p
&& p
!= (CPUArchState
*)cpu_env
) {
5126 lastp
= &p
->next_cpu
;
5129 /* If we didn't find the CPU for this thread then something is
5133 /* Remove the CPU from the list. */
5134 *lastp
= p
->next_cpu
;
5136 ts
= ((CPUArchState
*)cpu_env
)->opaque
;
5137 if (ts
->child_tidptr
) {
5138 put_user_u32(0, ts
->child_tidptr
);
5139 sys_futex(g2h(ts
->child_tidptr
), FUTEX_WAKE
, INT_MAX
,
5143 object_delete(OBJECT(ENV_GET_CPU(cpu_env
)));
5151 gdb_exit(cpu_env
, arg1
);
5153 ret
= 0; /* avoid warning */
5155 case TARGET_NR_read
:
5159 if (!(p
= lock_user(VERIFY_WRITE
, arg2
, arg3
, 0)))
5161 ret
= get_errno(read(arg1
, p
, arg3
));
5162 unlock_user(p
, arg2
, ret
);
5165 case TARGET_NR_write
:
5166 if (!(p
= lock_user(VERIFY_READ
, arg2
, arg3
, 1)))
5168 ret
= get_errno(write(arg1
, p
, arg3
));
5169 unlock_user(p
, arg2
, 0);
5171 case TARGET_NR_open
:
5172 if (!(p
= lock_user_string(arg1
)))
5174 ret
= get_errno(do_open(cpu_env
, p
,
5175 target_to_host_bitmask(arg2
, fcntl_flags_tbl
),
5177 unlock_user(p
, arg1
, 0);
5179 #if defined(TARGET_NR_openat) && defined(__NR_openat)
5180 case TARGET_NR_openat
:
5181 if (!(p
= lock_user_string(arg2
)))
5183 ret
= get_errno(sys_openat(arg1
,
5185 target_to_host_bitmask(arg3
, fcntl_flags_tbl
),
5187 unlock_user(p
, arg2
, 0);
5190 case TARGET_NR_close
:
5191 ret
= get_errno(close(arg1
));
5196 case TARGET_NR_fork
:
5197 ret
= get_errno(do_fork(cpu_env
, SIGCHLD
, 0, 0, 0, 0));
5199 #ifdef TARGET_NR_waitpid
5200 case TARGET_NR_waitpid
:
5203 ret
= get_errno(waitpid(arg1
, &status
, arg3
));
5204 if (!is_error(ret
) && arg2
&& ret
5205 && put_user_s32(host_to_target_waitstatus(status
), arg2
))
5210 #ifdef TARGET_NR_waitid
5211 case TARGET_NR_waitid
:
5215 ret
= get_errno(waitid(arg1
, arg2
, &info
, arg4
));
5216 if (!is_error(ret
) && arg3
&& info
.si_pid
!= 0) {
5217 if (!(p
= lock_user(VERIFY_WRITE
, arg3
, sizeof(target_siginfo_t
), 0)))
5219 host_to_target_siginfo(p
, &info
);
5220 unlock_user(p
, arg3
, sizeof(target_siginfo_t
));
5225 #ifdef TARGET_NR_creat /* not on alpha */
5226 case TARGET_NR_creat
:
5227 if (!(p
= lock_user_string(arg1
)))
5229 ret
= get_errno(creat(p
, arg2
));
5230 unlock_user(p
, arg1
, 0);
5233 case TARGET_NR_link
:
5236 p
= lock_user_string(arg1
);
5237 p2
= lock_user_string(arg2
);
5239 ret
= -TARGET_EFAULT
;
5241 ret
= get_errno(link(p
, p2
));
5242 unlock_user(p2
, arg2
, 0);
5243 unlock_user(p
, arg1
, 0);
5246 #if defined(TARGET_NR_linkat) && defined(__NR_linkat)
5247 case TARGET_NR_linkat
:
5252 p
= lock_user_string(arg2
);
5253 p2
= lock_user_string(arg4
);
5255 ret
= -TARGET_EFAULT
;
5257 ret
= get_errno(sys_linkat(arg1
, p
, arg3
, p2
, arg5
));
5258 unlock_user(p
, arg2
, 0);
5259 unlock_user(p2
, arg4
, 0);
5263 case TARGET_NR_unlink
:
5264 if (!(p
= lock_user_string(arg1
)))
5266 ret
= get_errno(unlink(p
));
5267 unlock_user(p
, arg1
, 0);
5269 #if defined(TARGET_NR_unlinkat) && defined(__NR_unlinkat)
5270 case TARGET_NR_unlinkat
:
5271 if (!(p
= lock_user_string(arg2
)))
5273 ret
= get_errno(sys_unlinkat(arg1
, p
, arg3
));
5274 unlock_user(p
, arg2
, 0);
5277 case TARGET_NR_execve
:
5279 char **argp
, **envp
;
5282 abi_ulong guest_argp
;
5283 abi_ulong guest_envp
;
5290 for (gp
= guest_argp
; gp
; gp
+= sizeof(abi_ulong
)) {
5291 if (get_user_ual(addr
, gp
))
5299 for (gp
= guest_envp
; gp
; gp
+= sizeof(abi_ulong
)) {
5300 if (get_user_ual(addr
, gp
))
5307 argp
= alloca((argc
+ 1) * sizeof(void *));
5308 envp
= alloca((envc
+ 1) * sizeof(void *));
5310 for (gp
= guest_argp
, q
= argp
; gp
;
5311 gp
+= sizeof(abi_ulong
), q
++) {
5312 if (get_user_ual(addr
, gp
))
5316 if (!(*q
= lock_user_string(addr
)))
5318 total_size
+= strlen(*q
) + 1;
5322 for (gp
= guest_envp
, q
= envp
; gp
;
5323 gp
+= sizeof(abi_ulong
), q
++) {
5324 if (get_user_ual(addr
, gp
))
5328 if (!(*q
= lock_user_string(addr
)))
5330 total_size
+= strlen(*q
) + 1;
5334 /* This case will not be caught by the host's execve() if its
5335 page size is bigger than the target's. */
5336 if (total_size
> MAX_ARG_PAGES
* TARGET_PAGE_SIZE
) {
5337 ret
= -TARGET_E2BIG
;
5340 if (!(p
= lock_user_string(arg1
)))
5342 ret
= get_errno(execve(p
, argp
, envp
));
5343 unlock_user(p
, arg1
, 0);
5348 ret
= -TARGET_EFAULT
;
5351 for (gp
= guest_argp
, q
= argp
; *q
;
5352 gp
+= sizeof(abi_ulong
), q
++) {
5353 if (get_user_ual(addr
, gp
)
5356 unlock_user(*q
, addr
, 0);
5358 for (gp
= guest_envp
, q
= envp
; *q
;
5359 gp
+= sizeof(abi_ulong
), q
++) {
5360 if (get_user_ual(addr
, gp
)
5363 unlock_user(*q
, addr
, 0);
5367 case TARGET_NR_chdir
:
5368 if (!(p
= lock_user_string(arg1
)))
5370 ret
= get_errno(chdir(p
));
5371 unlock_user(p
, arg1
, 0);
5373 #ifdef TARGET_NR_time
5374 case TARGET_NR_time
:
5377 ret
= get_errno(time(&host_time
));
5380 && put_user_sal(host_time
, arg1
))
5385 case TARGET_NR_mknod
:
5386 if (!(p
= lock_user_string(arg1
)))
5388 ret
= get_errno(mknod(p
, arg2
, arg3
));
5389 unlock_user(p
, arg1
, 0);
5391 #if defined(TARGET_NR_mknodat) && defined(__NR_mknodat)
5392 case TARGET_NR_mknodat
:
5393 if (!(p
= lock_user_string(arg2
)))
5395 ret
= get_errno(sys_mknodat(arg1
, p
, arg3
, arg4
));
5396 unlock_user(p
, arg2
, 0);
5399 case TARGET_NR_chmod
:
5400 if (!(p
= lock_user_string(arg1
)))
5402 ret
= get_errno(chmod(p
, arg2
));
5403 unlock_user(p
, arg1
, 0);
5405 #ifdef TARGET_NR_break
5406 case TARGET_NR_break
:
5409 #ifdef TARGET_NR_oldstat
5410 case TARGET_NR_oldstat
:
5413 case TARGET_NR_lseek
:
5414 ret
= get_errno(lseek(arg1
, arg2
, arg3
));
5416 #if defined(TARGET_NR_getxpid) && defined(TARGET_ALPHA)
5417 /* Alpha specific */
5418 case TARGET_NR_getxpid
:
5419 ((CPUAlphaState
*)cpu_env
)->ir
[IR_A4
] = getppid();
5420 ret
= get_errno(getpid());
5423 #ifdef TARGET_NR_getpid
5424 case TARGET_NR_getpid
:
5425 ret
= get_errno(getpid());
5428 case TARGET_NR_mount
:
5430 /* need to look at the data field */
5432 p
= lock_user_string(arg1
);
5433 p2
= lock_user_string(arg2
);
5434 p3
= lock_user_string(arg3
);
5435 if (!p
|| !p2
|| !p3
)
5436 ret
= -TARGET_EFAULT
;
5438 /* FIXME - arg5 should be locked, but it isn't clear how to
5439 * do that since it's not guaranteed to be a NULL-terminated
5443 ret
= get_errno(mount(p
, p2
, p3
, (unsigned long)arg4
, NULL
));
5445 ret
= get_errno(mount(p
, p2
, p3
, (unsigned long)arg4
, g2h(arg5
)));
5447 unlock_user(p
, arg1
, 0);
5448 unlock_user(p2
, arg2
, 0);
5449 unlock_user(p3
, arg3
, 0);
5452 #ifdef TARGET_NR_umount
5453 case TARGET_NR_umount
:
5454 if (!(p
= lock_user_string(arg1
)))
5456 ret
= get_errno(umount(p
));
5457 unlock_user(p
, arg1
, 0);
5460 #ifdef TARGET_NR_stime /* not on alpha */
5461 case TARGET_NR_stime
:
5464 if (get_user_sal(host_time
, arg1
))
5466 ret
= get_errno(stime(&host_time
));
5470 case TARGET_NR_ptrace
:
5472 #ifdef TARGET_NR_alarm /* not on alpha */
5473 case TARGET_NR_alarm
:
5477 #ifdef TARGET_NR_oldfstat
5478 case TARGET_NR_oldfstat
:
5481 #ifdef TARGET_NR_pause /* not on alpha */
5482 case TARGET_NR_pause
:
5483 ret
= get_errno(pause());
5486 #ifdef TARGET_NR_utime
5487 case TARGET_NR_utime
:
5489 struct utimbuf tbuf
, *host_tbuf
;
5490 struct target_utimbuf
*target_tbuf
;
5492 if (!lock_user_struct(VERIFY_READ
, target_tbuf
, arg2
, 1))
5494 tbuf
.actime
= tswapal(target_tbuf
->actime
);
5495 tbuf
.modtime
= tswapal(target_tbuf
->modtime
);
5496 unlock_user_struct(target_tbuf
, arg2
, 0);
5501 if (!(p
= lock_user_string(arg1
)))
5503 ret
= get_errno(utime(p
, host_tbuf
));
5504 unlock_user(p
, arg1
, 0);
5508 case TARGET_NR_utimes
:
5510 struct timeval
*tvp
, tv
[2];
5512 if (copy_from_user_timeval(&tv
[0], arg2
)
5513 || copy_from_user_timeval(&tv
[1],
5514 arg2
+ sizeof(struct target_timeval
)))
5520 if (!(p
= lock_user_string(arg1
)))
5522 ret
= get_errno(utimes(p
, tvp
));
5523 unlock_user(p
, arg1
, 0);
5526 #if defined(TARGET_NR_futimesat) && defined(__NR_futimesat)
5527 case TARGET_NR_futimesat
:
5529 struct timeval
*tvp
, tv
[2];
5531 if (copy_from_user_timeval(&tv
[0], arg3
)
5532 || copy_from_user_timeval(&tv
[1],
5533 arg3
+ sizeof(struct target_timeval
)))
5539 if (!(p
= lock_user_string(arg2
)))
5541 ret
= get_errno(sys_futimesat(arg1
, path(p
), tvp
));
5542 unlock_user(p
, arg2
, 0);
5546 #ifdef TARGET_NR_stty
5547 case TARGET_NR_stty
:
5550 #ifdef TARGET_NR_gtty
5551 case TARGET_NR_gtty
:
5554 case TARGET_NR_access
:
5555 if (!(p
= lock_user_string(arg1
)))
5557 ret
= get_errno(access(path(p
), arg2
));
5558 unlock_user(p
, arg1
, 0);
5560 #if defined(TARGET_NR_faccessat) && defined(__NR_faccessat)
5561 case TARGET_NR_faccessat
:
5562 if (!(p
= lock_user_string(arg2
)))
5564 ret
= get_errno(sys_faccessat(arg1
, p
, arg3
));
5565 unlock_user(p
, arg2
, 0);
5568 #ifdef TARGET_NR_nice /* not on alpha */
5569 case TARGET_NR_nice
:
5570 ret
= get_errno(nice(arg1
));
5573 #ifdef TARGET_NR_ftime
5574 case TARGET_NR_ftime
:
5577 case TARGET_NR_sync
:
5581 case TARGET_NR_kill
:
5582 ret
= get_errno(kill(arg1
, target_to_host_signal(arg2
)));
5584 case TARGET_NR_rename
:
5587 p
= lock_user_string(arg1
);
5588 p2
= lock_user_string(arg2
);
5590 ret
= -TARGET_EFAULT
;
5592 ret
= get_errno(rename(p
, p2
));
5593 unlock_user(p2
, arg2
, 0);
5594 unlock_user(p
, arg1
, 0);
5597 #if defined(TARGET_NR_renameat) && defined(__NR_renameat)
5598 case TARGET_NR_renameat
:
5601 p
= lock_user_string(arg2
);
5602 p2
= lock_user_string(arg4
);
5604 ret
= -TARGET_EFAULT
;
5606 ret
= get_errno(sys_renameat(arg1
, p
, arg3
, p2
));
5607 unlock_user(p2
, arg4
, 0);
5608 unlock_user(p
, arg2
, 0);
5612 case TARGET_NR_mkdir
:
5613 if (!(p
= lock_user_string(arg1
)))
5615 ret
= get_errno(mkdir(p
, arg2
));
5616 unlock_user(p
, arg1
, 0);
5618 #if defined(TARGET_NR_mkdirat) && defined(__NR_mkdirat)
5619 case TARGET_NR_mkdirat
:
5620 if (!(p
= lock_user_string(arg2
)))
5622 ret
= get_errno(sys_mkdirat(arg1
, p
, arg3
));
5623 unlock_user(p
, arg2
, 0);
5626 case TARGET_NR_rmdir
:
5627 if (!(p
= lock_user_string(arg1
)))
5629 ret
= get_errno(rmdir(p
));
5630 unlock_user(p
, arg1
, 0);
5633 ret
= get_errno(dup(arg1
));
5635 case TARGET_NR_pipe
:
5636 ret
= do_pipe(cpu_env
, arg1
, 0, 0);
5638 #ifdef TARGET_NR_pipe2
5639 case TARGET_NR_pipe2
:
5640 ret
= do_pipe(cpu_env
, arg1
,
5641 target_to_host_bitmask(arg2
, fcntl_flags_tbl
), 1);
5644 case TARGET_NR_times
:
5646 struct target_tms
*tmsp
;
5648 ret
= get_errno(times(&tms
));
5650 tmsp
= lock_user(VERIFY_WRITE
, arg1
, sizeof(struct target_tms
), 0);
5653 tmsp
->tms_utime
= tswapal(host_to_target_clock_t(tms
.tms_utime
));
5654 tmsp
->tms_stime
= tswapal(host_to_target_clock_t(tms
.tms_stime
));
5655 tmsp
->tms_cutime
= tswapal(host_to_target_clock_t(tms
.tms_cutime
));
5656 tmsp
->tms_cstime
= tswapal(host_to_target_clock_t(tms
.tms_cstime
));
5659 ret
= host_to_target_clock_t(ret
);
5662 #ifdef TARGET_NR_prof
5663 case TARGET_NR_prof
:
5666 #ifdef TARGET_NR_signal
5667 case TARGET_NR_signal
:
5670 case TARGET_NR_acct
:
5672 ret
= get_errno(acct(NULL
));
5674 if (!(p
= lock_user_string(arg1
)))
5676 ret
= get_errno(acct(path(p
)));
5677 unlock_user(p
, arg1
, 0);
5680 #ifdef TARGET_NR_umount2 /* not on alpha */
5681 case TARGET_NR_umount2
:
5682 if (!(p
= lock_user_string(arg1
)))
5684 ret
= get_errno(umount2(p
, arg2
));
5685 unlock_user(p
, arg1
, 0);
5688 #ifdef TARGET_NR_lock
5689 case TARGET_NR_lock
:
5692 case TARGET_NR_ioctl
:
5693 ret
= do_ioctl(arg1
, arg2
, arg3
);
5695 case TARGET_NR_fcntl
:
5696 ret
= do_fcntl(arg1
, arg2
, arg3
);
5698 #ifdef TARGET_NR_mpx
5702 case TARGET_NR_setpgid
:
5703 ret
= get_errno(setpgid(arg1
, arg2
));
5705 #ifdef TARGET_NR_ulimit
5706 case TARGET_NR_ulimit
:
5709 #ifdef TARGET_NR_oldolduname
5710 case TARGET_NR_oldolduname
:
5713 case TARGET_NR_umask
:
5714 ret
= get_errno(umask(arg1
));
5716 case TARGET_NR_chroot
:
5717 if (!(p
= lock_user_string(arg1
)))
5719 ret
= get_errno(chroot(p
));
5720 unlock_user(p
, arg1
, 0);
5722 case TARGET_NR_ustat
:
5724 case TARGET_NR_dup2
:
5725 ret
= get_errno(dup2(arg1
, arg2
));
5727 #if defined(CONFIG_DUP3) && defined(TARGET_NR_dup3)
5728 case TARGET_NR_dup3
:
5729 ret
= get_errno(dup3(arg1
, arg2
, arg3
));
5732 #ifdef TARGET_NR_getppid /* not on alpha */
5733 case TARGET_NR_getppid
:
5734 ret
= get_errno(getppid());
5737 case TARGET_NR_getpgrp
:
5738 ret
= get_errno(getpgrp());
5740 case TARGET_NR_setsid
:
5741 ret
= get_errno(setsid());
5743 #ifdef TARGET_NR_sigaction
5744 case TARGET_NR_sigaction
:
5746 #if defined(TARGET_ALPHA)
5747 struct target_sigaction act
, oact
, *pact
= 0;
5748 struct target_old_sigaction
*old_act
;
5750 if (!lock_user_struct(VERIFY_READ
, old_act
, arg2
, 1))
5752 act
._sa_handler
= old_act
->_sa_handler
;
5753 target_siginitset(&act
.sa_mask
, old_act
->sa_mask
);
5754 act
.sa_flags
= old_act
->sa_flags
;
5755 act
.sa_restorer
= 0;
5756 unlock_user_struct(old_act
, arg2
, 0);
5759 ret
= get_errno(do_sigaction(arg1
, pact
, &oact
));
5760 if (!is_error(ret
) && arg3
) {
5761 if (!lock_user_struct(VERIFY_WRITE
, old_act
, arg3
, 0))
5763 old_act
->_sa_handler
= oact
._sa_handler
;
5764 old_act
->sa_mask
= oact
.sa_mask
.sig
[0];
5765 old_act
->sa_flags
= oact
.sa_flags
;
5766 unlock_user_struct(old_act
, arg3
, 1);
5768 #elif defined(TARGET_MIPS)
5769 struct target_sigaction act
, oact
, *pact
, *old_act
;
5772 if (!lock_user_struct(VERIFY_READ
, old_act
, arg2
, 1))
5774 act
._sa_handler
= old_act
->_sa_handler
;
5775 target_siginitset(&act
.sa_mask
, old_act
->sa_mask
.sig
[0]);
5776 act
.sa_flags
= old_act
->sa_flags
;
5777 unlock_user_struct(old_act
, arg2
, 0);
5783 ret
= get_errno(do_sigaction(arg1
, pact
, &oact
));
5785 if (!is_error(ret
) && arg3
) {
5786 if (!lock_user_struct(VERIFY_WRITE
, old_act
, arg3
, 0))
5788 old_act
->_sa_handler
= oact
._sa_handler
;
5789 old_act
->sa_flags
= oact
.sa_flags
;
5790 old_act
->sa_mask
.sig
[0] = oact
.sa_mask
.sig
[0];
5791 old_act
->sa_mask
.sig
[1] = 0;
5792 old_act
->sa_mask
.sig
[2] = 0;
5793 old_act
->sa_mask
.sig
[3] = 0;
5794 unlock_user_struct(old_act
, arg3
, 1);
5797 struct target_old_sigaction
*old_act
;
5798 struct target_sigaction act
, oact
, *pact
;
5800 if (!lock_user_struct(VERIFY_READ
, old_act
, arg2
, 1))
5802 act
._sa_handler
= old_act
->_sa_handler
;
5803 target_siginitset(&act
.sa_mask
, old_act
->sa_mask
);
5804 act
.sa_flags
= old_act
->sa_flags
;
5805 act
.sa_restorer
= old_act
->sa_restorer
;
5806 unlock_user_struct(old_act
, arg2
, 0);
5811 ret
= get_errno(do_sigaction(arg1
, pact
, &oact
));
5812 if (!is_error(ret
) && arg3
) {
5813 if (!lock_user_struct(VERIFY_WRITE
, old_act
, arg3
, 0))
5815 old_act
->_sa_handler
= oact
._sa_handler
;
5816 old_act
->sa_mask
= oact
.sa_mask
.sig
[0];
5817 old_act
->sa_flags
= oact
.sa_flags
;
5818 old_act
->sa_restorer
= oact
.sa_restorer
;
5819 unlock_user_struct(old_act
, arg3
, 1);
5825 case TARGET_NR_rt_sigaction
:
5827 #if defined(TARGET_ALPHA)
5828 struct target_sigaction act
, oact
, *pact
= 0;
5829 struct target_rt_sigaction
*rt_act
;
5830 /* ??? arg4 == sizeof(sigset_t). */
5832 if (!lock_user_struct(VERIFY_READ
, rt_act
, arg2
, 1))
5834 act
._sa_handler
= rt_act
->_sa_handler
;
5835 act
.sa_mask
= rt_act
->sa_mask
;
5836 act
.sa_flags
= rt_act
->sa_flags
;
5837 act
.sa_restorer
= arg5
;
5838 unlock_user_struct(rt_act
, arg2
, 0);
5841 ret
= get_errno(do_sigaction(arg1
, pact
, &oact
));
5842 if (!is_error(ret
) && arg3
) {
5843 if (!lock_user_struct(VERIFY_WRITE
, rt_act
, arg3
, 0))
5845 rt_act
->_sa_handler
= oact
._sa_handler
;
5846 rt_act
->sa_mask
= oact
.sa_mask
;
5847 rt_act
->sa_flags
= oact
.sa_flags
;
5848 unlock_user_struct(rt_act
, arg3
, 1);
5851 struct target_sigaction
*act
;
5852 struct target_sigaction
*oact
;
5855 if (!lock_user_struct(VERIFY_READ
, act
, arg2
, 1))
5860 if (!lock_user_struct(VERIFY_WRITE
, oact
, arg3
, 0)) {
5861 ret
= -TARGET_EFAULT
;
5862 goto rt_sigaction_fail
;
5866 ret
= get_errno(do_sigaction(arg1
, act
, oact
));
5869 unlock_user_struct(act
, arg2
, 0);
5871 unlock_user_struct(oact
, arg3
, 1);
5875 #ifdef TARGET_NR_sgetmask /* not on alpha */
5876 case TARGET_NR_sgetmask
:
5879 abi_ulong target_set
;
5880 sigprocmask(0, NULL
, &cur_set
);
5881 host_to_target_old_sigset(&target_set
, &cur_set
);
5886 #ifdef TARGET_NR_ssetmask /* not on alpha */
5887 case TARGET_NR_ssetmask
:
5889 sigset_t set
, oset
, cur_set
;
5890 abi_ulong target_set
= arg1
;
5891 sigprocmask(0, NULL
, &cur_set
);
5892 target_to_host_old_sigset(&set
, &target_set
);
5893 sigorset(&set
, &set
, &cur_set
);
5894 sigprocmask(SIG_SETMASK
, &set
, &oset
);
5895 host_to_target_old_sigset(&target_set
, &oset
);
5900 #ifdef TARGET_NR_sigprocmask
5901 case TARGET_NR_sigprocmask
:
5903 #if defined(TARGET_ALPHA)
5904 sigset_t set
, oldset
;
5909 case TARGET_SIG_BLOCK
:
5912 case TARGET_SIG_UNBLOCK
:
5915 case TARGET_SIG_SETMASK
:
5919 ret
= -TARGET_EINVAL
;
5923 target_to_host_old_sigset(&set
, &mask
);
5925 ret
= get_errno(sigprocmask(how
, &set
, &oldset
));
5926 if (!is_error(ret
)) {
5927 host_to_target_old_sigset(&mask
, &oldset
);
5929 ((CPUAlphaState
*)cpu_env
)->ir
[IR_V0
] = 0; /* force no error */
5932 sigset_t set
, oldset
, *set_ptr
;
5937 case TARGET_SIG_BLOCK
:
5940 case TARGET_SIG_UNBLOCK
:
5943 case TARGET_SIG_SETMASK
:
5947 ret
= -TARGET_EINVAL
;
5950 if (!(p
= lock_user(VERIFY_READ
, arg2
, sizeof(target_sigset_t
), 1)))
5952 target_to_host_old_sigset(&set
, p
);
5953 unlock_user(p
, arg2
, 0);
5959 ret
= get_errno(sigprocmask(how
, set_ptr
, &oldset
));
5960 if (!is_error(ret
) && arg3
) {
5961 if (!(p
= lock_user(VERIFY_WRITE
, arg3
, sizeof(target_sigset_t
), 0)))
5963 host_to_target_old_sigset(p
, &oldset
);
5964 unlock_user(p
, arg3
, sizeof(target_sigset_t
));
5970 case TARGET_NR_rt_sigprocmask
:
5973 sigset_t set
, oldset
, *set_ptr
;
5977 case TARGET_SIG_BLOCK
:
5980 case TARGET_SIG_UNBLOCK
:
5983 case TARGET_SIG_SETMASK
:
5987 ret
= -TARGET_EINVAL
;
5990 if (!(p
= lock_user(VERIFY_READ
, arg2
, sizeof(target_sigset_t
), 1)))
5992 target_to_host_sigset(&set
, p
);
5993 unlock_user(p
, arg2
, 0);
5999 ret
= get_errno(sigprocmask(how
, set_ptr
, &oldset
));
6000 if (!is_error(ret
) && arg3
) {
6001 if (!(p
= lock_user(VERIFY_WRITE
, arg3
, sizeof(target_sigset_t
), 0)))
6003 host_to_target_sigset(p
, &oldset
);
6004 unlock_user(p
, arg3
, sizeof(target_sigset_t
));
6008 #ifdef TARGET_NR_sigpending
6009 case TARGET_NR_sigpending
:
6012 ret
= get_errno(sigpending(&set
));
6013 if (!is_error(ret
)) {
6014 if (!(p
= lock_user(VERIFY_WRITE
, arg1
, sizeof(target_sigset_t
), 0)))
6016 host_to_target_old_sigset(p
, &set
);
6017 unlock_user(p
, arg1
, sizeof(target_sigset_t
));
6022 case TARGET_NR_rt_sigpending
:
6025 ret
= get_errno(sigpending(&set
));
6026 if (!is_error(ret
)) {
6027 if (!(p
= lock_user(VERIFY_WRITE
, arg1
, sizeof(target_sigset_t
), 0)))
6029 host_to_target_sigset(p
, &set
);
6030 unlock_user(p
, arg1
, sizeof(target_sigset_t
));
6034 #ifdef TARGET_NR_sigsuspend
6035 case TARGET_NR_sigsuspend
:
6038 #if defined(TARGET_ALPHA)
6039 abi_ulong mask
= arg1
;
6040 target_to_host_old_sigset(&set
, &mask
);
6042 if (!(p
= lock_user(VERIFY_READ
, arg1
, sizeof(target_sigset_t
), 1)))
6044 target_to_host_old_sigset(&set
, p
);
6045 unlock_user(p
, arg1
, 0);
6047 ret
= get_errno(sigsuspend(&set
));
6051 case TARGET_NR_rt_sigsuspend
:
6054 if (!(p
= lock_user(VERIFY_READ
, arg1
, sizeof(target_sigset_t
), 1)))
6056 target_to_host_sigset(&set
, p
);
6057 unlock_user(p
, arg1
, 0);
6058 ret
= get_errno(sigsuspend(&set
));
6061 case TARGET_NR_rt_sigtimedwait
:
6064 struct timespec uts
, *puts
;
6067 if (!(p
= lock_user(VERIFY_READ
, arg1
, sizeof(target_sigset_t
), 1)))
6069 target_to_host_sigset(&set
, p
);
6070 unlock_user(p
, arg1
, 0);
6073 target_to_host_timespec(puts
, arg3
);
6077 ret
= get_errno(sigtimedwait(&set
, &uinfo
, puts
));
6078 if (!is_error(ret
) && arg2
) {
6079 if (!(p
= lock_user(VERIFY_WRITE
, arg2
, sizeof(target_siginfo_t
), 0)))
6081 host_to_target_siginfo(p
, &uinfo
);
6082 unlock_user(p
, arg2
, sizeof(target_siginfo_t
));
6086 case TARGET_NR_rt_sigqueueinfo
:
6089 if (!(p
= lock_user(VERIFY_READ
, arg3
, sizeof(target_sigset_t
), 1)))
6091 target_to_host_siginfo(&uinfo
, p
);
6092 unlock_user(p
, arg1
, 0);
6093 ret
= get_errno(sys_rt_sigqueueinfo(arg1
, arg2
, &uinfo
));
6096 #ifdef TARGET_NR_sigreturn
6097 case TARGET_NR_sigreturn
:
6098 /* NOTE: ret is eax, so not transcoding must be done */
6099 ret
= do_sigreturn(cpu_env
);
6102 case TARGET_NR_rt_sigreturn
:
6103 /* NOTE: ret is eax, so not transcoding must be done */
6104 ret
= do_rt_sigreturn(cpu_env
);
6106 case TARGET_NR_sethostname
:
6107 if (!(p
= lock_user_string(arg1
)))
6109 ret
= get_errno(sethostname(p
, arg2
));
6110 unlock_user(p
, arg1
, 0);
6112 case TARGET_NR_setrlimit
:
6114 int resource
= target_to_host_resource(arg1
);
6115 struct target_rlimit
*target_rlim
;
6117 if (!lock_user_struct(VERIFY_READ
, target_rlim
, arg2
, 1))
6119 rlim
.rlim_cur
= target_to_host_rlim(target_rlim
->rlim_cur
);
6120 rlim
.rlim_max
= target_to_host_rlim(target_rlim
->rlim_max
);
6121 unlock_user_struct(target_rlim
, arg2
, 0);
6122 ret
= get_errno(setrlimit(resource
, &rlim
));
6125 case TARGET_NR_getrlimit
:
6127 int resource
= target_to_host_resource(arg1
);
6128 struct target_rlimit
*target_rlim
;
6131 ret
= get_errno(getrlimit(resource
, &rlim
));
6132 if (!is_error(ret
)) {
6133 if (!lock_user_struct(VERIFY_WRITE
, target_rlim
, arg2
, 0))
6135 target_rlim
->rlim_cur
= host_to_target_rlim(rlim
.rlim_cur
);
6136 target_rlim
->rlim_max
= host_to_target_rlim(rlim
.rlim_max
);
6137 unlock_user_struct(target_rlim
, arg2
, 1);
6141 case TARGET_NR_getrusage
:
6143 struct rusage rusage
;
6144 ret
= get_errno(getrusage(arg1
, &rusage
));
6145 if (!is_error(ret
)) {
6146 host_to_target_rusage(arg2
, &rusage
);
6150 case TARGET_NR_gettimeofday
:
6153 ret
= get_errno(gettimeofday(&tv
, NULL
));
6154 if (!is_error(ret
)) {
6155 if (copy_to_user_timeval(arg1
, &tv
))
6160 case TARGET_NR_settimeofday
:
6163 if (copy_from_user_timeval(&tv
, arg1
))
6165 ret
= get_errno(settimeofday(&tv
, NULL
));
6168 #if defined(TARGET_NR_select) && !defined(TARGET_S390X) && !defined(TARGET_S390)
6169 case TARGET_NR_select
:
6171 struct target_sel_arg_struct
*sel
;
6172 abi_ulong inp
, outp
, exp
, tvp
;
6175 if (!lock_user_struct(VERIFY_READ
, sel
, arg1
, 1))
6177 nsel
= tswapal(sel
->n
);
6178 inp
= tswapal(sel
->inp
);
6179 outp
= tswapal(sel
->outp
);
6180 exp
= tswapal(sel
->exp
);
6181 tvp
= tswapal(sel
->tvp
);
6182 unlock_user_struct(sel
, arg1
, 0);
6183 ret
= do_select(nsel
, inp
, outp
, exp
, tvp
);
6187 #ifdef TARGET_NR_pselect6
6188 case TARGET_NR_pselect6
:
6190 abi_long rfd_addr
, wfd_addr
, efd_addr
, n
, ts_addr
;
6191 fd_set rfds
, wfds
, efds
;
6192 fd_set
*rfds_ptr
, *wfds_ptr
, *efds_ptr
;
6193 struct timespec ts
, *ts_ptr
;
6196 * The 6th arg is actually two args smashed together,
6197 * so we cannot use the C library.
6205 abi_ulong arg_sigset
, arg_sigsize
, *arg7
;
6206 target_sigset_t
*target_sigset
;
6214 ret
= copy_from_user_fdset_ptr(&rfds
, &rfds_ptr
, rfd_addr
, n
);
6218 ret
= copy_from_user_fdset_ptr(&wfds
, &wfds_ptr
, wfd_addr
, n
);
6222 ret
= copy_from_user_fdset_ptr(&efds
, &efds_ptr
, efd_addr
, n
);
6228 * This takes a timespec, and not a timeval, so we cannot
6229 * use the do_select() helper ...
6232 if (target_to_host_timespec(&ts
, ts_addr
)) {
6240 /* Extract the two packed args for the sigset */
6243 sig
.size
= _NSIG
/ 8;
6245 arg7
= lock_user(VERIFY_READ
, arg6
, sizeof(*arg7
) * 2, 1);
6249 arg_sigset
= tswapal(arg7
[0]);
6250 arg_sigsize
= tswapal(arg7
[1]);
6251 unlock_user(arg7
, arg6
, 0);
6255 if (arg_sigsize
!= sizeof(*target_sigset
)) {
6256 /* Like the kernel, we enforce correct size sigsets */
6257 ret
= -TARGET_EINVAL
;
6260 target_sigset
= lock_user(VERIFY_READ
, arg_sigset
,
6261 sizeof(*target_sigset
), 1);
6262 if (!target_sigset
) {
6265 target_to_host_sigset(&set
, target_sigset
);
6266 unlock_user(target_sigset
, arg_sigset
, 0);
6274 ret
= get_errno(sys_pselect6(n
, rfds_ptr
, wfds_ptr
, efds_ptr
,
6277 if (!is_error(ret
)) {
6278 if (rfd_addr
&& copy_to_user_fdset(rfd_addr
, &rfds
, n
))
6280 if (wfd_addr
&& copy_to_user_fdset(wfd_addr
, &wfds
, n
))
6282 if (efd_addr
&& copy_to_user_fdset(efd_addr
, &efds
, n
))
6285 if (ts_addr
&& host_to_target_timespec(ts_addr
, &ts
))
6291 case TARGET_NR_symlink
:
6294 p
= lock_user_string(arg1
);
6295 p2
= lock_user_string(arg2
);
6297 ret
= -TARGET_EFAULT
;
6299 ret
= get_errno(symlink(p
, p2
));
6300 unlock_user(p2
, arg2
, 0);
6301 unlock_user(p
, arg1
, 0);
6304 #if defined(TARGET_NR_symlinkat) && defined(__NR_symlinkat)
6305 case TARGET_NR_symlinkat
:
6308 p
= lock_user_string(arg1
);
6309 p2
= lock_user_string(arg3
);
6311 ret
= -TARGET_EFAULT
;
6313 ret
= get_errno(sys_symlinkat(p
, arg2
, p2
));
6314 unlock_user(p2
, arg3
, 0);
6315 unlock_user(p
, arg1
, 0);
6319 #ifdef TARGET_NR_oldlstat
6320 case TARGET_NR_oldlstat
:
6323 case TARGET_NR_readlink
:
6326 p
= lock_user_string(arg1
);
6327 p2
= lock_user(VERIFY_WRITE
, arg2
, arg3
, 0);
6329 ret
= -TARGET_EFAULT
;
6331 if (strncmp((const char *)p
, "/proc/self/exe", 14) == 0) {
6332 char real
[PATH_MAX
];
6333 temp
= realpath(exec_path
,real
);
6334 ret
= (temp
==NULL
) ? get_errno(-1) : strlen(real
) ;
6335 snprintf((char *)p2
, arg3
, "%s", real
);
6338 ret
= get_errno(readlink(path(p
), p2
, arg3
));
6340 unlock_user(p2
, arg2
, ret
);
6341 unlock_user(p
, arg1
, 0);
6344 #if defined(TARGET_NR_readlinkat) && defined(__NR_readlinkat)
6345 case TARGET_NR_readlinkat
:
6348 p
= lock_user_string(arg2
);
6349 p2
= lock_user(VERIFY_WRITE
, arg3
, arg4
, 0);
6351 ret
= -TARGET_EFAULT
;
6353 ret
= get_errno(sys_readlinkat(arg1
, path(p
), p2
, arg4
));
6354 unlock_user(p2
, arg3
, ret
);
6355 unlock_user(p
, arg2
, 0);
6359 #ifdef TARGET_NR_uselib
6360 case TARGET_NR_uselib
:
6363 #ifdef TARGET_NR_swapon
6364 case TARGET_NR_swapon
:
6365 if (!(p
= lock_user_string(arg1
)))
6367 ret
= get_errno(swapon(p
, arg2
));
6368 unlock_user(p
, arg1
, 0);
6371 case TARGET_NR_reboot
:
6372 if (!(p
= lock_user_string(arg4
)))
6374 ret
= reboot(arg1
, arg2
, arg3
, p
);
6375 unlock_user(p
, arg4
, 0);
6377 #ifdef TARGET_NR_readdir
6378 case TARGET_NR_readdir
:
6381 #ifdef TARGET_NR_mmap
6382 case TARGET_NR_mmap
:
6383 #if (defined(TARGET_I386) && defined(TARGET_ABI32)) || defined(TARGET_ARM) || \
6384 defined(TARGET_M68K) || defined(TARGET_CRIS) || defined(TARGET_MICROBLAZE) \
6385 || defined(TARGET_S390X)
6388 abi_ulong v1
, v2
, v3
, v4
, v5
, v6
;
6389 if (!(v
= lock_user(VERIFY_READ
, arg1
, 6 * sizeof(abi_ulong
), 1)))
6397 unlock_user(v
, arg1
, 0);
6398 ret
= get_errno(target_mmap(v1
, v2
, v3
,
6399 target_to_host_bitmask(v4
, mmap_flags_tbl
),
6403 ret
= get_errno(target_mmap(arg1
, arg2
, arg3
,
6404 target_to_host_bitmask(arg4
, mmap_flags_tbl
),
6410 #ifdef TARGET_NR_mmap2
6411 case TARGET_NR_mmap2
:
6413 #define MMAP_SHIFT 12
6415 ret
= get_errno(target_mmap(arg1
, arg2
, arg3
,
6416 target_to_host_bitmask(arg4
, mmap_flags_tbl
),
6418 arg6
<< MMAP_SHIFT
));
6421 case TARGET_NR_munmap
:
6422 ret
= get_errno(target_munmap(arg1
, arg2
));
6424 case TARGET_NR_mprotect
:
6426 TaskState
*ts
= ((CPUArchState
*)cpu_env
)->opaque
;
6427 /* Special hack to detect libc making the stack executable. */
6428 if ((arg3
& PROT_GROWSDOWN
)
6429 && arg1
>= ts
->info
->stack_limit
6430 && arg1
<= ts
->info
->start_stack
) {
6431 arg3
&= ~PROT_GROWSDOWN
;
6432 arg2
= arg2
+ arg1
- ts
->info
->stack_limit
;
6433 arg1
= ts
->info
->stack_limit
;
6436 ret
= get_errno(target_mprotect(arg1
, arg2
, arg3
));
6438 #ifdef TARGET_NR_mremap
6439 case TARGET_NR_mremap
:
6440 ret
= get_errno(target_mremap(arg1
, arg2
, arg3
, arg4
, arg5
));
6443 /* ??? msync/mlock/munlock are broken for softmmu. */
6444 #ifdef TARGET_NR_msync
6445 case TARGET_NR_msync
:
6446 ret
= get_errno(msync(g2h(arg1
), arg2
, arg3
));
6449 #ifdef TARGET_NR_mlock
6450 case TARGET_NR_mlock
:
6451 ret
= get_errno(mlock(g2h(arg1
), arg2
));
6454 #ifdef TARGET_NR_munlock
6455 case TARGET_NR_munlock
:
6456 ret
= get_errno(munlock(g2h(arg1
), arg2
));
6459 #ifdef TARGET_NR_mlockall
6460 case TARGET_NR_mlockall
:
6461 ret
= get_errno(mlockall(arg1
));
6464 #ifdef TARGET_NR_munlockall
6465 case TARGET_NR_munlockall
:
6466 ret
= get_errno(munlockall());
6469 case TARGET_NR_truncate
:
6470 if (!(p
= lock_user_string(arg1
)))
6472 ret
= get_errno(truncate(p
, arg2
));
6473 unlock_user(p
, arg1
, 0);
6475 case TARGET_NR_ftruncate
:
6476 ret
= get_errno(ftruncate(arg1
, arg2
));
6478 case TARGET_NR_fchmod
:
6479 ret
= get_errno(fchmod(arg1
, arg2
));
6481 #if defined(TARGET_NR_fchmodat) && defined(__NR_fchmodat)
6482 case TARGET_NR_fchmodat
:
6483 if (!(p
= lock_user_string(arg2
)))
6485 ret
= get_errno(sys_fchmodat(arg1
, p
, arg3
));
6486 unlock_user(p
, arg2
, 0);
6489 case TARGET_NR_getpriority
:
6490 /* Note that negative values are valid for getpriority, so we must
6491 differentiate based on errno settings. */
6493 ret
= getpriority(arg1
, arg2
);
6494 if (ret
== -1 && errno
!= 0) {
6495 ret
= -host_to_target_errno(errno
);
6499 /* Return value is the unbiased priority. Signal no error. */
6500 ((CPUAlphaState
*)cpu_env
)->ir
[IR_V0
] = 0;
6502 /* Return value is a biased priority to avoid negative numbers. */
6506 case TARGET_NR_setpriority
:
6507 ret
= get_errno(setpriority(arg1
, arg2
, arg3
));
6509 #ifdef TARGET_NR_profil
6510 case TARGET_NR_profil
:
6513 case TARGET_NR_statfs
:
6514 if (!(p
= lock_user_string(arg1
)))
6516 ret
= get_errno(statfs(path(p
), &stfs
));
6517 unlock_user(p
, arg1
, 0);
6519 if (!is_error(ret
)) {
6520 struct target_statfs
*target_stfs
;
6522 if (!lock_user_struct(VERIFY_WRITE
, target_stfs
, arg2
, 0))
6524 __put_user(stfs
.f_type
, &target_stfs
->f_type
);
6525 __put_user(stfs
.f_bsize
, &target_stfs
->f_bsize
);
6526 __put_user(stfs
.f_blocks
, &target_stfs
->f_blocks
);
6527 __put_user(stfs
.f_bfree
, &target_stfs
->f_bfree
);
6528 __put_user(stfs
.f_bavail
, &target_stfs
->f_bavail
);
6529 __put_user(stfs
.f_files
, &target_stfs
->f_files
);
6530 __put_user(stfs
.f_ffree
, &target_stfs
->f_ffree
);
6531 __put_user(stfs
.f_fsid
.__val
[0], &target_stfs
->f_fsid
.val
[0]);
6532 __put_user(stfs
.f_fsid
.__val
[1], &target_stfs
->f_fsid
.val
[1]);
6533 __put_user(stfs
.f_namelen
, &target_stfs
->f_namelen
);
6534 unlock_user_struct(target_stfs
, arg2
, 1);
6537 case TARGET_NR_fstatfs
:
6538 ret
= get_errno(fstatfs(arg1
, &stfs
));
6539 goto convert_statfs
;
6540 #ifdef TARGET_NR_statfs64
6541 case TARGET_NR_statfs64
:
6542 if (!(p
= lock_user_string(arg1
)))
6544 ret
= get_errno(statfs(path(p
), &stfs
));
6545 unlock_user(p
, arg1
, 0);
6547 if (!is_error(ret
)) {
6548 struct target_statfs64
*target_stfs
;
6550 if (!lock_user_struct(VERIFY_WRITE
, target_stfs
, arg3
, 0))
6552 __put_user(stfs
.f_type
, &target_stfs
->f_type
);
6553 __put_user(stfs
.f_bsize
, &target_stfs
->f_bsize
);
6554 __put_user(stfs
.f_blocks
, &target_stfs
->f_blocks
);
6555 __put_user(stfs
.f_bfree
, &target_stfs
->f_bfree
);
6556 __put_user(stfs
.f_bavail
, &target_stfs
->f_bavail
);
6557 __put_user(stfs
.f_files
, &target_stfs
->f_files
);
6558 __put_user(stfs
.f_ffree
, &target_stfs
->f_ffree
);
6559 __put_user(stfs
.f_fsid
.__val
[0], &target_stfs
->f_fsid
.val
[0]);
6560 __put_user(stfs
.f_fsid
.__val
[1], &target_stfs
->f_fsid
.val
[1]);
6561 __put_user(stfs
.f_namelen
, &target_stfs
->f_namelen
);
6562 unlock_user_struct(target_stfs
, arg3
, 1);
6565 case TARGET_NR_fstatfs64
:
6566 ret
= get_errno(fstatfs(arg1
, &stfs
));
6567 goto convert_statfs64
;
6569 #ifdef TARGET_NR_ioperm
6570 case TARGET_NR_ioperm
:
6573 #ifdef TARGET_NR_socketcall
6574 case TARGET_NR_socketcall
:
6575 ret
= do_socketcall(arg1
, arg2
);
6578 #ifdef TARGET_NR_accept
6579 case TARGET_NR_accept
:
6580 ret
= do_accept(arg1
, arg2
, arg3
);
6583 #ifdef TARGET_NR_bind
6584 case TARGET_NR_bind
:
6585 ret
= do_bind(arg1
, arg2
, arg3
);
6588 #ifdef TARGET_NR_connect
6589 case TARGET_NR_connect
:
6590 ret
= do_connect(arg1
, arg2
, arg3
);
6593 #ifdef TARGET_NR_getpeername
6594 case TARGET_NR_getpeername
:
6595 ret
= do_getpeername(arg1
, arg2
, arg3
);
6598 #ifdef TARGET_NR_getsockname
6599 case TARGET_NR_getsockname
:
6600 ret
= do_getsockname(arg1
, arg2
, arg3
);
6603 #ifdef TARGET_NR_getsockopt
6604 case TARGET_NR_getsockopt
:
6605 ret
= do_getsockopt(arg1
, arg2
, arg3
, arg4
, arg5
);
6608 #ifdef TARGET_NR_listen
6609 case TARGET_NR_listen
:
6610 ret
= get_errno(listen(arg1
, arg2
));
6613 #ifdef TARGET_NR_recv
6614 case TARGET_NR_recv
:
6615 ret
= do_recvfrom(arg1
, arg2
, arg3
, arg4
, 0, 0);
6618 #ifdef TARGET_NR_recvfrom
6619 case TARGET_NR_recvfrom
:
6620 ret
= do_recvfrom(arg1
, arg2
, arg3
, arg4
, arg5
, arg6
);
6623 #ifdef TARGET_NR_recvmsg
6624 case TARGET_NR_recvmsg
:
6625 ret
= do_sendrecvmsg(arg1
, arg2
, arg3
, 0);
6628 #ifdef TARGET_NR_send
6629 case TARGET_NR_send
:
6630 ret
= do_sendto(arg1
, arg2
, arg3
, arg4
, 0, 0);
6633 #ifdef TARGET_NR_sendmsg
6634 case TARGET_NR_sendmsg
:
6635 ret
= do_sendrecvmsg(arg1
, arg2
, arg3
, 1);
6638 #ifdef TARGET_NR_sendto
6639 case TARGET_NR_sendto
:
6640 ret
= do_sendto(arg1
, arg2
, arg3
, arg4
, arg5
, arg6
);
6643 #ifdef TARGET_NR_shutdown
6644 case TARGET_NR_shutdown
:
6645 ret
= get_errno(shutdown(arg1
, arg2
));
6648 #ifdef TARGET_NR_socket
6649 case TARGET_NR_socket
:
6650 ret
= do_socket(arg1
, arg2
, arg3
);
6653 #ifdef TARGET_NR_socketpair
6654 case TARGET_NR_socketpair
:
6655 ret
= do_socketpair(arg1
, arg2
, arg3
, arg4
);
6658 #ifdef TARGET_NR_setsockopt
6659 case TARGET_NR_setsockopt
:
6660 ret
= do_setsockopt(arg1
, arg2
, arg3
, arg4
, (socklen_t
) arg5
);
6664 case TARGET_NR_syslog
:
6665 if (!(p
= lock_user_string(arg2
)))
6667 ret
= get_errno(sys_syslog((int)arg1
, p
, (int)arg3
));
6668 unlock_user(p
, arg2
, 0);
6671 case TARGET_NR_setitimer
:
6673 struct itimerval value
, ovalue
, *pvalue
;
6677 if (copy_from_user_timeval(&pvalue
->it_interval
, arg2
)
6678 || copy_from_user_timeval(&pvalue
->it_value
,
6679 arg2
+ sizeof(struct target_timeval
)))
6684 ret
= get_errno(setitimer(arg1
, pvalue
, &ovalue
));
6685 if (!is_error(ret
) && arg3
) {
6686 if (copy_to_user_timeval(arg3
,
6687 &ovalue
.it_interval
)
6688 || copy_to_user_timeval(arg3
+ sizeof(struct target_timeval
),
6694 case TARGET_NR_getitimer
:
6696 struct itimerval value
;
6698 ret
= get_errno(getitimer(arg1
, &value
));
6699 if (!is_error(ret
) && arg2
) {
6700 if (copy_to_user_timeval(arg2
,
6702 || copy_to_user_timeval(arg2
+ sizeof(struct target_timeval
),
6708 case TARGET_NR_stat
:
6709 if (!(p
= lock_user_string(arg1
)))
6711 ret
= get_errno(stat(path(p
), &st
));
6712 unlock_user(p
, arg1
, 0);
6714 case TARGET_NR_lstat
:
6715 if (!(p
= lock_user_string(arg1
)))
6717 ret
= get_errno(lstat(path(p
), &st
));
6718 unlock_user(p
, arg1
, 0);
6720 case TARGET_NR_fstat
:
6722 ret
= get_errno(fstat(arg1
, &st
));
6724 if (!is_error(ret
)) {
6725 struct target_stat
*target_st
;
6727 if (!lock_user_struct(VERIFY_WRITE
, target_st
, arg2
, 0))
6729 memset(target_st
, 0, sizeof(*target_st
));
6730 __put_user(st
.st_dev
, &target_st
->st_dev
);
6731 __put_user(st
.st_ino
, &target_st
->st_ino
);
6732 __put_user(st
.st_mode
, &target_st
->st_mode
);
6733 __put_user(st
.st_uid
, &target_st
->st_uid
);
6734 __put_user(st
.st_gid
, &target_st
->st_gid
);
6735 __put_user(st
.st_nlink
, &target_st
->st_nlink
);
6736 __put_user(st
.st_rdev
, &target_st
->st_rdev
);
6737 __put_user(st
.st_size
, &target_st
->st_size
);
6738 __put_user(st
.st_blksize
, &target_st
->st_blksize
);
6739 __put_user(st
.st_blocks
, &target_st
->st_blocks
);
6740 __put_user(st
.st_atime
, &target_st
->target_st_atime
);
6741 __put_user(st
.st_mtime
, &target_st
->target_st_mtime
);
6742 __put_user(st
.st_ctime
, &target_st
->target_st_ctime
);
6743 unlock_user_struct(target_st
, arg2
, 1);
6747 #ifdef TARGET_NR_olduname
6748 case TARGET_NR_olduname
:
6751 #ifdef TARGET_NR_iopl
6752 case TARGET_NR_iopl
:
6755 case TARGET_NR_vhangup
:
6756 ret
= get_errno(vhangup());
6758 #ifdef TARGET_NR_idle
6759 case TARGET_NR_idle
:
6762 #ifdef TARGET_NR_syscall
6763 case TARGET_NR_syscall
:
6764 ret
= do_syscall(cpu_env
, arg1
& 0xffff, arg2
, arg3
, arg4
, arg5
,
6765 arg6
, arg7
, arg8
, 0);
6768 case TARGET_NR_wait4
:
6771 abi_long status_ptr
= arg2
;
6772 struct rusage rusage
, *rusage_ptr
;
6773 abi_ulong target_rusage
= arg4
;
6775 rusage_ptr
= &rusage
;
6778 ret
= get_errno(wait4(arg1
, &status
, arg3
, rusage_ptr
));
6779 if (!is_error(ret
)) {
6780 if (status_ptr
&& ret
) {
6781 status
= host_to_target_waitstatus(status
);
6782 if (put_user_s32(status
, status_ptr
))
6786 host_to_target_rusage(target_rusage
, &rusage
);
6790 #ifdef TARGET_NR_swapoff
6791 case TARGET_NR_swapoff
:
6792 if (!(p
= lock_user_string(arg1
)))
6794 ret
= get_errno(swapoff(p
));
6795 unlock_user(p
, arg1
, 0);
6798 case TARGET_NR_sysinfo
:
6800 struct target_sysinfo
*target_value
;
6801 struct sysinfo value
;
6802 ret
= get_errno(sysinfo(&value
));
6803 if (!is_error(ret
) && arg1
)
6805 if (!lock_user_struct(VERIFY_WRITE
, target_value
, arg1
, 0))
6807 __put_user(value
.uptime
, &target_value
->uptime
);
6808 __put_user(value
.loads
[0], &target_value
->loads
[0]);
6809 __put_user(value
.loads
[1], &target_value
->loads
[1]);
6810 __put_user(value
.loads
[2], &target_value
->loads
[2]);
6811 __put_user(value
.totalram
, &target_value
->totalram
);
6812 __put_user(value
.freeram
, &target_value
->freeram
);
6813 __put_user(value
.sharedram
, &target_value
->sharedram
);
6814 __put_user(value
.bufferram
, &target_value
->bufferram
);
6815 __put_user(value
.totalswap
, &target_value
->totalswap
);
6816 __put_user(value
.freeswap
, &target_value
->freeswap
);
6817 __put_user(value
.procs
, &target_value
->procs
);
6818 __put_user(value
.totalhigh
, &target_value
->totalhigh
);
6819 __put_user(value
.freehigh
, &target_value
->freehigh
);
6820 __put_user(value
.mem_unit
, &target_value
->mem_unit
);
6821 unlock_user_struct(target_value
, arg1
, 1);
6825 #ifdef TARGET_NR_ipc
6827 ret
= do_ipc(arg1
, arg2
, arg3
, arg4
, arg5
, arg6
);
6830 #ifdef TARGET_NR_semget
6831 case TARGET_NR_semget
:
6832 ret
= get_errno(semget(arg1
, arg2
, arg3
));
6835 #ifdef TARGET_NR_semop
6836 case TARGET_NR_semop
:
6837 ret
= get_errno(do_semop(arg1
, arg2
, arg3
));
6840 #ifdef TARGET_NR_semctl
6841 case TARGET_NR_semctl
:
6842 ret
= do_semctl(arg1
, arg2
, arg3
, (union target_semun
)(abi_ulong
)arg4
);
6845 #ifdef TARGET_NR_msgctl
6846 case TARGET_NR_msgctl
:
6847 ret
= do_msgctl(arg1
, arg2
, arg3
);
6850 #ifdef TARGET_NR_msgget
6851 case TARGET_NR_msgget
:
6852 ret
= get_errno(msgget(arg1
, arg2
));
6855 #ifdef TARGET_NR_msgrcv
6856 case TARGET_NR_msgrcv
:
6857 ret
= do_msgrcv(arg1
, arg2
, arg3
, arg4
, arg5
);
6860 #ifdef TARGET_NR_msgsnd
6861 case TARGET_NR_msgsnd
:
6862 ret
= do_msgsnd(arg1
, arg2
, arg3
, arg4
);
6865 #ifdef TARGET_NR_shmget
6866 case TARGET_NR_shmget
:
6867 ret
= get_errno(shmget(arg1
, arg2
, arg3
));
6870 #ifdef TARGET_NR_shmctl
6871 case TARGET_NR_shmctl
:
6872 ret
= do_shmctl(arg1
, arg2
, arg3
);
6875 #ifdef TARGET_NR_shmat
6876 case TARGET_NR_shmat
:
6877 ret
= do_shmat(arg1
, arg2
, arg3
);
6880 #ifdef TARGET_NR_shmdt
6881 case TARGET_NR_shmdt
:
6882 ret
= do_shmdt(arg1
);
6885 case TARGET_NR_fsync
:
6886 ret
= get_errno(fsync(arg1
));
6888 case TARGET_NR_clone
:
6889 #if defined(TARGET_SH4) || defined(TARGET_ALPHA)
6890 ret
= get_errno(do_fork(cpu_env
, arg1
, arg2
, arg3
, arg5
, arg4
));
6891 #elif defined(TARGET_CRIS)
6892 ret
= get_errno(do_fork(cpu_env
, arg2
, arg1
, arg3
, arg4
, arg5
));
6893 #elif defined(TARGET_S390X)
6894 ret
= get_errno(do_fork(cpu_env
, arg2
, arg1
, arg3
, arg5
, arg4
));
6896 ret
= get_errno(do_fork(cpu_env
, arg1
, arg2
, arg3
, arg4
, arg5
));
6899 #ifdef __NR_exit_group
6900 /* new thread calls */
6901 case TARGET_NR_exit_group
:
6905 gdb_exit(cpu_env
, arg1
);
6906 ret
= get_errno(exit_group(arg1
));
6909 case TARGET_NR_setdomainname
:
6910 if (!(p
= lock_user_string(arg1
)))
6912 ret
= get_errno(setdomainname(p
, arg2
));
6913 unlock_user(p
, arg1
, 0);
6915 case TARGET_NR_uname
:
6916 /* no need to transcode because we use the linux syscall */
6918 struct new_utsname
* buf
;
6920 if (!lock_user_struct(VERIFY_WRITE
, buf
, arg1
, 0))
6922 ret
= get_errno(sys_uname(buf
));
6923 if (!is_error(ret
)) {
6924 /* Overrite the native machine name with whatever is being
6926 strcpy (buf
->machine
, cpu_to_uname_machine(cpu_env
));
6927 /* Allow the user to override the reported release. */
6928 if (qemu_uname_release
&& *qemu_uname_release
)
6929 strcpy (buf
->release
, qemu_uname_release
);
6931 unlock_user_struct(buf
, arg1
, 1);
6935 case TARGET_NR_modify_ldt
:
6936 ret
= do_modify_ldt(cpu_env
, arg1
, arg2
, arg3
);
6938 #if !defined(TARGET_X86_64)
6939 case TARGET_NR_vm86old
:
6941 case TARGET_NR_vm86
:
6942 ret
= do_vm86(cpu_env
, arg1
, arg2
);
6946 case TARGET_NR_adjtimex
:
6948 #ifdef TARGET_NR_create_module
6949 case TARGET_NR_create_module
:
6951 case TARGET_NR_init_module
:
6952 case TARGET_NR_delete_module
:
6953 #ifdef TARGET_NR_get_kernel_syms
6954 case TARGET_NR_get_kernel_syms
:
6957 case TARGET_NR_quotactl
:
6959 case TARGET_NR_getpgid
:
6960 ret
= get_errno(getpgid(arg1
));
6962 case TARGET_NR_fchdir
:
6963 ret
= get_errno(fchdir(arg1
));
6965 #ifdef TARGET_NR_bdflush /* not on x86_64 */
6966 case TARGET_NR_bdflush
:
6969 #ifdef TARGET_NR_sysfs
6970 case TARGET_NR_sysfs
:
6973 case TARGET_NR_personality
:
6974 ret
= get_errno(personality(arg1
));
6976 #ifdef TARGET_NR_afs_syscall
6977 case TARGET_NR_afs_syscall
:
6980 #ifdef TARGET_NR__llseek /* Not on alpha */
6981 case TARGET_NR__llseek
:
6984 #if !defined(__NR_llseek)
6985 res
= lseek(arg1
, ((uint64_t)arg2
<< 32) | arg3
, arg5
);
6987 ret
= get_errno(res
);
6992 ret
= get_errno(_llseek(arg1
, arg2
, arg3
, &res
, arg5
));
6994 if ((ret
== 0) && put_user_s64(res
, arg4
)) {
7000 case TARGET_NR_getdents
:
7001 #if TARGET_ABI_BITS == 32 && HOST_LONG_BITS == 64
7003 struct target_dirent
*target_dirp
;
7004 struct linux_dirent
*dirp
;
7005 abi_long count
= arg3
;
7007 dirp
= malloc(count
);
7009 ret
= -TARGET_ENOMEM
;
7013 ret
= get_errno(sys_getdents(arg1
, dirp
, count
));
7014 if (!is_error(ret
)) {
7015 struct linux_dirent
*de
;
7016 struct target_dirent
*tde
;
7018 int reclen
, treclen
;
7019 int count1
, tnamelen
;
7023 if (!(target_dirp
= lock_user(VERIFY_WRITE
, arg2
, count
, 0)))
7027 reclen
= de
->d_reclen
;
7028 tnamelen
= reclen
- offsetof(struct linux_dirent
, d_name
);
7029 assert(tnamelen
>= 0);
7030 treclen
= tnamelen
+ offsetof(struct target_dirent
, d_name
);
7031 assert(count1
+ treclen
<= count
);
7032 tde
->d_reclen
= tswap16(treclen
);
7033 tde
->d_ino
= tswapal(de
->d_ino
);
7034 tde
->d_off
= tswapal(de
->d_off
);
7035 memcpy(tde
->d_name
, de
->d_name
, tnamelen
);
7036 de
= (struct linux_dirent
*)((char *)de
+ reclen
);
7038 tde
= (struct target_dirent
*)((char *)tde
+ treclen
);
7042 unlock_user(target_dirp
, arg2
, ret
);
7048 struct linux_dirent
*dirp
;
7049 abi_long count
= arg3
;
7051 if (!(dirp
= lock_user(VERIFY_WRITE
, arg2
, count
, 0)))
7053 ret
= get_errno(sys_getdents(arg1
, dirp
, count
));
7054 if (!is_error(ret
)) {
7055 struct linux_dirent
*de
;
7060 reclen
= de
->d_reclen
;
7063 de
->d_reclen
= tswap16(reclen
);
7064 tswapls(&de
->d_ino
);
7065 tswapls(&de
->d_off
);
7066 de
= (struct linux_dirent
*)((char *)de
+ reclen
);
7070 unlock_user(dirp
, arg2
, ret
);
7074 #if defined(TARGET_NR_getdents64) && defined(__NR_getdents64)
7075 case TARGET_NR_getdents64
:
7077 struct linux_dirent64
*dirp
;
7078 abi_long count
= arg3
;
7079 if (!(dirp
= lock_user(VERIFY_WRITE
, arg2
, count
, 0)))
7081 ret
= get_errno(sys_getdents64(arg1
, dirp
, count
));
7082 if (!is_error(ret
)) {
7083 struct linux_dirent64
*de
;
7088 reclen
= de
->d_reclen
;
7091 de
->d_reclen
= tswap16(reclen
);
7092 tswap64s((uint64_t *)&de
->d_ino
);
7093 tswap64s((uint64_t *)&de
->d_off
);
7094 de
= (struct linux_dirent64
*)((char *)de
+ reclen
);
7098 unlock_user(dirp
, arg2
, ret
);
7101 #endif /* TARGET_NR_getdents64 */
7102 #if defined(TARGET_NR__newselect) || defined(TARGET_S390X)
7104 case TARGET_NR_select
:
7106 case TARGET_NR__newselect
:
7108 ret
= do_select(arg1
, arg2
, arg3
, arg4
, arg5
);
7111 #if defined(TARGET_NR_poll) || defined(TARGET_NR_ppoll)
7112 # ifdef TARGET_NR_poll
7113 case TARGET_NR_poll
:
7115 # ifdef TARGET_NR_ppoll
7116 case TARGET_NR_ppoll
:
7119 struct target_pollfd
*target_pfd
;
7120 unsigned int nfds
= arg2
;
7125 target_pfd
= lock_user(VERIFY_WRITE
, arg1
, sizeof(struct target_pollfd
) * nfds
, 1);
7129 pfd
= alloca(sizeof(struct pollfd
) * nfds
);
7130 for(i
= 0; i
< nfds
; i
++) {
7131 pfd
[i
].fd
= tswap32(target_pfd
[i
].fd
);
7132 pfd
[i
].events
= tswap16(target_pfd
[i
].events
);
7135 # ifdef TARGET_NR_ppoll
7136 if (num
== TARGET_NR_ppoll
) {
7137 struct timespec _timeout_ts
, *timeout_ts
= &_timeout_ts
;
7138 target_sigset_t
*target_set
;
7139 sigset_t _set
, *set
= &_set
;
7142 if (target_to_host_timespec(timeout_ts
, arg3
)) {
7143 unlock_user(target_pfd
, arg1
, 0);
7151 target_set
= lock_user(VERIFY_READ
, arg4
, sizeof(target_sigset_t
), 1);
7153 unlock_user(target_pfd
, arg1
, 0);
7156 target_to_host_sigset(set
, target_set
);
7161 ret
= get_errno(sys_ppoll(pfd
, nfds
, timeout_ts
, set
, _NSIG
/8));
7163 if (!is_error(ret
) && arg3
) {
7164 host_to_target_timespec(arg3
, timeout_ts
);
7167 unlock_user(target_set
, arg4
, 0);
7171 ret
= get_errno(poll(pfd
, nfds
, timeout
));
7173 if (!is_error(ret
)) {
7174 for(i
= 0; i
< nfds
; i
++) {
7175 target_pfd
[i
].revents
= tswap16(pfd
[i
].revents
);
7178 unlock_user(target_pfd
, arg1
, sizeof(struct target_pollfd
) * nfds
);
7182 case TARGET_NR_flock
:
7183 /* NOTE: the flock constant seems to be the same for every
7185 ret
= get_errno(flock(arg1
, arg2
));
7187 case TARGET_NR_readv
:
7192 vec
= alloca(count
* sizeof(struct iovec
));
7193 if (lock_iovec(VERIFY_WRITE
, vec
, arg2
, count
, 0) < 0)
7195 ret
= get_errno(readv(arg1
, vec
, count
));
7196 unlock_iovec(vec
, arg2
, count
, 1);
7199 case TARGET_NR_writev
:
7204 vec
= alloca(count
* sizeof(struct iovec
));
7205 if (lock_iovec(VERIFY_READ
, vec
, arg2
, count
, 1) < 0)
7207 ret
= get_errno(writev(arg1
, vec
, count
));
7208 unlock_iovec(vec
, arg2
, count
, 0);
7211 case TARGET_NR_getsid
:
7212 ret
= get_errno(getsid(arg1
));
7214 #if defined(TARGET_NR_fdatasync) /* Not on alpha (osf_datasync ?) */
7215 case TARGET_NR_fdatasync
:
7216 ret
= get_errno(fdatasync(arg1
));
7219 case TARGET_NR__sysctl
:
7220 /* We don't implement this, but ENOTDIR is always a safe
7222 ret
= -TARGET_ENOTDIR
;
7224 case TARGET_NR_sched_getaffinity
:
7226 unsigned int mask_size
;
7227 unsigned long *mask
;
7230 * sched_getaffinity needs multiples of ulong, so need to take
7231 * care of mismatches between target ulong and host ulong sizes.
7233 if (arg2
& (sizeof(abi_ulong
) - 1)) {
7234 ret
= -TARGET_EINVAL
;
7237 mask_size
= (arg2
+ (sizeof(*mask
) - 1)) & ~(sizeof(*mask
) - 1);
7239 mask
= alloca(mask_size
);
7240 ret
= get_errno(sys_sched_getaffinity(arg1
, mask_size
, mask
));
7242 if (!is_error(ret
)) {
7243 if (copy_to_user(arg3
, mask
, ret
)) {
7249 case TARGET_NR_sched_setaffinity
:
7251 unsigned int mask_size
;
7252 unsigned long *mask
;
7255 * sched_setaffinity needs multiples of ulong, so need to take
7256 * care of mismatches between target ulong and host ulong sizes.
7258 if (arg2
& (sizeof(abi_ulong
) - 1)) {
7259 ret
= -TARGET_EINVAL
;
7262 mask_size
= (arg2
+ (sizeof(*mask
) - 1)) & ~(sizeof(*mask
) - 1);
7264 mask
= alloca(mask_size
);
7265 if (!lock_user_struct(VERIFY_READ
, p
, arg3
, 1)) {
7268 memcpy(mask
, p
, arg2
);
7269 unlock_user_struct(p
, arg2
, 0);
7271 ret
= get_errno(sys_sched_setaffinity(arg1
, mask_size
, mask
));
7274 case TARGET_NR_sched_setparam
:
7276 struct sched_param
*target_schp
;
7277 struct sched_param schp
;
7279 if (!lock_user_struct(VERIFY_READ
, target_schp
, arg2
, 1))
7281 schp
.sched_priority
= tswap32(target_schp
->sched_priority
);
7282 unlock_user_struct(target_schp
, arg2
, 0);
7283 ret
= get_errno(sched_setparam(arg1
, &schp
));
7286 case TARGET_NR_sched_getparam
:
7288 struct sched_param
*target_schp
;
7289 struct sched_param schp
;
7290 ret
= get_errno(sched_getparam(arg1
, &schp
));
7291 if (!is_error(ret
)) {
7292 if (!lock_user_struct(VERIFY_WRITE
, target_schp
, arg2
, 0))
7294 target_schp
->sched_priority
= tswap32(schp
.sched_priority
);
7295 unlock_user_struct(target_schp
, arg2
, 1);
7299 case TARGET_NR_sched_setscheduler
:
7301 struct sched_param
*target_schp
;
7302 struct sched_param schp
;
7303 if (!lock_user_struct(VERIFY_READ
, target_schp
, arg3
, 1))
7305 schp
.sched_priority
= tswap32(target_schp
->sched_priority
);
7306 unlock_user_struct(target_schp
, arg3
, 0);
7307 ret
= get_errno(sched_setscheduler(arg1
, arg2
, &schp
));
7310 case TARGET_NR_sched_getscheduler
:
7311 ret
= get_errno(sched_getscheduler(arg1
));
7313 case TARGET_NR_sched_yield
:
7314 ret
= get_errno(sched_yield());
7316 case TARGET_NR_sched_get_priority_max
:
7317 ret
= get_errno(sched_get_priority_max(arg1
));
7319 case TARGET_NR_sched_get_priority_min
:
7320 ret
= get_errno(sched_get_priority_min(arg1
));
7322 case TARGET_NR_sched_rr_get_interval
:
7325 ret
= get_errno(sched_rr_get_interval(arg1
, &ts
));
7326 if (!is_error(ret
)) {
7327 host_to_target_timespec(arg2
, &ts
);
7331 case TARGET_NR_nanosleep
:
7333 struct timespec req
, rem
;
7334 target_to_host_timespec(&req
, arg1
);
7335 ret
= get_errno(nanosleep(&req
, &rem
));
7336 if (is_error(ret
) && arg2
) {
7337 host_to_target_timespec(arg2
, &rem
);
7341 #ifdef TARGET_NR_query_module
7342 case TARGET_NR_query_module
:
7345 #ifdef TARGET_NR_nfsservctl
7346 case TARGET_NR_nfsservctl
:
7349 case TARGET_NR_prctl
:
7351 case PR_GET_PDEATHSIG
:
7354 ret
= get_errno(prctl(arg1
, &deathsig
, arg3
, arg4
, arg5
));
7355 if (!is_error(ret
) && arg2
7356 && put_user_ual(deathsig
, arg2
)) {
7364 void *name
= lock_user(VERIFY_WRITE
, arg2
, 16, 1);
7368 ret
= get_errno(prctl(arg1
, (unsigned long)name
,
7370 unlock_user(name
, arg2
, 16);
7375 void *name
= lock_user(VERIFY_READ
, arg2
, 16, 1);
7379 ret
= get_errno(prctl(arg1
, (unsigned long)name
,
7381 unlock_user(name
, arg2
, 0);
7386 /* Most prctl options have no pointer arguments */
7387 ret
= get_errno(prctl(arg1
, arg2
, arg3
, arg4
, arg5
));
7391 #ifdef TARGET_NR_arch_prctl
7392 case TARGET_NR_arch_prctl
:
7393 #if defined(TARGET_I386) && !defined(TARGET_ABI32)
7394 ret
= do_arch_prctl(cpu_env
, arg1
, arg2
);
7400 #ifdef TARGET_NR_pread
7401 case TARGET_NR_pread
:
7402 if (regpairs_aligned(cpu_env
))
7404 if (!(p
= lock_user(VERIFY_WRITE
, arg2
, arg3
, 0)))
7406 ret
= get_errno(pread(arg1
, p
, arg3
, arg4
));
7407 unlock_user(p
, arg2
, ret
);
7409 case TARGET_NR_pwrite
:
7410 if (regpairs_aligned(cpu_env
))
7412 if (!(p
= lock_user(VERIFY_READ
, arg2
, arg3
, 1)))
7414 ret
= get_errno(pwrite(arg1
, p
, arg3
, arg4
));
7415 unlock_user(p
, arg2
, 0);
7418 #ifdef TARGET_NR_pread64
7419 case TARGET_NR_pread64
:
7420 if (!(p
= lock_user(VERIFY_WRITE
, arg2
, arg3
, 0)))
7422 ret
= get_errno(pread64(arg1
, p
, arg3
, target_offset64(arg4
, arg5
)));
7423 unlock_user(p
, arg2
, ret
);
7425 case TARGET_NR_pwrite64
:
7426 if (!(p
= lock_user(VERIFY_READ
, arg2
, arg3
, 1)))
7428 ret
= get_errno(pwrite64(arg1
, p
, arg3
, target_offset64(arg4
, arg5
)));
7429 unlock_user(p
, arg2
, 0);
7432 case TARGET_NR_getcwd
:
7433 if (!(p
= lock_user(VERIFY_WRITE
, arg1
, arg2
, 0)))
7435 ret
= get_errno(sys_getcwd1(p
, arg2
));
7436 unlock_user(p
, arg1
, ret
);
7438 case TARGET_NR_capget
:
7440 case TARGET_NR_capset
:
7442 case TARGET_NR_sigaltstack
:
7443 #if defined(TARGET_I386) || defined(TARGET_ARM) || defined(TARGET_MIPS) || \
7444 defined(TARGET_SPARC) || defined(TARGET_PPC) || defined(TARGET_ALPHA) || \
7445 defined(TARGET_M68K) || defined(TARGET_S390X) || defined(TARGET_OPENRISC)
7446 ret
= do_sigaltstack(arg1
, arg2
, get_sp_from_cpustate((CPUArchState
*)cpu_env
));
7451 case TARGET_NR_sendfile
:
7453 #ifdef TARGET_NR_getpmsg
7454 case TARGET_NR_getpmsg
:
7457 #ifdef TARGET_NR_putpmsg
7458 case TARGET_NR_putpmsg
:
7461 #ifdef TARGET_NR_vfork
7462 case TARGET_NR_vfork
:
7463 ret
= get_errno(do_fork(cpu_env
, CLONE_VFORK
| CLONE_VM
| SIGCHLD
,
7467 #ifdef TARGET_NR_ugetrlimit
7468 case TARGET_NR_ugetrlimit
:
7471 int resource
= target_to_host_resource(arg1
);
7472 ret
= get_errno(getrlimit(resource
, &rlim
));
7473 if (!is_error(ret
)) {
7474 struct target_rlimit
*target_rlim
;
7475 if (!lock_user_struct(VERIFY_WRITE
, target_rlim
, arg2
, 0))
7477 target_rlim
->rlim_cur
= host_to_target_rlim(rlim
.rlim_cur
);
7478 target_rlim
->rlim_max
= host_to_target_rlim(rlim
.rlim_max
);
7479 unlock_user_struct(target_rlim
, arg2
, 1);
7484 #ifdef TARGET_NR_truncate64
7485 case TARGET_NR_truncate64
:
7486 if (!(p
= lock_user_string(arg1
)))
7488 ret
= target_truncate64(cpu_env
, p
, arg2
, arg3
, arg4
);
7489 unlock_user(p
, arg1
, 0);
7492 #ifdef TARGET_NR_ftruncate64
7493 case TARGET_NR_ftruncate64
:
7494 ret
= target_ftruncate64(cpu_env
, arg1
, arg2
, arg3
, arg4
);
7497 #ifdef TARGET_NR_stat64
7498 case TARGET_NR_stat64
:
7499 if (!(p
= lock_user_string(arg1
)))
7501 ret
= get_errno(stat(path(p
), &st
));
7502 unlock_user(p
, arg1
, 0);
7504 ret
= host_to_target_stat64(cpu_env
, arg2
, &st
);
7507 #ifdef TARGET_NR_lstat64
7508 case TARGET_NR_lstat64
:
7509 if (!(p
= lock_user_string(arg1
)))
7511 ret
= get_errno(lstat(path(p
), &st
));
7512 unlock_user(p
, arg1
, 0);
7514 ret
= host_to_target_stat64(cpu_env
, arg2
, &st
);
7517 #ifdef TARGET_NR_fstat64
7518 case TARGET_NR_fstat64
:
7519 ret
= get_errno(fstat(arg1
, &st
));
7521 ret
= host_to_target_stat64(cpu_env
, arg2
, &st
);
7524 #if (defined(TARGET_NR_fstatat64) || defined(TARGET_NR_newfstatat)) && \
7525 (defined(__NR_fstatat64) || defined(__NR_newfstatat))
7526 #ifdef TARGET_NR_fstatat64
7527 case TARGET_NR_fstatat64
:
7529 #ifdef TARGET_NR_newfstatat
7530 case TARGET_NR_newfstatat
:
7532 if (!(p
= lock_user_string(arg2
)))
7534 #ifdef __NR_fstatat64
7535 ret
= get_errno(sys_fstatat64(arg1
, path(p
), &st
, arg4
));
7537 ret
= get_errno(sys_newfstatat(arg1
, path(p
), &st
, arg4
));
7540 ret
= host_to_target_stat64(cpu_env
, arg3
, &st
);
7543 case TARGET_NR_lchown
:
7544 if (!(p
= lock_user_string(arg1
)))
7546 ret
= get_errno(lchown(p
, low2highuid(arg2
), low2highgid(arg3
)));
7547 unlock_user(p
, arg1
, 0);
7549 #ifdef TARGET_NR_getuid
7550 case TARGET_NR_getuid
:
7551 ret
= get_errno(high2lowuid(getuid()));
7554 #ifdef TARGET_NR_getgid
7555 case TARGET_NR_getgid
:
7556 ret
= get_errno(high2lowgid(getgid()));
7559 #ifdef TARGET_NR_geteuid
7560 case TARGET_NR_geteuid
:
7561 ret
= get_errno(high2lowuid(geteuid()));
7564 #ifdef TARGET_NR_getegid
7565 case TARGET_NR_getegid
:
7566 ret
= get_errno(high2lowgid(getegid()));
7569 case TARGET_NR_setreuid
:
7570 ret
= get_errno(setreuid(low2highuid(arg1
), low2highuid(arg2
)));
7572 case TARGET_NR_setregid
:
7573 ret
= get_errno(setregid(low2highgid(arg1
), low2highgid(arg2
)));
7575 case TARGET_NR_getgroups
:
7577 int gidsetsize
= arg1
;
7578 target_id
*target_grouplist
;
7582 grouplist
= alloca(gidsetsize
* sizeof(gid_t
));
7583 ret
= get_errno(getgroups(gidsetsize
, grouplist
));
7584 if (gidsetsize
== 0)
7586 if (!is_error(ret
)) {
7587 target_grouplist
= lock_user(VERIFY_WRITE
, arg2
, gidsetsize
* 2, 0);
7588 if (!target_grouplist
)
7590 for(i
= 0;i
< ret
; i
++)
7591 target_grouplist
[i
] = tswapid(high2lowgid(grouplist
[i
]));
7592 unlock_user(target_grouplist
, arg2
, gidsetsize
* 2);
7596 case TARGET_NR_setgroups
:
7598 int gidsetsize
= arg1
;
7599 target_id
*target_grouplist
;
7603 grouplist
= alloca(gidsetsize
* sizeof(gid_t
));
7604 target_grouplist
= lock_user(VERIFY_READ
, arg2
, gidsetsize
* 2, 1);
7605 if (!target_grouplist
) {
7606 ret
= -TARGET_EFAULT
;
7609 for(i
= 0;i
< gidsetsize
; i
++)
7610 grouplist
[i
] = low2highgid(tswapid(target_grouplist
[i
]));
7611 unlock_user(target_grouplist
, arg2
, 0);
7612 ret
= get_errno(setgroups(gidsetsize
, grouplist
));
7615 case TARGET_NR_fchown
:
7616 ret
= get_errno(fchown(arg1
, low2highuid(arg2
), low2highgid(arg3
)));
7618 #if defined(TARGET_NR_fchownat) && defined(__NR_fchownat)
7619 case TARGET_NR_fchownat
:
7620 if (!(p
= lock_user_string(arg2
)))
7622 ret
= get_errno(sys_fchownat(arg1
, p
, low2highuid(arg3
), low2highgid(arg4
), arg5
));
7623 unlock_user(p
, arg2
, 0);
7626 #ifdef TARGET_NR_setresuid
7627 case TARGET_NR_setresuid
:
7628 ret
= get_errno(setresuid(low2highuid(arg1
),
7630 low2highuid(arg3
)));
7633 #ifdef TARGET_NR_getresuid
7634 case TARGET_NR_getresuid
:
7636 uid_t ruid
, euid
, suid
;
7637 ret
= get_errno(getresuid(&ruid
, &euid
, &suid
));
7638 if (!is_error(ret
)) {
7639 if (put_user_u16(high2lowuid(ruid
), arg1
)
7640 || put_user_u16(high2lowuid(euid
), arg2
)
7641 || put_user_u16(high2lowuid(suid
), arg3
))
7647 #ifdef TARGET_NR_getresgid
7648 case TARGET_NR_setresgid
:
7649 ret
= get_errno(setresgid(low2highgid(arg1
),
7651 low2highgid(arg3
)));
7654 #ifdef TARGET_NR_getresgid
7655 case TARGET_NR_getresgid
:
7657 gid_t rgid
, egid
, sgid
;
7658 ret
= get_errno(getresgid(&rgid
, &egid
, &sgid
));
7659 if (!is_error(ret
)) {
7660 if (put_user_u16(high2lowgid(rgid
), arg1
)
7661 || put_user_u16(high2lowgid(egid
), arg2
)
7662 || put_user_u16(high2lowgid(sgid
), arg3
))
7668 case TARGET_NR_chown
:
7669 if (!(p
= lock_user_string(arg1
)))
7671 ret
= get_errno(chown(p
, low2highuid(arg2
), low2highgid(arg3
)));
7672 unlock_user(p
, arg1
, 0);
7674 case TARGET_NR_setuid
:
7675 ret
= get_errno(setuid(low2highuid(arg1
)));
7677 case TARGET_NR_setgid
:
7678 ret
= get_errno(setgid(low2highgid(arg1
)));
7680 case TARGET_NR_setfsuid
:
7681 ret
= get_errno(setfsuid(arg1
));
7683 case TARGET_NR_setfsgid
:
7684 ret
= get_errno(setfsgid(arg1
));
7687 #ifdef TARGET_NR_lchown32
7688 case TARGET_NR_lchown32
:
7689 if (!(p
= lock_user_string(arg1
)))
7691 ret
= get_errno(lchown(p
, arg2
, arg3
));
7692 unlock_user(p
, arg1
, 0);
7695 #ifdef TARGET_NR_getuid32
7696 case TARGET_NR_getuid32
:
7697 ret
= get_errno(getuid());
7701 #if defined(TARGET_NR_getxuid) && defined(TARGET_ALPHA)
7702 /* Alpha specific */
7703 case TARGET_NR_getxuid
:
7707 ((CPUAlphaState
*)cpu_env
)->ir
[IR_A4
]=euid
;
7709 ret
= get_errno(getuid());
7712 #if defined(TARGET_NR_getxgid) && defined(TARGET_ALPHA)
7713 /* Alpha specific */
7714 case TARGET_NR_getxgid
:
7718 ((CPUAlphaState
*)cpu_env
)->ir
[IR_A4
]=egid
;
7720 ret
= get_errno(getgid());
7723 #if defined(TARGET_NR_osf_getsysinfo) && defined(TARGET_ALPHA)
7724 /* Alpha specific */
7725 case TARGET_NR_osf_getsysinfo
:
7726 ret
= -TARGET_EOPNOTSUPP
;
7728 case TARGET_GSI_IEEE_FP_CONTROL
:
7730 uint64_t swcr
, fpcr
= cpu_alpha_load_fpcr (cpu_env
);
7732 /* Copied from linux ieee_fpcr_to_swcr. */
7733 swcr
= (fpcr
>> 35) & SWCR_STATUS_MASK
;
7734 swcr
|= (fpcr
>> 36) & SWCR_MAP_DMZ
;
7735 swcr
|= (~fpcr
>> 48) & (SWCR_TRAP_ENABLE_INV
7736 | SWCR_TRAP_ENABLE_DZE
7737 | SWCR_TRAP_ENABLE_OVF
);
7738 swcr
|= (~fpcr
>> 57) & (SWCR_TRAP_ENABLE_UNF
7739 | SWCR_TRAP_ENABLE_INE
);
7740 swcr
|= (fpcr
>> 47) & SWCR_MAP_UMZ
;
7741 swcr
|= (~fpcr
>> 41) & SWCR_TRAP_ENABLE_DNO
;
7743 if (put_user_u64 (swcr
, arg2
))
7749 /* case GSI_IEEE_STATE_AT_SIGNAL:
7750 -- Not implemented in linux kernel.
7752 -- Retrieves current unaligned access state; not much used.
7754 -- Retrieves implver information; surely not used.
7756 -- Grabs a copy of the HWRPB; surely not used.
7761 #if defined(TARGET_NR_osf_setsysinfo) && defined(TARGET_ALPHA)
7762 /* Alpha specific */
7763 case TARGET_NR_osf_setsysinfo
:
7764 ret
= -TARGET_EOPNOTSUPP
;
7766 case TARGET_SSI_IEEE_FP_CONTROL
:
7768 uint64_t swcr
, fpcr
, orig_fpcr
;
7770 if (get_user_u64 (swcr
, arg2
)) {
7773 orig_fpcr
= cpu_alpha_load_fpcr(cpu_env
);
7774 fpcr
= orig_fpcr
& FPCR_DYN_MASK
;
7776 /* Copied from linux ieee_swcr_to_fpcr. */
7777 fpcr
|= (swcr
& SWCR_STATUS_MASK
) << 35;
7778 fpcr
|= (swcr
& SWCR_MAP_DMZ
) << 36;
7779 fpcr
|= (~swcr
& (SWCR_TRAP_ENABLE_INV
7780 | SWCR_TRAP_ENABLE_DZE
7781 | SWCR_TRAP_ENABLE_OVF
)) << 48;
7782 fpcr
|= (~swcr
& (SWCR_TRAP_ENABLE_UNF
7783 | SWCR_TRAP_ENABLE_INE
)) << 57;
7784 fpcr
|= (swcr
& SWCR_MAP_UMZ
? FPCR_UNDZ
| FPCR_UNFD
: 0);
7785 fpcr
|= (~swcr
& SWCR_TRAP_ENABLE_DNO
) << 41;
7787 cpu_alpha_store_fpcr(cpu_env
, fpcr
);
7792 case TARGET_SSI_IEEE_RAISE_EXCEPTION
:
7794 uint64_t exc
, fpcr
, orig_fpcr
;
7797 if (get_user_u64(exc
, arg2
)) {
7801 orig_fpcr
= cpu_alpha_load_fpcr(cpu_env
);
7803 /* We only add to the exception status here. */
7804 fpcr
= orig_fpcr
| ((exc
& SWCR_STATUS_MASK
) << 35);
7806 cpu_alpha_store_fpcr(cpu_env
, fpcr
);
7809 /* Old exceptions are not signaled. */
7810 fpcr
&= ~(orig_fpcr
& FPCR_STATUS_MASK
);
7812 /* If any exceptions set by this call,
7813 and are unmasked, send a signal. */
7815 if ((fpcr
& (FPCR_INE
| FPCR_INED
)) == FPCR_INE
) {
7816 si_code
= TARGET_FPE_FLTRES
;
7818 if ((fpcr
& (FPCR_UNF
| FPCR_UNFD
)) == FPCR_UNF
) {
7819 si_code
= TARGET_FPE_FLTUND
;
7821 if ((fpcr
& (FPCR_OVF
| FPCR_OVFD
)) == FPCR_OVF
) {
7822 si_code
= TARGET_FPE_FLTOVF
;
7824 if ((fpcr
& (FPCR_DZE
| FPCR_DZED
)) == FPCR_DZE
) {
7825 si_code
= TARGET_FPE_FLTDIV
;
7827 if ((fpcr
& (FPCR_INV
| FPCR_INVD
)) == FPCR_INV
) {
7828 si_code
= TARGET_FPE_FLTINV
;
7831 target_siginfo_t info
;
7832 info
.si_signo
= SIGFPE
;
7834 info
.si_code
= si_code
;
7835 info
._sifields
._sigfault
._addr
7836 = ((CPUArchState
*)cpu_env
)->pc
;
7837 queue_signal((CPUArchState
*)cpu_env
, info
.si_signo
, &info
);
7842 /* case SSI_NVPAIRS:
7843 -- Used with SSIN_UACPROC to enable unaligned accesses.
7844 case SSI_IEEE_STATE_AT_SIGNAL:
7845 case SSI_IEEE_IGNORE_STATE_AT_SIGNAL:
7846 -- Not implemented in linux kernel
7851 #ifdef TARGET_NR_osf_sigprocmask
7852 /* Alpha specific. */
7853 case TARGET_NR_osf_sigprocmask
:
7857 sigset_t set
, oldset
;
7860 case TARGET_SIG_BLOCK
:
7863 case TARGET_SIG_UNBLOCK
:
7866 case TARGET_SIG_SETMASK
:
7870 ret
= -TARGET_EINVAL
;
7874 target_to_host_old_sigset(&set
, &mask
);
7875 sigprocmask(how
, &set
, &oldset
);
7876 host_to_target_old_sigset(&mask
, &oldset
);
7882 #ifdef TARGET_NR_getgid32
7883 case TARGET_NR_getgid32
:
7884 ret
= get_errno(getgid());
7887 #ifdef TARGET_NR_geteuid32
7888 case TARGET_NR_geteuid32
:
7889 ret
= get_errno(geteuid());
7892 #ifdef TARGET_NR_getegid32
7893 case TARGET_NR_getegid32
:
7894 ret
= get_errno(getegid());
7897 #ifdef TARGET_NR_setreuid32
7898 case TARGET_NR_setreuid32
:
7899 ret
= get_errno(setreuid(arg1
, arg2
));
7902 #ifdef TARGET_NR_setregid32
7903 case TARGET_NR_setregid32
:
7904 ret
= get_errno(setregid(arg1
, arg2
));
7907 #ifdef TARGET_NR_getgroups32
7908 case TARGET_NR_getgroups32
:
7910 int gidsetsize
= arg1
;
7911 uint32_t *target_grouplist
;
7915 grouplist
= alloca(gidsetsize
* sizeof(gid_t
));
7916 ret
= get_errno(getgroups(gidsetsize
, grouplist
));
7917 if (gidsetsize
== 0)
7919 if (!is_error(ret
)) {
7920 target_grouplist
= lock_user(VERIFY_WRITE
, arg2
, gidsetsize
* 4, 0);
7921 if (!target_grouplist
) {
7922 ret
= -TARGET_EFAULT
;
7925 for(i
= 0;i
< ret
; i
++)
7926 target_grouplist
[i
] = tswap32(grouplist
[i
]);
7927 unlock_user(target_grouplist
, arg2
, gidsetsize
* 4);
7932 #ifdef TARGET_NR_setgroups32
7933 case TARGET_NR_setgroups32
:
7935 int gidsetsize
= arg1
;
7936 uint32_t *target_grouplist
;
7940 grouplist
= alloca(gidsetsize
* sizeof(gid_t
));
7941 target_grouplist
= lock_user(VERIFY_READ
, arg2
, gidsetsize
* 4, 1);
7942 if (!target_grouplist
) {
7943 ret
= -TARGET_EFAULT
;
7946 for(i
= 0;i
< gidsetsize
; i
++)
7947 grouplist
[i
] = tswap32(target_grouplist
[i
]);
7948 unlock_user(target_grouplist
, arg2
, 0);
7949 ret
= get_errno(setgroups(gidsetsize
, grouplist
));
7953 #ifdef TARGET_NR_fchown32
7954 case TARGET_NR_fchown32
:
7955 ret
= get_errno(fchown(arg1
, arg2
, arg3
));
7958 #ifdef TARGET_NR_setresuid32
7959 case TARGET_NR_setresuid32
:
7960 ret
= get_errno(setresuid(arg1
, arg2
, arg3
));
7963 #ifdef TARGET_NR_getresuid32
7964 case TARGET_NR_getresuid32
:
7966 uid_t ruid
, euid
, suid
;
7967 ret
= get_errno(getresuid(&ruid
, &euid
, &suid
));
7968 if (!is_error(ret
)) {
7969 if (put_user_u32(ruid
, arg1
)
7970 || put_user_u32(euid
, arg2
)
7971 || put_user_u32(suid
, arg3
))
7977 #ifdef TARGET_NR_setresgid32
7978 case TARGET_NR_setresgid32
:
7979 ret
= get_errno(setresgid(arg1
, arg2
, arg3
));
7982 #ifdef TARGET_NR_getresgid32
7983 case TARGET_NR_getresgid32
:
7985 gid_t rgid
, egid
, sgid
;
7986 ret
= get_errno(getresgid(&rgid
, &egid
, &sgid
));
7987 if (!is_error(ret
)) {
7988 if (put_user_u32(rgid
, arg1
)
7989 || put_user_u32(egid
, arg2
)
7990 || put_user_u32(sgid
, arg3
))
7996 #ifdef TARGET_NR_chown32
7997 case TARGET_NR_chown32
:
7998 if (!(p
= lock_user_string(arg1
)))
8000 ret
= get_errno(chown(p
, arg2
, arg3
));
8001 unlock_user(p
, arg1
, 0);
8004 #ifdef TARGET_NR_setuid32
8005 case TARGET_NR_setuid32
:
8006 ret
= get_errno(setuid(arg1
));
8009 #ifdef TARGET_NR_setgid32
8010 case TARGET_NR_setgid32
:
8011 ret
= get_errno(setgid(arg1
));
8014 #ifdef TARGET_NR_setfsuid32
8015 case TARGET_NR_setfsuid32
:
8016 ret
= get_errno(setfsuid(arg1
));
8019 #ifdef TARGET_NR_setfsgid32
8020 case TARGET_NR_setfsgid32
:
8021 ret
= get_errno(setfsgid(arg1
));
8025 case TARGET_NR_pivot_root
:
8027 #ifdef TARGET_NR_mincore
8028 case TARGET_NR_mincore
:
8031 ret
= -TARGET_EFAULT
;
8032 if (!(a
= lock_user(VERIFY_READ
, arg1
,arg2
, 0)))
8034 if (!(p
= lock_user_string(arg3
)))
8036 ret
= get_errno(mincore(a
, arg2
, p
));
8037 unlock_user(p
, arg3
, ret
);
8039 unlock_user(a
, arg1
, 0);
8043 #ifdef TARGET_NR_arm_fadvise64_64
8044 case TARGET_NR_arm_fadvise64_64
:
8047 * arm_fadvise64_64 looks like fadvise64_64 but
8048 * with different argument order
8056 #if defined(TARGET_NR_fadvise64_64) || defined(TARGET_NR_arm_fadvise64_64) || defined(TARGET_NR_fadvise64)
8057 #ifdef TARGET_NR_fadvise64_64
8058 case TARGET_NR_fadvise64_64
:
8060 #ifdef TARGET_NR_fadvise64
8061 case TARGET_NR_fadvise64
:
8065 case 4: arg4
= POSIX_FADV_NOREUSE
+ 1; break; /* make sure it's an invalid value */
8066 case 5: arg4
= POSIX_FADV_NOREUSE
+ 2; break; /* ditto */
8067 case 6: arg4
= POSIX_FADV_DONTNEED
; break;
8068 case 7: arg4
= POSIX_FADV_NOREUSE
; break;
8072 ret
= -posix_fadvise(arg1
, arg2
, arg3
, arg4
);
8075 #ifdef TARGET_NR_madvise
8076 case TARGET_NR_madvise
:
8077 /* A straight passthrough may not be safe because qemu sometimes
8078 turns private flie-backed mappings into anonymous mappings.
8079 This will break MADV_DONTNEED.
8080 This is a hint, so ignoring and returning success is ok. */
8084 #if TARGET_ABI_BITS == 32
8085 case TARGET_NR_fcntl64
:
8089 struct target_flock64
*target_fl
;
8091 struct target_eabi_flock64
*target_efl
;
8094 cmd
= target_to_host_fcntl_cmd(arg2
);
8095 if (cmd
== -TARGET_EINVAL
) {
8101 case TARGET_F_GETLK64
:
8103 if (((CPUARMState
*)cpu_env
)->eabi
) {
8104 if (!lock_user_struct(VERIFY_READ
, target_efl
, arg3
, 1))
8106 fl
.l_type
= tswap16(target_efl
->l_type
);
8107 fl
.l_whence
= tswap16(target_efl
->l_whence
);
8108 fl
.l_start
= tswap64(target_efl
->l_start
);
8109 fl
.l_len
= tswap64(target_efl
->l_len
);
8110 fl
.l_pid
= tswap32(target_efl
->l_pid
);
8111 unlock_user_struct(target_efl
, arg3
, 0);
8115 if (!lock_user_struct(VERIFY_READ
, target_fl
, arg3
, 1))
8117 fl
.l_type
= tswap16(target_fl
->l_type
);
8118 fl
.l_whence
= tswap16(target_fl
->l_whence
);
8119 fl
.l_start
= tswap64(target_fl
->l_start
);
8120 fl
.l_len
= tswap64(target_fl
->l_len
);
8121 fl
.l_pid
= tswap32(target_fl
->l_pid
);
8122 unlock_user_struct(target_fl
, arg3
, 0);
8124 ret
= get_errno(fcntl(arg1
, cmd
, &fl
));
8127 if (((CPUARMState
*)cpu_env
)->eabi
) {
8128 if (!lock_user_struct(VERIFY_WRITE
, target_efl
, arg3
, 0))
8130 target_efl
->l_type
= tswap16(fl
.l_type
);
8131 target_efl
->l_whence
= tswap16(fl
.l_whence
);
8132 target_efl
->l_start
= tswap64(fl
.l_start
);
8133 target_efl
->l_len
= tswap64(fl
.l_len
);
8134 target_efl
->l_pid
= tswap32(fl
.l_pid
);
8135 unlock_user_struct(target_efl
, arg3
, 1);
8139 if (!lock_user_struct(VERIFY_WRITE
, target_fl
, arg3
, 0))
8141 target_fl
->l_type
= tswap16(fl
.l_type
);
8142 target_fl
->l_whence
= tswap16(fl
.l_whence
);
8143 target_fl
->l_start
= tswap64(fl
.l_start
);
8144 target_fl
->l_len
= tswap64(fl
.l_len
);
8145 target_fl
->l_pid
= tswap32(fl
.l_pid
);
8146 unlock_user_struct(target_fl
, arg3
, 1);
8151 case TARGET_F_SETLK64
:
8152 case TARGET_F_SETLKW64
:
8154 if (((CPUARMState
*)cpu_env
)->eabi
) {
8155 if (!lock_user_struct(VERIFY_READ
, target_efl
, arg3
, 1))
8157 fl
.l_type
= tswap16(target_efl
->l_type
);
8158 fl
.l_whence
= tswap16(target_efl
->l_whence
);
8159 fl
.l_start
= tswap64(target_efl
->l_start
);
8160 fl
.l_len
= tswap64(target_efl
->l_len
);
8161 fl
.l_pid
= tswap32(target_efl
->l_pid
);
8162 unlock_user_struct(target_efl
, arg3
, 0);
8166 if (!lock_user_struct(VERIFY_READ
, target_fl
, arg3
, 1))
8168 fl
.l_type
= tswap16(target_fl
->l_type
);
8169 fl
.l_whence
= tswap16(target_fl
->l_whence
);
8170 fl
.l_start
= tswap64(target_fl
->l_start
);
8171 fl
.l_len
= tswap64(target_fl
->l_len
);
8172 fl
.l_pid
= tswap32(target_fl
->l_pid
);
8173 unlock_user_struct(target_fl
, arg3
, 0);
8175 ret
= get_errno(fcntl(arg1
, cmd
, &fl
));
8178 ret
= do_fcntl(arg1
, arg2
, arg3
);
8184 #ifdef TARGET_NR_cacheflush
8185 case TARGET_NR_cacheflush
:
8186 /* self-modifying code is handled automatically, so nothing needed */
8190 #ifdef TARGET_NR_security
8191 case TARGET_NR_security
:
8194 #ifdef TARGET_NR_getpagesize
8195 case TARGET_NR_getpagesize
:
8196 ret
= TARGET_PAGE_SIZE
;
8199 case TARGET_NR_gettid
:
8200 ret
= get_errno(gettid());
8202 #ifdef TARGET_NR_readahead
8203 case TARGET_NR_readahead
:
8204 #if TARGET_ABI_BITS == 32
8205 if (regpairs_aligned(cpu_env
)) {
8210 ret
= get_errno(readahead(arg1
, ((off64_t
)arg3
<< 32) | arg2
, arg4
));
8212 ret
= get_errno(readahead(arg1
, arg2
, arg3
));
8217 #ifdef TARGET_NR_setxattr
8218 case TARGET_NR_listxattr
:
8219 case TARGET_NR_llistxattr
:
8223 b
= lock_user(VERIFY_WRITE
, arg2
, arg3
, 0);
8225 ret
= -TARGET_EFAULT
;
8229 p
= lock_user_string(arg1
);
8231 if (num
== TARGET_NR_listxattr
) {
8232 ret
= get_errno(listxattr(p
, b
, arg3
));
8234 ret
= get_errno(llistxattr(p
, b
, arg3
));
8237 ret
= -TARGET_EFAULT
;
8239 unlock_user(p
, arg1
, 0);
8240 unlock_user(b
, arg2
, arg3
);
8243 case TARGET_NR_flistxattr
:
8247 b
= lock_user(VERIFY_WRITE
, arg2
, arg3
, 0);
8249 ret
= -TARGET_EFAULT
;
8253 ret
= get_errno(flistxattr(arg1
, b
, arg3
));
8254 unlock_user(b
, arg2
, arg3
);
8257 case TARGET_NR_setxattr
:
8258 case TARGET_NR_lsetxattr
:
8260 void *p
, *n
, *v
= 0;
8262 v
= lock_user(VERIFY_READ
, arg3
, arg4
, 1);
8264 ret
= -TARGET_EFAULT
;
8268 p
= lock_user_string(arg1
);
8269 n
= lock_user_string(arg2
);
8271 if (num
== TARGET_NR_setxattr
) {
8272 ret
= get_errno(setxattr(p
, n
, v
, arg4
, arg5
));
8274 ret
= get_errno(lsetxattr(p
, n
, v
, arg4
, arg5
));
8277 ret
= -TARGET_EFAULT
;
8279 unlock_user(p
, arg1
, 0);
8280 unlock_user(n
, arg2
, 0);
8281 unlock_user(v
, arg3
, 0);
8284 case TARGET_NR_fsetxattr
:
8288 v
= lock_user(VERIFY_READ
, arg3
, arg4
, 1);
8290 ret
= -TARGET_EFAULT
;
8294 n
= lock_user_string(arg2
);
8296 ret
= get_errno(fsetxattr(arg1
, n
, v
, arg4
, arg5
));
8298 ret
= -TARGET_EFAULT
;
8300 unlock_user(n
, arg2
, 0);
8301 unlock_user(v
, arg3
, 0);
8304 case TARGET_NR_getxattr
:
8305 case TARGET_NR_lgetxattr
:
8307 void *p
, *n
, *v
= 0;
8309 v
= lock_user(VERIFY_WRITE
, arg3
, arg4
, 0);
8311 ret
= -TARGET_EFAULT
;
8315 p
= lock_user_string(arg1
);
8316 n
= lock_user_string(arg2
);
8318 if (num
== TARGET_NR_getxattr
) {
8319 ret
= get_errno(getxattr(p
, n
, v
, arg4
));
8321 ret
= get_errno(lgetxattr(p
, n
, v
, arg4
));
8324 ret
= -TARGET_EFAULT
;
8326 unlock_user(p
, arg1
, 0);
8327 unlock_user(n
, arg2
, 0);
8328 unlock_user(v
, arg3
, arg4
);
8331 case TARGET_NR_fgetxattr
:
8335 v
= lock_user(VERIFY_WRITE
, arg3
, arg4
, 0);
8337 ret
= -TARGET_EFAULT
;
8341 n
= lock_user_string(arg2
);
8343 ret
= get_errno(fgetxattr(arg1
, n
, v
, arg4
));
8345 ret
= -TARGET_EFAULT
;
8347 unlock_user(n
, arg2
, 0);
8348 unlock_user(v
, arg3
, arg4
);
8351 case TARGET_NR_removexattr
:
8352 case TARGET_NR_lremovexattr
:
8355 p
= lock_user_string(arg1
);
8356 n
= lock_user_string(arg2
);
8358 if (num
== TARGET_NR_removexattr
) {
8359 ret
= get_errno(removexattr(p
, n
));
8361 ret
= get_errno(lremovexattr(p
, n
));
8364 ret
= -TARGET_EFAULT
;
8366 unlock_user(p
, arg1
, 0);
8367 unlock_user(n
, arg2
, 0);
8370 case TARGET_NR_fremovexattr
:
8373 n
= lock_user_string(arg2
);
8375 ret
= get_errno(fremovexattr(arg1
, n
));
8377 ret
= -TARGET_EFAULT
;
8379 unlock_user(n
, arg2
, 0);
8383 #endif /* CONFIG_ATTR */
8384 #ifdef TARGET_NR_set_thread_area
8385 case TARGET_NR_set_thread_area
:
8386 #if defined(TARGET_MIPS)
8387 ((CPUMIPSState
*) cpu_env
)->tls_value
= arg1
;
8390 #elif defined(TARGET_CRIS)
8392 ret
= -TARGET_EINVAL
;
8394 ((CPUCRISState
*) cpu_env
)->pregs
[PR_PID
] = arg1
;
8398 #elif defined(TARGET_I386) && defined(TARGET_ABI32)
8399 ret
= do_set_thread_area(cpu_env
, arg1
);
8402 goto unimplemented_nowarn
;
8405 #ifdef TARGET_NR_get_thread_area
8406 case TARGET_NR_get_thread_area
:
8407 #if defined(TARGET_I386) && defined(TARGET_ABI32)
8408 ret
= do_get_thread_area(cpu_env
, arg1
);
8410 goto unimplemented_nowarn
;
8413 #ifdef TARGET_NR_getdomainname
8414 case TARGET_NR_getdomainname
:
8415 goto unimplemented_nowarn
;
8418 #ifdef TARGET_NR_clock_gettime
8419 case TARGET_NR_clock_gettime
:
8422 ret
= get_errno(clock_gettime(arg1
, &ts
));
8423 if (!is_error(ret
)) {
8424 host_to_target_timespec(arg2
, &ts
);
8429 #ifdef TARGET_NR_clock_getres
8430 case TARGET_NR_clock_getres
:
8433 ret
= get_errno(clock_getres(arg1
, &ts
));
8434 if (!is_error(ret
)) {
8435 host_to_target_timespec(arg2
, &ts
);
8440 #ifdef TARGET_NR_clock_nanosleep
8441 case TARGET_NR_clock_nanosleep
:
8444 target_to_host_timespec(&ts
, arg3
);
8445 ret
= get_errno(clock_nanosleep(arg1
, arg2
, &ts
, arg4
? &ts
: NULL
));
8447 host_to_target_timespec(arg4
, &ts
);
8452 #if defined(TARGET_NR_set_tid_address) && defined(__NR_set_tid_address)
8453 case TARGET_NR_set_tid_address
:
8454 ret
= get_errno(set_tid_address((int *)g2h(arg1
)));
8458 #if defined(TARGET_NR_tkill) && defined(__NR_tkill)
8459 case TARGET_NR_tkill
:
8460 ret
= get_errno(sys_tkill((int)arg1
, target_to_host_signal(arg2
)));
8464 #if defined(TARGET_NR_tgkill) && defined(__NR_tgkill)
8465 case TARGET_NR_tgkill
:
8466 ret
= get_errno(sys_tgkill((int)arg1
, (int)arg2
,
8467 target_to_host_signal(arg3
)));
8471 #ifdef TARGET_NR_set_robust_list
8472 case TARGET_NR_set_robust_list
:
8473 goto unimplemented_nowarn
;
8476 #if defined(TARGET_NR_utimensat) && defined(__NR_utimensat)
8477 case TARGET_NR_utimensat
:
8479 struct timespec
*tsp
, ts
[2];
8483 target_to_host_timespec(ts
, arg3
);
8484 target_to_host_timespec(ts
+1, arg3
+sizeof(struct target_timespec
));
8488 ret
= get_errno(sys_utimensat(arg1
, NULL
, tsp
, arg4
));
8490 if (!(p
= lock_user_string(arg2
))) {
8491 ret
= -TARGET_EFAULT
;
8494 ret
= get_errno(sys_utimensat(arg1
, path(p
), tsp
, arg4
));
8495 unlock_user(p
, arg2
, 0);
8500 #if defined(CONFIG_USE_NPTL)
8501 case TARGET_NR_futex
:
8502 ret
= do_futex(arg1
, arg2
, arg3
, arg4
, arg5
, arg6
);
8505 #if defined(TARGET_NR_inotify_init) && defined(__NR_inotify_init)
8506 case TARGET_NR_inotify_init
:
8507 ret
= get_errno(sys_inotify_init());
8510 #ifdef CONFIG_INOTIFY1
8511 #if defined(TARGET_NR_inotify_init1) && defined(__NR_inotify_init1)
8512 case TARGET_NR_inotify_init1
:
8513 ret
= get_errno(sys_inotify_init1(arg1
));
8517 #if defined(TARGET_NR_inotify_add_watch) && defined(__NR_inotify_add_watch)
8518 case TARGET_NR_inotify_add_watch
:
8519 p
= lock_user_string(arg2
);
8520 ret
= get_errno(sys_inotify_add_watch(arg1
, path(p
), arg3
));
8521 unlock_user(p
, arg2
, 0);
8524 #if defined(TARGET_NR_inotify_rm_watch) && defined(__NR_inotify_rm_watch)
8525 case TARGET_NR_inotify_rm_watch
:
8526 ret
= get_errno(sys_inotify_rm_watch(arg1
, arg2
));
8530 #if defined(TARGET_NR_mq_open) && defined(__NR_mq_open)
8531 case TARGET_NR_mq_open
:
8533 struct mq_attr posix_mq_attr
;
8535 p
= lock_user_string(arg1
- 1);
8537 copy_from_user_mq_attr (&posix_mq_attr
, arg4
);
8538 ret
= get_errno(mq_open(p
, arg2
, arg3
, &posix_mq_attr
));
8539 unlock_user (p
, arg1
, 0);
8543 case TARGET_NR_mq_unlink
:
8544 p
= lock_user_string(arg1
- 1);
8545 ret
= get_errno(mq_unlink(p
));
8546 unlock_user (p
, arg1
, 0);
8549 case TARGET_NR_mq_timedsend
:
8553 p
= lock_user (VERIFY_READ
, arg2
, arg3
, 1);
8555 target_to_host_timespec(&ts
, arg5
);
8556 ret
= get_errno(mq_timedsend(arg1
, p
, arg3
, arg4
, &ts
));
8557 host_to_target_timespec(arg5
, &ts
);
8560 ret
= get_errno(mq_send(arg1
, p
, arg3
, arg4
));
8561 unlock_user (p
, arg2
, arg3
);
8565 case TARGET_NR_mq_timedreceive
:
8570 p
= lock_user (VERIFY_READ
, arg2
, arg3
, 1);
8572 target_to_host_timespec(&ts
, arg5
);
8573 ret
= get_errno(mq_timedreceive(arg1
, p
, arg3
, &prio
, &ts
));
8574 host_to_target_timespec(arg5
, &ts
);
8577 ret
= get_errno(mq_receive(arg1
, p
, arg3
, &prio
));
8578 unlock_user (p
, arg2
, arg3
);
8580 put_user_u32(prio
, arg4
);
8584 /* Not implemented for now... */
8585 /* case TARGET_NR_mq_notify: */
8588 case TARGET_NR_mq_getsetattr
:
8590 struct mq_attr posix_mq_attr_in
, posix_mq_attr_out
;
8593 ret
= mq_getattr(arg1
, &posix_mq_attr_out
);
8594 copy_to_user_mq_attr(arg3
, &posix_mq_attr_out
);
8597 copy_from_user_mq_attr(&posix_mq_attr_in
, arg2
);
8598 ret
|= mq_setattr(arg1
, &posix_mq_attr_in
, &posix_mq_attr_out
);
8605 #ifdef CONFIG_SPLICE
8606 #ifdef TARGET_NR_tee
8609 ret
= get_errno(tee(arg1
,arg2
,arg3
,arg4
));
8613 #ifdef TARGET_NR_splice
8614 case TARGET_NR_splice
:
8616 loff_t loff_in
, loff_out
;
8617 loff_t
*ploff_in
= NULL
, *ploff_out
= NULL
;
8619 get_user_u64(loff_in
, arg2
);
8620 ploff_in
= &loff_in
;
8623 get_user_u64(loff_out
, arg2
);
8624 ploff_out
= &loff_out
;
8626 ret
= get_errno(splice(arg1
, ploff_in
, arg3
, ploff_out
, arg5
, arg6
));
8630 #ifdef TARGET_NR_vmsplice
8631 case TARGET_NR_vmsplice
:
8636 vec
= alloca(count
* sizeof(struct iovec
));
8637 if (lock_iovec(VERIFY_READ
, vec
, arg2
, count
, 1) < 0)
8639 ret
= get_errno(vmsplice(arg1
, vec
, count
, arg4
));
8640 unlock_iovec(vec
, arg2
, count
, 0);
8644 #endif /* CONFIG_SPLICE */
8645 #ifdef CONFIG_EVENTFD
8646 #if defined(TARGET_NR_eventfd)
8647 case TARGET_NR_eventfd
:
8648 ret
= get_errno(eventfd(arg1
, 0));
8651 #if defined(TARGET_NR_eventfd2)
8652 case TARGET_NR_eventfd2
:
8653 ret
= get_errno(eventfd(arg1
, arg2
));
8656 #endif /* CONFIG_EVENTFD */
8657 #if defined(CONFIG_FALLOCATE) && defined(TARGET_NR_fallocate)
8658 case TARGET_NR_fallocate
:
8659 #if TARGET_ABI_BITS == 32
8660 ret
= get_errno(fallocate(arg1
, arg2
, target_offset64(arg3
, arg4
),
8661 target_offset64(arg5
, arg6
)));
8663 ret
= get_errno(fallocate(arg1
, arg2
, arg3
, arg4
));
8667 #if defined(CONFIG_SYNC_FILE_RANGE)
8668 #if defined(TARGET_NR_sync_file_range)
8669 case TARGET_NR_sync_file_range
:
8670 #if TARGET_ABI_BITS == 32
8671 #if defined(TARGET_MIPS)
8672 ret
= get_errno(sync_file_range(arg1
, target_offset64(arg3
, arg4
),
8673 target_offset64(arg5
, arg6
), arg7
));
8675 ret
= get_errno(sync_file_range(arg1
, target_offset64(arg2
, arg3
),
8676 target_offset64(arg4
, arg5
), arg6
));
8677 #endif /* !TARGET_MIPS */
8679 ret
= get_errno(sync_file_range(arg1
, arg2
, arg3
, arg4
));
8683 #if defined(TARGET_NR_sync_file_range2)
8684 case TARGET_NR_sync_file_range2
:
8685 /* This is like sync_file_range but the arguments are reordered */
8686 #if TARGET_ABI_BITS == 32
8687 ret
= get_errno(sync_file_range(arg1
, target_offset64(arg3
, arg4
),
8688 target_offset64(arg5
, arg6
), arg2
));
8690 ret
= get_errno(sync_file_range(arg1
, arg3
, arg4
, arg2
));
8695 #if defined(CONFIG_EPOLL)
8696 #if defined(TARGET_NR_epoll_create)
8697 case TARGET_NR_epoll_create
:
8698 ret
= get_errno(epoll_create(arg1
));
8701 #if defined(TARGET_NR_epoll_create1) && defined(CONFIG_EPOLL_CREATE1)
8702 case TARGET_NR_epoll_create1
:
8703 ret
= get_errno(epoll_create1(arg1
));
8706 #if defined(TARGET_NR_epoll_ctl)
8707 case TARGET_NR_epoll_ctl
:
8709 struct epoll_event ep
;
8710 struct epoll_event
*epp
= 0;
8712 struct target_epoll_event
*target_ep
;
8713 if (!lock_user_struct(VERIFY_READ
, target_ep
, arg4
, 1)) {
8716 ep
.events
= tswap32(target_ep
->events
);
8717 /* The epoll_data_t union is just opaque data to the kernel,
8718 * so we transfer all 64 bits across and need not worry what
8719 * actual data type it is.
8721 ep
.data
.u64
= tswap64(target_ep
->data
.u64
);
8722 unlock_user_struct(target_ep
, arg4
, 0);
8725 ret
= get_errno(epoll_ctl(arg1
, arg2
, arg3
, epp
));
8730 #if defined(TARGET_NR_epoll_pwait) && defined(CONFIG_EPOLL_PWAIT)
8731 #define IMPLEMENT_EPOLL_PWAIT
8733 #if defined(TARGET_NR_epoll_wait) || defined(IMPLEMENT_EPOLL_PWAIT)
8734 #if defined(TARGET_NR_epoll_wait)
8735 case TARGET_NR_epoll_wait
:
8737 #if defined(IMPLEMENT_EPOLL_PWAIT)
8738 case TARGET_NR_epoll_pwait
:
8741 struct target_epoll_event
*target_ep
;
8742 struct epoll_event
*ep
;
8744 int maxevents
= arg3
;
8747 target_ep
= lock_user(VERIFY_WRITE
, arg2
,
8748 maxevents
* sizeof(struct target_epoll_event
), 1);
8753 ep
= alloca(maxevents
* sizeof(struct epoll_event
));
8756 #if defined(IMPLEMENT_EPOLL_PWAIT)
8757 case TARGET_NR_epoll_pwait
:
8759 target_sigset_t
*target_set
;
8760 sigset_t _set
, *set
= &_set
;
8763 target_set
= lock_user(VERIFY_READ
, arg5
,
8764 sizeof(target_sigset_t
), 1);
8766 unlock_user(target_ep
, arg2
, 0);
8769 target_to_host_sigset(set
, target_set
);
8770 unlock_user(target_set
, arg5
, 0);
8775 ret
= get_errno(epoll_pwait(epfd
, ep
, maxevents
, timeout
, set
));
8779 #if defined(TARGET_NR_epoll_wait)
8780 case TARGET_NR_epoll_wait
:
8781 ret
= get_errno(epoll_wait(epfd
, ep
, maxevents
, timeout
));
8785 ret
= -TARGET_ENOSYS
;
8787 if (!is_error(ret
)) {
8789 for (i
= 0; i
< ret
; i
++) {
8790 target_ep
[i
].events
= tswap32(ep
[i
].events
);
8791 target_ep
[i
].data
.u64
= tswap64(ep
[i
].data
.u64
);
8794 unlock_user(target_ep
, arg2
, ret
* sizeof(struct target_epoll_event
));
8799 #ifdef TARGET_NR_prlimit64
8800 case TARGET_NR_prlimit64
:
8802 /* args: pid, resource number, ptr to new rlimit, ptr to old rlimit */
8803 struct target_rlimit64
*target_rnew
, *target_rold
;
8804 struct host_rlimit64 rnew
, rold
, *rnewp
= 0;
8806 if (!lock_user_struct(VERIFY_READ
, target_rnew
, arg3
, 1)) {
8809 rnew
.rlim_cur
= tswap64(target_rnew
->rlim_cur
);
8810 rnew
.rlim_max
= tswap64(target_rnew
->rlim_max
);
8811 unlock_user_struct(target_rnew
, arg3
, 0);
8815 ret
= get_errno(sys_prlimit64(arg1
, arg2
, rnewp
, arg4
? &rold
: 0));
8816 if (!is_error(ret
) && arg4
) {
8817 if (!lock_user_struct(VERIFY_WRITE
, target_rold
, arg4
, 1)) {
8820 target_rold
->rlim_cur
= tswap64(rold
.rlim_cur
);
8821 target_rold
->rlim_max
= tswap64(rold
.rlim_max
);
8822 unlock_user_struct(target_rold
, arg4
, 1);
8829 gemu_log("qemu: Unsupported syscall: %d\n", num
);
8830 #if defined(TARGET_NR_setxattr) || defined(TARGET_NR_get_thread_area) || defined(TARGET_NR_getdomainname) || defined(TARGET_NR_set_robust_list)
8831 unimplemented_nowarn
:
8833 ret
= -TARGET_ENOSYS
;
8838 gemu_log(" = " TARGET_ABI_FMT_ld
"\n", ret
);
8841 print_syscall_ret(num
, ret
);
8844 ret
= -TARGET_EFAULT
;