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
);
3635 static IOCTLEntry ioctl_entries
[] = {
3636 #define IOCTL(cmd, access, ...) \
3637 { TARGET_ ## cmd, cmd, #cmd, access, 0, { __VA_ARGS__ } },
3638 #define IOCTL_SPECIAL(cmd, access, dofn, ...) \
3639 { TARGET_ ## cmd, cmd, #cmd, access, dofn, { __VA_ARGS__ } },
3644 /* ??? Implement proper locking for ioctls. */
3645 /* do_ioctl() Must return target values and target errnos. */
3646 static abi_long
do_ioctl(int fd
, abi_long cmd
, abi_long arg
)
3648 const IOCTLEntry
*ie
;
3649 const argtype
*arg_type
;
3651 uint8_t buf_temp
[MAX_STRUCT_SIZE
];
3657 if (ie
->target_cmd
== 0) {
3658 gemu_log("Unsupported ioctl: cmd=0x%04lx\n", (long)cmd
);
3659 return -TARGET_ENOSYS
;
3661 if (ie
->target_cmd
== cmd
)
3665 arg_type
= ie
->arg_type
;
3667 gemu_log("ioctl: cmd=0x%04lx (%s)\n", (long)cmd
, ie
->name
);
3670 return ie
->do_ioctl(ie
, buf_temp
, fd
, cmd
, arg
);
3673 switch(arg_type
[0]) {
3676 ret
= get_errno(ioctl(fd
, ie
->host_cmd
));
3681 ret
= get_errno(ioctl(fd
, ie
->host_cmd
, arg
));
3685 target_size
= thunk_type_size(arg_type
, 0);
3686 switch(ie
->access
) {
3688 ret
= get_errno(ioctl(fd
, ie
->host_cmd
, buf_temp
));
3689 if (!is_error(ret
)) {
3690 argptr
= lock_user(VERIFY_WRITE
, arg
, target_size
, 0);
3692 return -TARGET_EFAULT
;
3693 thunk_convert(argptr
, buf_temp
, arg_type
, THUNK_TARGET
);
3694 unlock_user(argptr
, arg
, target_size
);
3698 argptr
= lock_user(VERIFY_READ
, arg
, target_size
, 1);
3700 return -TARGET_EFAULT
;
3701 thunk_convert(buf_temp
, argptr
, arg_type
, THUNK_HOST
);
3702 unlock_user(argptr
, arg
, 0);
3703 ret
= get_errno(ioctl(fd
, ie
->host_cmd
, buf_temp
));
3707 argptr
= lock_user(VERIFY_READ
, arg
, target_size
, 1);
3709 return -TARGET_EFAULT
;
3710 thunk_convert(buf_temp
, argptr
, arg_type
, THUNK_HOST
);
3711 unlock_user(argptr
, arg
, 0);
3712 ret
= get_errno(ioctl(fd
, ie
->host_cmd
, buf_temp
));
3713 if (!is_error(ret
)) {
3714 argptr
= lock_user(VERIFY_WRITE
, arg
, target_size
, 0);
3716 return -TARGET_EFAULT
;
3717 thunk_convert(argptr
, buf_temp
, arg_type
, THUNK_TARGET
);
3718 unlock_user(argptr
, arg
, target_size
);
3724 gemu_log("Unsupported ioctl type: cmd=0x%04lx type=%d\n",
3725 (long)cmd
, arg_type
[0]);
3726 ret
= -TARGET_ENOSYS
;
3732 static const bitmask_transtbl iflag_tbl
[] = {
3733 { TARGET_IGNBRK
, TARGET_IGNBRK
, IGNBRK
, IGNBRK
},
3734 { TARGET_BRKINT
, TARGET_BRKINT
, BRKINT
, BRKINT
},
3735 { TARGET_IGNPAR
, TARGET_IGNPAR
, IGNPAR
, IGNPAR
},
3736 { TARGET_PARMRK
, TARGET_PARMRK
, PARMRK
, PARMRK
},
3737 { TARGET_INPCK
, TARGET_INPCK
, INPCK
, INPCK
},
3738 { TARGET_ISTRIP
, TARGET_ISTRIP
, ISTRIP
, ISTRIP
},
3739 { TARGET_INLCR
, TARGET_INLCR
, INLCR
, INLCR
},
3740 { TARGET_IGNCR
, TARGET_IGNCR
, IGNCR
, IGNCR
},
3741 { TARGET_ICRNL
, TARGET_ICRNL
, ICRNL
, ICRNL
},
3742 { TARGET_IUCLC
, TARGET_IUCLC
, IUCLC
, IUCLC
},
3743 { TARGET_IXON
, TARGET_IXON
, IXON
, IXON
},
3744 { TARGET_IXANY
, TARGET_IXANY
, IXANY
, IXANY
},
3745 { TARGET_IXOFF
, TARGET_IXOFF
, IXOFF
, IXOFF
},
3746 { TARGET_IMAXBEL
, TARGET_IMAXBEL
, IMAXBEL
, IMAXBEL
},
3750 static const bitmask_transtbl oflag_tbl
[] = {
3751 { TARGET_OPOST
, TARGET_OPOST
, OPOST
, OPOST
},
3752 { TARGET_OLCUC
, TARGET_OLCUC
, OLCUC
, OLCUC
},
3753 { TARGET_ONLCR
, TARGET_ONLCR
, ONLCR
, ONLCR
},
3754 { TARGET_OCRNL
, TARGET_OCRNL
, OCRNL
, OCRNL
},
3755 { TARGET_ONOCR
, TARGET_ONOCR
, ONOCR
, ONOCR
},
3756 { TARGET_ONLRET
, TARGET_ONLRET
, ONLRET
, ONLRET
},
3757 { TARGET_OFILL
, TARGET_OFILL
, OFILL
, OFILL
},
3758 { TARGET_OFDEL
, TARGET_OFDEL
, OFDEL
, OFDEL
},
3759 { TARGET_NLDLY
, TARGET_NL0
, NLDLY
, NL0
},
3760 { TARGET_NLDLY
, TARGET_NL1
, NLDLY
, NL1
},
3761 { TARGET_CRDLY
, TARGET_CR0
, CRDLY
, CR0
},
3762 { TARGET_CRDLY
, TARGET_CR1
, CRDLY
, CR1
},
3763 { TARGET_CRDLY
, TARGET_CR2
, CRDLY
, CR2
},
3764 { TARGET_CRDLY
, TARGET_CR3
, CRDLY
, CR3
},
3765 { TARGET_TABDLY
, TARGET_TAB0
, TABDLY
, TAB0
},
3766 { TARGET_TABDLY
, TARGET_TAB1
, TABDLY
, TAB1
},
3767 { TARGET_TABDLY
, TARGET_TAB2
, TABDLY
, TAB2
},
3768 { TARGET_TABDLY
, TARGET_TAB3
, TABDLY
, TAB3
},
3769 { TARGET_BSDLY
, TARGET_BS0
, BSDLY
, BS0
},
3770 { TARGET_BSDLY
, TARGET_BS1
, BSDLY
, BS1
},
3771 { TARGET_VTDLY
, TARGET_VT0
, VTDLY
, VT0
},
3772 { TARGET_VTDLY
, TARGET_VT1
, VTDLY
, VT1
},
3773 { TARGET_FFDLY
, TARGET_FF0
, FFDLY
, FF0
},
3774 { TARGET_FFDLY
, TARGET_FF1
, FFDLY
, FF1
},
3778 static const bitmask_transtbl cflag_tbl
[] = {
3779 { TARGET_CBAUD
, TARGET_B0
, CBAUD
, B0
},
3780 { TARGET_CBAUD
, TARGET_B50
, CBAUD
, B50
},
3781 { TARGET_CBAUD
, TARGET_B75
, CBAUD
, B75
},
3782 { TARGET_CBAUD
, TARGET_B110
, CBAUD
, B110
},
3783 { TARGET_CBAUD
, TARGET_B134
, CBAUD
, B134
},
3784 { TARGET_CBAUD
, TARGET_B150
, CBAUD
, B150
},
3785 { TARGET_CBAUD
, TARGET_B200
, CBAUD
, B200
},
3786 { TARGET_CBAUD
, TARGET_B300
, CBAUD
, B300
},
3787 { TARGET_CBAUD
, TARGET_B600
, CBAUD
, B600
},
3788 { TARGET_CBAUD
, TARGET_B1200
, CBAUD
, B1200
},
3789 { TARGET_CBAUD
, TARGET_B1800
, CBAUD
, B1800
},
3790 { TARGET_CBAUD
, TARGET_B2400
, CBAUD
, B2400
},
3791 { TARGET_CBAUD
, TARGET_B4800
, CBAUD
, B4800
},
3792 { TARGET_CBAUD
, TARGET_B9600
, CBAUD
, B9600
},
3793 { TARGET_CBAUD
, TARGET_B19200
, CBAUD
, B19200
},
3794 { TARGET_CBAUD
, TARGET_B38400
, CBAUD
, B38400
},
3795 { TARGET_CBAUD
, TARGET_B57600
, CBAUD
, B57600
},
3796 { TARGET_CBAUD
, TARGET_B115200
, CBAUD
, B115200
},
3797 { TARGET_CBAUD
, TARGET_B230400
, CBAUD
, B230400
},
3798 { TARGET_CBAUD
, TARGET_B460800
, CBAUD
, B460800
},
3799 { TARGET_CSIZE
, TARGET_CS5
, CSIZE
, CS5
},
3800 { TARGET_CSIZE
, TARGET_CS6
, CSIZE
, CS6
},
3801 { TARGET_CSIZE
, TARGET_CS7
, CSIZE
, CS7
},
3802 { TARGET_CSIZE
, TARGET_CS8
, CSIZE
, CS8
},
3803 { TARGET_CSTOPB
, TARGET_CSTOPB
, CSTOPB
, CSTOPB
},
3804 { TARGET_CREAD
, TARGET_CREAD
, CREAD
, CREAD
},
3805 { TARGET_PARENB
, TARGET_PARENB
, PARENB
, PARENB
},
3806 { TARGET_PARODD
, TARGET_PARODD
, PARODD
, PARODD
},
3807 { TARGET_HUPCL
, TARGET_HUPCL
, HUPCL
, HUPCL
},
3808 { TARGET_CLOCAL
, TARGET_CLOCAL
, CLOCAL
, CLOCAL
},
3809 { TARGET_CRTSCTS
, TARGET_CRTSCTS
, CRTSCTS
, CRTSCTS
},
3813 static const bitmask_transtbl lflag_tbl
[] = {
3814 { TARGET_ISIG
, TARGET_ISIG
, ISIG
, ISIG
},
3815 { TARGET_ICANON
, TARGET_ICANON
, ICANON
, ICANON
},
3816 { TARGET_XCASE
, TARGET_XCASE
, XCASE
, XCASE
},
3817 { TARGET_ECHO
, TARGET_ECHO
, ECHO
, ECHO
},
3818 { TARGET_ECHOE
, TARGET_ECHOE
, ECHOE
, ECHOE
},
3819 { TARGET_ECHOK
, TARGET_ECHOK
, ECHOK
, ECHOK
},
3820 { TARGET_ECHONL
, TARGET_ECHONL
, ECHONL
, ECHONL
},
3821 { TARGET_NOFLSH
, TARGET_NOFLSH
, NOFLSH
, NOFLSH
},
3822 { TARGET_TOSTOP
, TARGET_TOSTOP
, TOSTOP
, TOSTOP
},
3823 { TARGET_ECHOCTL
, TARGET_ECHOCTL
, ECHOCTL
, ECHOCTL
},
3824 { TARGET_ECHOPRT
, TARGET_ECHOPRT
, ECHOPRT
, ECHOPRT
},
3825 { TARGET_ECHOKE
, TARGET_ECHOKE
, ECHOKE
, ECHOKE
},
3826 { TARGET_FLUSHO
, TARGET_FLUSHO
, FLUSHO
, FLUSHO
},
3827 { TARGET_PENDIN
, TARGET_PENDIN
, PENDIN
, PENDIN
},
3828 { TARGET_IEXTEN
, TARGET_IEXTEN
, IEXTEN
, IEXTEN
},
3832 static void target_to_host_termios (void *dst
, const void *src
)
3834 struct host_termios
*host
= dst
;
3835 const struct target_termios
*target
= src
;
3838 target_to_host_bitmask(tswap32(target
->c_iflag
), iflag_tbl
);
3840 target_to_host_bitmask(tswap32(target
->c_oflag
), oflag_tbl
);
3842 target_to_host_bitmask(tswap32(target
->c_cflag
), cflag_tbl
);
3844 target_to_host_bitmask(tswap32(target
->c_lflag
), lflag_tbl
);
3845 host
->c_line
= target
->c_line
;
3847 memset(host
->c_cc
, 0, sizeof(host
->c_cc
));
3848 host
->c_cc
[VINTR
] = target
->c_cc
[TARGET_VINTR
];
3849 host
->c_cc
[VQUIT
] = target
->c_cc
[TARGET_VQUIT
];
3850 host
->c_cc
[VERASE
] = target
->c_cc
[TARGET_VERASE
];
3851 host
->c_cc
[VKILL
] = target
->c_cc
[TARGET_VKILL
];
3852 host
->c_cc
[VEOF
] = target
->c_cc
[TARGET_VEOF
];
3853 host
->c_cc
[VTIME
] = target
->c_cc
[TARGET_VTIME
];
3854 host
->c_cc
[VMIN
] = target
->c_cc
[TARGET_VMIN
];
3855 host
->c_cc
[VSWTC
] = target
->c_cc
[TARGET_VSWTC
];
3856 host
->c_cc
[VSTART
] = target
->c_cc
[TARGET_VSTART
];
3857 host
->c_cc
[VSTOP
] = target
->c_cc
[TARGET_VSTOP
];
3858 host
->c_cc
[VSUSP
] = target
->c_cc
[TARGET_VSUSP
];
3859 host
->c_cc
[VEOL
] = target
->c_cc
[TARGET_VEOL
];
3860 host
->c_cc
[VREPRINT
] = target
->c_cc
[TARGET_VREPRINT
];
3861 host
->c_cc
[VDISCARD
] = target
->c_cc
[TARGET_VDISCARD
];
3862 host
->c_cc
[VWERASE
] = target
->c_cc
[TARGET_VWERASE
];
3863 host
->c_cc
[VLNEXT
] = target
->c_cc
[TARGET_VLNEXT
];
3864 host
->c_cc
[VEOL2
] = target
->c_cc
[TARGET_VEOL2
];
3867 static void host_to_target_termios (void *dst
, const void *src
)
3869 struct target_termios
*target
= dst
;
3870 const struct host_termios
*host
= src
;
3873 tswap32(host_to_target_bitmask(host
->c_iflag
, iflag_tbl
));
3875 tswap32(host_to_target_bitmask(host
->c_oflag
, oflag_tbl
));
3877 tswap32(host_to_target_bitmask(host
->c_cflag
, cflag_tbl
));
3879 tswap32(host_to_target_bitmask(host
->c_lflag
, lflag_tbl
));
3880 target
->c_line
= host
->c_line
;
3882 memset(target
->c_cc
, 0, sizeof(target
->c_cc
));
3883 target
->c_cc
[TARGET_VINTR
] = host
->c_cc
[VINTR
];
3884 target
->c_cc
[TARGET_VQUIT
] = host
->c_cc
[VQUIT
];
3885 target
->c_cc
[TARGET_VERASE
] = host
->c_cc
[VERASE
];
3886 target
->c_cc
[TARGET_VKILL
] = host
->c_cc
[VKILL
];
3887 target
->c_cc
[TARGET_VEOF
] = host
->c_cc
[VEOF
];
3888 target
->c_cc
[TARGET_VTIME
] = host
->c_cc
[VTIME
];
3889 target
->c_cc
[TARGET_VMIN
] = host
->c_cc
[VMIN
];
3890 target
->c_cc
[TARGET_VSWTC
] = host
->c_cc
[VSWTC
];
3891 target
->c_cc
[TARGET_VSTART
] = host
->c_cc
[VSTART
];
3892 target
->c_cc
[TARGET_VSTOP
] = host
->c_cc
[VSTOP
];
3893 target
->c_cc
[TARGET_VSUSP
] = host
->c_cc
[VSUSP
];
3894 target
->c_cc
[TARGET_VEOL
] = host
->c_cc
[VEOL
];
3895 target
->c_cc
[TARGET_VREPRINT
] = host
->c_cc
[VREPRINT
];
3896 target
->c_cc
[TARGET_VDISCARD
] = host
->c_cc
[VDISCARD
];
3897 target
->c_cc
[TARGET_VWERASE
] = host
->c_cc
[VWERASE
];
3898 target
->c_cc
[TARGET_VLNEXT
] = host
->c_cc
[VLNEXT
];
3899 target
->c_cc
[TARGET_VEOL2
] = host
->c_cc
[VEOL2
];
3902 static const StructEntry struct_termios_def
= {
3903 .convert
= { host_to_target_termios
, target_to_host_termios
},
3904 .size
= { sizeof(struct target_termios
), sizeof(struct host_termios
) },
3905 .align
= { __alignof__(struct target_termios
), __alignof__(struct host_termios
) },
3908 static bitmask_transtbl mmap_flags_tbl
[] = {
3909 { TARGET_MAP_SHARED
, TARGET_MAP_SHARED
, MAP_SHARED
, MAP_SHARED
},
3910 { TARGET_MAP_PRIVATE
, TARGET_MAP_PRIVATE
, MAP_PRIVATE
, MAP_PRIVATE
},
3911 { TARGET_MAP_FIXED
, TARGET_MAP_FIXED
, MAP_FIXED
, MAP_FIXED
},
3912 { TARGET_MAP_ANONYMOUS
, TARGET_MAP_ANONYMOUS
, MAP_ANONYMOUS
, MAP_ANONYMOUS
},
3913 { TARGET_MAP_GROWSDOWN
, TARGET_MAP_GROWSDOWN
, MAP_GROWSDOWN
, MAP_GROWSDOWN
},
3914 { TARGET_MAP_DENYWRITE
, TARGET_MAP_DENYWRITE
, MAP_DENYWRITE
, MAP_DENYWRITE
},
3915 { TARGET_MAP_EXECUTABLE
, TARGET_MAP_EXECUTABLE
, MAP_EXECUTABLE
, MAP_EXECUTABLE
},
3916 { TARGET_MAP_LOCKED
, TARGET_MAP_LOCKED
, MAP_LOCKED
, MAP_LOCKED
},
3920 #if defined(TARGET_I386)
3922 /* NOTE: there is really one LDT for all the threads */
3923 static uint8_t *ldt_table
;
3925 static abi_long
read_ldt(abi_ulong ptr
, unsigned long bytecount
)
3932 size
= TARGET_LDT_ENTRIES
* TARGET_LDT_ENTRY_SIZE
;
3933 if (size
> bytecount
)
3935 p
= lock_user(VERIFY_WRITE
, ptr
, size
, 0);
3937 return -TARGET_EFAULT
;
3938 /* ??? Should this by byteswapped? */
3939 memcpy(p
, ldt_table
, size
);
3940 unlock_user(p
, ptr
, size
);
3944 /* XXX: add locking support */
3945 static abi_long
write_ldt(CPUX86State
*env
,
3946 abi_ulong ptr
, unsigned long bytecount
, int oldmode
)
3948 struct target_modify_ldt_ldt_s ldt_info
;
3949 struct target_modify_ldt_ldt_s
*target_ldt_info
;
3950 int seg_32bit
, contents
, read_exec_only
, limit_in_pages
;
3951 int seg_not_present
, useable
, lm
;
3952 uint32_t *lp
, entry_1
, entry_2
;
3954 if (bytecount
!= sizeof(ldt_info
))
3955 return -TARGET_EINVAL
;
3956 if (!lock_user_struct(VERIFY_READ
, target_ldt_info
, ptr
, 1))
3957 return -TARGET_EFAULT
;
3958 ldt_info
.entry_number
= tswap32(target_ldt_info
->entry_number
);
3959 ldt_info
.base_addr
= tswapal(target_ldt_info
->base_addr
);
3960 ldt_info
.limit
= tswap32(target_ldt_info
->limit
);
3961 ldt_info
.flags
= tswap32(target_ldt_info
->flags
);
3962 unlock_user_struct(target_ldt_info
, ptr
, 0);
3964 if (ldt_info
.entry_number
>= TARGET_LDT_ENTRIES
)
3965 return -TARGET_EINVAL
;
3966 seg_32bit
= ldt_info
.flags
& 1;
3967 contents
= (ldt_info
.flags
>> 1) & 3;
3968 read_exec_only
= (ldt_info
.flags
>> 3) & 1;
3969 limit_in_pages
= (ldt_info
.flags
>> 4) & 1;
3970 seg_not_present
= (ldt_info
.flags
>> 5) & 1;
3971 useable
= (ldt_info
.flags
>> 6) & 1;
3975 lm
= (ldt_info
.flags
>> 7) & 1;
3977 if (contents
== 3) {
3979 return -TARGET_EINVAL
;
3980 if (seg_not_present
== 0)
3981 return -TARGET_EINVAL
;
3983 /* allocate the LDT */
3985 env
->ldt
.base
= target_mmap(0,
3986 TARGET_LDT_ENTRIES
* TARGET_LDT_ENTRY_SIZE
,
3987 PROT_READ
|PROT_WRITE
,
3988 MAP_ANONYMOUS
|MAP_PRIVATE
, -1, 0);
3989 if (env
->ldt
.base
== -1)
3990 return -TARGET_ENOMEM
;
3991 memset(g2h(env
->ldt
.base
), 0,
3992 TARGET_LDT_ENTRIES
* TARGET_LDT_ENTRY_SIZE
);
3993 env
->ldt
.limit
= 0xffff;
3994 ldt_table
= g2h(env
->ldt
.base
);
3997 /* NOTE: same code as Linux kernel */
3998 /* Allow LDTs to be cleared by the user. */
3999 if (ldt_info
.base_addr
== 0 && ldt_info
.limit
== 0) {
4002 read_exec_only
== 1 &&
4004 limit_in_pages
== 0 &&
4005 seg_not_present
== 1 &&
4013 entry_1
= ((ldt_info
.base_addr
& 0x0000ffff) << 16) |
4014 (ldt_info
.limit
& 0x0ffff);
4015 entry_2
= (ldt_info
.base_addr
& 0xff000000) |
4016 ((ldt_info
.base_addr
& 0x00ff0000) >> 16) |
4017 (ldt_info
.limit
& 0xf0000) |
4018 ((read_exec_only
^ 1) << 9) |
4020 ((seg_not_present
^ 1) << 15) |
4022 (limit_in_pages
<< 23) |
4026 entry_2
|= (useable
<< 20);
4028 /* Install the new entry ... */
4030 lp
= (uint32_t *)(ldt_table
+ (ldt_info
.entry_number
<< 3));
4031 lp
[0] = tswap32(entry_1
);
4032 lp
[1] = tswap32(entry_2
);
4036 /* specific and weird i386 syscalls */
4037 static abi_long
do_modify_ldt(CPUX86State
*env
, int func
, abi_ulong ptr
,
4038 unsigned long bytecount
)
4044 ret
= read_ldt(ptr
, bytecount
);
4047 ret
= write_ldt(env
, ptr
, bytecount
, 1);
4050 ret
= write_ldt(env
, ptr
, bytecount
, 0);
4053 ret
= -TARGET_ENOSYS
;
4059 #if defined(TARGET_I386) && defined(TARGET_ABI32)
4060 static abi_long
do_set_thread_area(CPUX86State
*env
, abi_ulong ptr
)
4062 uint64_t *gdt_table
= g2h(env
->gdt
.base
);
4063 struct target_modify_ldt_ldt_s ldt_info
;
4064 struct target_modify_ldt_ldt_s
*target_ldt_info
;
4065 int seg_32bit
, contents
, read_exec_only
, limit_in_pages
;
4066 int seg_not_present
, useable
, lm
;
4067 uint32_t *lp
, entry_1
, entry_2
;
4070 lock_user_struct(VERIFY_WRITE
, target_ldt_info
, ptr
, 1);
4071 if (!target_ldt_info
)
4072 return -TARGET_EFAULT
;
4073 ldt_info
.entry_number
= tswap32(target_ldt_info
->entry_number
);
4074 ldt_info
.base_addr
= tswapal(target_ldt_info
->base_addr
);
4075 ldt_info
.limit
= tswap32(target_ldt_info
->limit
);
4076 ldt_info
.flags
= tswap32(target_ldt_info
->flags
);
4077 if (ldt_info
.entry_number
== -1) {
4078 for (i
=TARGET_GDT_ENTRY_TLS_MIN
; i
<=TARGET_GDT_ENTRY_TLS_MAX
; i
++) {
4079 if (gdt_table
[i
] == 0) {
4080 ldt_info
.entry_number
= i
;
4081 target_ldt_info
->entry_number
= tswap32(i
);
4086 unlock_user_struct(target_ldt_info
, ptr
, 1);
4088 if (ldt_info
.entry_number
< TARGET_GDT_ENTRY_TLS_MIN
||
4089 ldt_info
.entry_number
> TARGET_GDT_ENTRY_TLS_MAX
)
4090 return -TARGET_EINVAL
;
4091 seg_32bit
= ldt_info
.flags
& 1;
4092 contents
= (ldt_info
.flags
>> 1) & 3;
4093 read_exec_only
= (ldt_info
.flags
>> 3) & 1;
4094 limit_in_pages
= (ldt_info
.flags
>> 4) & 1;
4095 seg_not_present
= (ldt_info
.flags
>> 5) & 1;
4096 useable
= (ldt_info
.flags
>> 6) & 1;
4100 lm
= (ldt_info
.flags
>> 7) & 1;
4103 if (contents
== 3) {
4104 if (seg_not_present
== 0)
4105 return -TARGET_EINVAL
;
4108 /* NOTE: same code as Linux kernel */
4109 /* Allow LDTs to be cleared by the user. */
4110 if (ldt_info
.base_addr
== 0 && ldt_info
.limit
== 0) {
4111 if ((contents
== 0 &&
4112 read_exec_only
== 1 &&
4114 limit_in_pages
== 0 &&
4115 seg_not_present
== 1 &&
4123 entry_1
= ((ldt_info
.base_addr
& 0x0000ffff) << 16) |
4124 (ldt_info
.limit
& 0x0ffff);
4125 entry_2
= (ldt_info
.base_addr
& 0xff000000) |
4126 ((ldt_info
.base_addr
& 0x00ff0000) >> 16) |
4127 (ldt_info
.limit
& 0xf0000) |
4128 ((read_exec_only
^ 1) << 9) |
4130 ((seg_not_present
^ 1) << 15) |
4132 (limit_in_pages
<< 23) |
4137 /* Install the new entry ... */
4139 lp
= (uint32_t *)(gdt_table
+ ldt_info
.entry_number
);
4140 lp
[0] = tswap32(entry_1
);
4141 lp
[1] = tswap32(entry_2
);
4145 static abi_long
do_get_thread_area(CPUX86State
*env
, abi_ulong ptr
)
4147 struct target_modify_ldt_ldt_s
*target_ldt_info
;
4148 uint64_t *gdt_table
= g2h(env
->gdt
.base
);
4149 uint32_t base_addr
, limit
, flags
;
4150 int seg_32bit
, contents
, read_exec_only
, limit_in_pages
, idx
;
4151 int seg_not_present
, useable
, lm
;
4152 uint32_t *lp
, entry_1
, entry_2
;
4154 lock_user_struct(VERIFY_WRITE
, target_ldt_info
, ptr
, 1);
4155 if (!target_ldt_info
)
4156 return -TARGET_EFAULT
;
4157 idx
= tswap32(target_ldt_info
->entry_number
);
4158 if (idx
< TARGET_GDT_ENTRY_TLS_MIN
||
4159 idx
> TARGET_GDT_ENTRY_TLS_MAX
) {
4160 unlock_user_struct(target_ldt_info
, ptr
, 1);
4161 return -TARGET_EINVAL
;
4163 lp
= (uint32_t *)(gdt_table
+ idx
);
4164 entry_1
= tswap32(lp
[0]);
4165 entry_2
= tswap32(lp
[1]);
4167 read_exec_only
= ((entry_2
>> 9) & 1) ^ 1;
4168 contents
= (entry_2
>> 10) & 3;
4169 seg_not_present
= ((entry_2
>> 15) & 1) ^ 1;
4170 seg_32bit
= (entry_2
>> 22) & 1;
4171 limit_in_pages
= (entry_2
>> 23) & 1;
4172 useable
= (entry_2
>> 20) & 1;
4176 lm
= (entry_2
>> 21) & 1;
4178 flags
= (seg_32bit
<< 0) | (contents
<< 1) |
4179 (read_exec_only
<< 3) | (limit_in_pages
<< 4) |
4180 (seg_not_present
<< 5) | (useable
<< 6) | (lm
<< 7);
4181 limit
= (entry_1
& 0xffff) | (entry_2
& 0xf0000);
4182 base_addr
= (entry_1
>> 16) |
4183 (entry_2
& 0xff000000) |
4184 ((entry_2
& 0xff) << 16);
4185 target_ldt_info
->base_addr
= tswapal(base_addr
);
4186 target_ldt_info
->limit
= tswap32(limit
);
4187 target_ldt_info
->flags
= tswap32(flags
);
4188 unlock_user_struct(target_ldt_info
, ptr
, 1);
4191 #endif /* TARGET_I386 && TARGET_ABI32 */
4193 #ifndef TARGET_ABI32
4194 static abi_long
do_arch_prctl(CPUX86State
*env
, int code
, abi_ulong addr
)
4201 case TARGET_ARCH_SET_GS
:
4202 case TARGET_ARCH_SET_FS
:
4203 if (code
== TARGET_ARCH_SET_GS
)
4207 cpu_x86_load_seg(env
, idx
, 0);
4208 env
->segs
[idx
].base
= addr
;
4210 case TARGET_ARCH_GET_GS
:
4211 case TARGET_ARCH_GET_FS
:
4212 if (code
== TARGET_ARCH_GET_GS
)
4216 val
= env
->segs
[idx
].base
;
4217 if (put_user(val
, addr
, abi_ulong
))
4218 ret
= -TARGET_EFAULT
;
4221 ret
= -TARGET_EINVAL
;
4228 #endif /* defined(TARGET_I386) */
4230 #define NEW_STACK_SIZE 0x40000
4232 #if defined(CONFIG_USE_NPTL)
4234 static pthread_mutex_t clone_lock
= PTHREAD_MUTEX_INITIALIZER
;
4237 pthread_mutex_t mutex
;
4238 pthread_cond_t cond
;
4241 abi_ulong child_tidptr
;
4242 abi_ulong parent_tidptr
;
4246 static void *clone_func(void *arg
)
4248 new_thread_info
*info
= arg
;
4254 ts
= (TaskState
*)thread_env
->opaque
;
4255 info
->tid
= gettid();
4256 env
->host_tid
= info
->tid
;
4258 if (info
->child_tidptr
)
4259 put_user_u32(info
->tid
, info
->child_tidptr
);
4260 if (info
->parent_tidptr
)
4261 put_user_u32(info
->tid
, info
->parent_tidptr
);
4262 /* Enable signals. */
4263 sigprocmask(SIG_SETMASK
, &info
->sigmask
, NULL
);
4264 /* Signal to the parent that we're ready. */
4265 pthread_mutex_lock(&info
->mutex
);
4266 pthread_cond_broadcast(&info
->cond
);
4267 pthread_mutex_unlock(&info
->mutex
);
4268 /* Wait until the parent has finshed initializing the tls state. */
4269 pthread_mutex_lock(&clone_lock
);
4270 pthread_mutex_unlock(&clone_lock
);
4277 static int clone_func(void *arg
)
4279 CPUArchState
*env
= arg
;
4286 /* do_fork() Must return host values and target errnos (unlike most
4287 do_*() functions). */
4288 static int do_fork(CPUArchState
*env
, unsigned int flags
, abi_ulong newsp
,
4289 abi_ulong parent_tidptr
, target_ulong newtls
,
4290 abi_ulong child_tidptr
)
4294 CPUArchState
*new_env
;
4295 #if defined(CONFIG_USE_NPTL)
4296 unsigned int nptl_flags
;
4302 /* Emulate vfork() with fork() */
4303 if (flags
& CLONE_VFORK
)
4304 flags
&= ~(CLONE_VFORK
| CLONE_VM
);
4306 if (flags
& CLONE_VM
) {
4307 TaskState
*parent_ts
= (TaskState
*)env
->opaque
;
4308 #if defined(CONFIG_USE_NPTL)
4309 new_thread_info info
;
4310 pthread_attr_t attr
;
4312 ts
= g_malloc0(sizeof(TaskState
));
4313 init_task_state(ts
);
4314 /* we create a new CPU instance. */
4315 new_env
= cpu_copy(env
);
4316 #if defined(TARGET_I386) || defined(TARGET_SPARC) || defined(TARGET_PPC)
4317 cpu_reset(ENV_GET_CPU(new_env
));
4319 /* Init regs that differ from the parent. */
4320 cpu_clone_regs(new_env
, newsp
);
4321 new_env
->opaque
= ts
;
4322 ts
->bprm
= parent_ts
->bprm
;
4323 ts
->info
= parent_ts
->info
;
4324 #if defined(CONFIG_USE_NPTL)
4326 flags
&= ~CLONE_NPTL_FLAGS2
;
4328 if (nptl_flags
& CLONE_CHILD_CLEARTID
) {
4329 ts
->child_tidptr
= child_tidptr
;
4332 if (nptl_flags
& CLONE_SETTLS
)
4333 cpu_set_tls (new_env
, newtls
);
4335 /* Grab a mutex so that thread setup appears atomic. */
4336 pthread_mutex_lock(&clone_lock
);
4338 memset(&info
, 0, sizeof(info
));
4339 pthread_mutex_init(&info
.mutex
, NULL
);
4340 pthread_mutex_lock(&info
.mutex
);
4341 pthread_cond_init(&info
.cond
, NULL
);
4343 if (nptl_flags
& CLONE_CHILD_SETTID
)
4344 info
.child_tidptr
= child_tidptr
;
4345 if (nptl_flags
& CLONE_PARENT_SETTID
)
4346 info
.parent_tidptr
= parent_tidptr
;
4348 ret
= pthread_attr_init(&attr
);
4349 ret
= pthread_attr_setstacksize(&attr
, NEW_STACK_SIZE
);
4350 ret
= pthread_attr_setdetachstate(&attr
, PTHREAD_CREATE_DETACHED
);
4351 /* It is not safe to deliver signals until the child has finished
4352 initializing, so temporarily block all signals. */
4353 sigfillset(&sigmask
);
4354 sigprocmask(SIG_BLOCK
, &sigmask
, &info
.sigmask
);
4356 ret
= pthread_create(&info
.thread
, &attr
, clone_func
, &info
);
4357 /* TODO: Free new CPU state if thread creation failed. */
4359 sigprocmask(SIG_SETMASK
, &info
.sigmask
, NULL
);
4360 pthread_attr_destroy(&attr
);
4362 /* Wait for the child to initialize. */
4363 pthread_cond_wait(&info
.cond
, &info
.mutex
);
4365 if (flags
& CLONE_PARENT_SETTID
)
4366 put_user_u32(ret
, parent_tidptr
);
4370 pthread_mutex_unlock(&info
.mutex
);
4371 pthread_cond_destroy(&info
.cond
);
4372 pthread_mutex_destroy(&info
.mutex
);
4373 pthread_mutex_unlock(&clone_lock
);
4375 if (flags
& CLONE_NPTL_FLAGS2
)
4377 /* This is probably going to die very quickly, but do it anyway. */
4378 new_stack
= g_malloc0 (NEW_STACK_SIZE
);
4380 ret
= __clone2(clone_func
, new_stack
, NEW_STACK_SIZE
, flags
, new_env
);
4382 ret
= clone(clone_func
, new_stack
+ NEW_STACK_SIZE
, flags
, new_env
);
4386 /* if no CLONE_VM, we consider it is a fork */
4387 if ((flags
& ~(CSIGNAL
| CLONE_NPTL_FLAGS2
)) != 0)
4392 /* Child Process. */
4393 cpu_clone_regs(env
, newsp
);
4395 #if defined(CONFIG_USE_NPTL)
4396 /* There is a race condition here. The parent process could
4397 theoretically read the TID in the child process before the child
4398 tid is set. This would require using either ptrace
4399 (not implemented) or having *_tidptr to point at a shared memory
4400 mapping. We can't repeat the spinlock hack used above because
4401 the child process gets its own copy of the lock. */
4402 if (flags
& CLONE_CHILD_SETTID
)
4403 put_user_u32(gettid(), child_tidptr
);
4404 if (flags
& CLONE_PARENT_SETTID
)
4405 put_user_u32(gettid(), parent_tidptr
);
4406 ts
= (TaskState
*)env
->opaque
;
4407 if (flags
& CLONE_SETTLS
)
4408 cpu_set_tls (env
, newtls
);
4409 if (flags
& CLONE_CHILD_CLEARTID
)
4410 ts
->child_tidptr
= child_tidptr
;
4419 /* warning : doesn't handle linux specific flags... */
4420 static int target_to_host_fcntl_cmd(int cmd
)
4423 case TARGET_F_DUPFD
:
4424 case TARGET_F_GETFD
:
4425 case TARGET_F_SETFD
:
4426 case TARGET_F_GETFL
:
4427 case TARGET_F_SETFL
:
4429 case TARGET_F_GETLK
:
4431 case TARGET_F_SETLK
:
4433 case TARGET_F_SETLKW
:
4435 case TARGET_F_GETOWN
:
4437 case TARGET_F_SETOWN
:
4439 case TARGET_F_GETSIG
:
4441 case TARGET_F_SETSIG
:
4443 #if TARGET_ABI_BITS == 32
4444 case TARGET_F_GETLK64
:
4446 case TARGET_F_SETLK64
:
4448 case TARGET_F_SETLKW64
:
4451 case TARGET_F_SETLEASE
:
4453 case TARGET_F_GETLEASE
:
4455 #ifdef F_DUPFD_CLOEXEC
4456 case TARGET_F_DUPFD_CLOEXEC
:
4457 return F_DUPFD_CLOEXEC
;
4459 case TARGET_F_NOTIFY
:
4462 return -TARGET_EINVAL
;
4464 return -TARGET_EINVAL
;
4467 static abi_long
do_fcntl(int fd
, int cmd
, abi_ulong arg
)
4470 struct target_flock
*target_fl
;
4471 struct flock64 fl64
;
4472 struct target_flock64
*target_fl64
;
4474 int host_cmd
= target_to_host_fcntl_cmd(cmd
);
4476 if (host_cmd
== -TARGET_EINVAL
)
4480 case TARGET_F_GETLK
:
4481 if (!lock_user_struct(VERIFY_READ
, target_fl
, arg
, 1))
4482 return -TARGET_EFAULT
;
4483 fl
.l_type
= tswap16(target_fl
->l_type
);
4484 fl
.l_whence
= tswap16(target_fl
->l_whence
);
4485 fl
.l_start
= tswapal(target_fl
->l_start
);
4486 fl
.l_len
= tswapal(target_fl
->l_len
);
4487 fl
.l_pid
= tswap32(target_fl
->l_pid
);
4488 unlock_user_struct(target_fl
, arg
, 0);
4489 ret
= get_errno(fcntl(fd
, host_cmd
, &fl
));
4491 if (!lock_user_struct(VERIFY_WRITE
, target_fl
, arg
, 0))
4492 return -TARGET_EFAULT
;
4493 target_fl
->l_type
= tswap16(fl
.l_type
);
4494 target_fl
->l_whence
= tswap16(fl
.l_whence
);
4495 target_fl
->l_start
= tswapal(fl
.l_start
);
4496 target_fl
->l_len
= tswapal(fl
.l_len
);
4497 target_fl
->l_pid
= tswap32(fl
.l_pid
);
4498 unlock_user_struct(target_fl
, arg
, 1);
4502 case TARGET_F_SETLK
:
4503 case TARGET_F_SETLKW
:
4504 if (!lock_user_struct(VERIFY_READ
, target_fl
, arg
, 1))
4505 return -TARGET_EFAULT
;
4506 fl
.l_type
= tswap16(target_fl
->l_type
);
4507 fl
.l_whence
= tswap16(target_fl
->l_whence
);
4508 fl
.l_start
= tswapal(target_fl
->l_start
);
4509 fl
.l_len
= tswapal(target_fl
->l_len
);
4510 fl
.l_pid
= tswap32(target_fl
->l_pid
);
4511 unlock_user_struct(target_fl
, arg
, 0);
4512 ret
= get_errno(fcntl(fd
, host_cmd
, &fl
));
4515 case TARGET_F_GETLK64
:
4516 if (!lock_user_struct(VERIFY_READ
, target_fl64
, arg
, 1))
4517 return -TARGET_EFAULT
;
4518 fl64
.l_type
= tswap16(target_fl64
->l_type
) >> 1;
4519 fl64
.l_whence
= tswap16(target_fl64
->l_whence
);
4520 fl64
.l_start
= tswap64(target_fl64
->l_start
);
4521 fl64
.l_len
= tswap64(target_fl64
->l_len
);
4522 fl64
.l_pid
= tswap32(target_fl64
->l_pid
);
4523 unlock_user_struct(target_fl64
, arg
, 0);
4524 ret
= get_errno(fcntl(fd
, host_cmd
, &fl64
));
4526 if (!lock_user_struct(VERIFY_WRITE
, target_fl64
, arg
, 0))
4527 return -TARGET_EFAULT
;
4528 target_fl64
->l_type
= tswap16(fl64
.l_type
) >> 1;
4529 target_fl64
->l_whence
= tswap16(fl64
.l_whence
);
4530 target_fl64
->l_start
= tswap64(fl64
.l_start
);
4531 target_fl64
->l_len
= tswap64(fl64
.l_len
);
4532 target_fl64
->l_pid
= tswap32(fl64
.l_pid
);
4533 unlock_user_struct(target_fl64
, arg
, 1);
4536 case TARGET_F_SETLK64
:
4537 case TARGET_F_SETLKW64
:
4538 if (!lock_user_struct(VERIFY_READ
, target_fl64
, arg
, 1))
4539 return -TARGET_EFAULT
;
4540 fl64
.l_type
= tswap16(target_fl64
->l_type
) >> 1;
4541 fl64
.l_whence
= tswap16(target_fl64
->l_whence
);
4542 fl64
.l_start
= tswap64(target_fl64
->l_start
);
4543 fl64
.l_len
= tswap64(target_fl64
->l_len
);
4544 fl64
.l_pid
= tswap32(target_fl64
->l_pid
);
4545 unlock_user_struct(target_fl64
, arg
, 0);
4546 ret
= get_errno(fcntl(fd
, host_cmd
, &fl64
));
4549 case TARGET_F_GETFL
:
4550 ret
= get_errno(fcntl(fd
, host_cmd
, arg
));
4552 ret
= host_to_target_bitmask(ret
, fcntl_flags_tbl
);
4556 case TARGET_F_SETFL
:
4557 ret
= get_errno(fcntl(fd
, host_cmd
, target_to_host_bitmask(arg
, fcntl_flags_tbl
)));
4560 case TARGET_F_SETOWN
:
4561 case TARGET_F_GETOWN
:
4562 case TARGET_F_SETSIG
:
4563 case TARGET_F_GETSIG
:
4564 case TARGET_F_SETLEASE
:
4565 case TARGET_F_GETLEASE
:
4566 ret
= get_errno(fcntl(fd
, host_cmd
, arg
));
4570 ret
= get_errno(fcntl(fd
, cmd
, arg
));
4578 static inline int high2lowuid(int uid
)
4586 static inline int high2lowgid(int gid
)
4594 static inline int low2highuid(int uid
)
4596 if ((int16_t)uid
== -1)
4602 static inline int low2highgid(int gid
)
4604 if ((int16_t)gid
== -1)
4609 static inline int tswapid(int id
)
4613 #else /* !USE_UID16 */
4614 static inline int high2lowuid(int uid
)
4618 static inline int high2lowgid(int gid
)
4622 static inline int low2highuid(int uid
)
4626 static inline int low2highgid(int gid
)
4630 static inline int tswapid(int id
)
4634 #endif /* USE_UID16 */
4636 void syscall_init(void)
4639 const argtype
*arg_type
;
4643 #define STRUCT(name, ...) thunk_register_struct(STRUCT_ ## name, #name, struct_ ## name ## _def);
4644 #define STRUCT_SPECIAL(name) thunk_register_struct_direct(STRUCT_ ## name, #name, &struct_ ## name ## _def);
4645 #include "syscall_types.h"
4647 #undef STRUCT_SPECIAL
4649 /* Build target_to_host_errno_table[] table from
4650 * host_to_target_errno_table[]. */
4651 for (i
= 0; i
< ERRNO_TABLE_SIZE
; i
++) {
4652 target_to_host_errno_table
[host_to_target_errno_table
[i
]] = i
;
4655 /* we patch the ioctl size if necessary. We rely on the fact that
4656 no ioctl has all the bits at '1' in the size field */
4658 while (ie
->target_cmd
!= 0) {
4659 if (((ie
->target_cmd
>> TARGET_IOC_SIZESHIFT
) & TARGET_IOC_SIZEMASK
) ==
4660 TARGET_IOC_SIZEMASK
) {
4661 arg_type
= ie
->arg_type
;
4662 if (arg_type
[0] != TYPE_PTR
) {
4663 fprintf(stderr
, "cannot patch size for ioctl 0x%x\n",
4668 size
= thunk_type_size(arg_type
, 0);
4669 ie
->target_cmd
= (ie
->target_cmd
&
4670 ~(TARGET_IOC_SIZEMASK
<< TARGET_IOC_SIZESHIFT
)) |
4671 (size
<< TARGET_IOC_SIZESHIFT
);
4674 /* automatic consistency check if same arch */
4675 #if (defined(__i386__) && defined(TARGET_I386) && defined(TARGET_ABI32)) || \
4676 (defined(__x86_64__) && defined(TARGET_X86_64))
4677 if (unlikely(ie
->target_cmd
!= ie
->host_cmd
)) {
4678 fprintf(stderr
, "ERROR: ioctl(%s): target=0x%x host=0x%x\n",
4679 ie
->name
, ie
->target_cmd
, ie
->host_cmd
);
4686 #if TARGET_ABI_BITS == 32
4687 static inline uint64_t target_offset64(uint32_t word0
, uint32_t word1
)
4689 #ifdef TARGET_WORDS_BIGENDIAN
4690 return ((uint64_t)word0
<< 32) | word1
;
4692 return ((uint64_t)word1
<< 32) | word0
;
4695 #else /* TARGET_ABI_BITS == 32 */
4696 static inline uint64_t target_offset64(uint64_t word0
, uint64_t word1
)
4700 #endif /* TARGET_ABI_BITS != 32 */
4702 #ifdef TARGET_NR_truncate64
4703 static inline abi_long
target_truncate64(void *cpu_env
, const char *arg1
,
4708 if (regpairs_aligned(cpu_env
)) {
4712 return get_errno(truncate64(arg1
, target_offset64(arg2
, arg3
)));
4716 #ifdef TARGET_NR_ftruncate64
4717 static inline abi_long
target_ftruncate64(void *cpu_env
, abi_long arg1
,
4722 if (regpairs_aligned(cpu_env
)) {
4726 return get_errno(ftruncate64(arg1
, target_offset64(arg2
, arg3
)));
4730 static inline abi_long
target_to_host_timespec(struct timespec
*host_ts
,
4731 abi_ulong target_addr
)
4733 struct target_timespec
*target_ts
;
4735 if (!lock_user_struct(VERIFY_READ
, target_ts
, target_addr
, 1))
4736 return -TARGET_EFAULT
;
4737 host_ts
->tv_sec
= tswapal(target_ts
->tv_sec
);
4738 host_ts
->tv_nsec
= tswapal(target_ts
->tv_nsec
);
4739 unlock_user_struct(target_ts
, target_addr
, 0);
4743 static inline abi_long
host_to_target_timespec(abi_ulong target_addr
,
4744 struct timespec
*host_ts
)
4746 struct target_timespec
*target_ts
;
4748 if (!lock_user_struct(VERIFY_WRITE
, target_ts
, target_addr
, 0))
4749 return -TARGET_EFAULT
;
4750 target_ts
->tv_sec
= tswapal(host_ts
->tv_sec
);
4751 target_ts
->tv_nsec
= tswapal(host_ts
->tv_nsec
);
4752 unlock_user_struct(target_ts
, target_addr
, 1);
4756 #if defined(TARGET_NR_stat64) || defined(TARGET_NR_newfstatat)
4757 static inline abi_long
host_to_target_stat64(void *cpu_env
,
4758 abi_ulong target_addr
,
4759 struct stat
*host_st
)
4762 if (((CPUARMState
*)cpu_env
)->eabi
) {
4763 struct target_eabi_stat64
*target_st
;
4765 if (!lock_user_struct(VERIFY_WRITE
, target_st
, target_addr
, 0))
4766 return -TARGET_EFAULT
;
4767 memset(target_st
, 0, sizeof(struct target_eabi_stat64
));
4768 __put_user(host_st
->st_dev
, &target_st
->st_dev
);
4769 __put_user(host_st
->st_ino
, &target_st
->st_ino
);
4770 #ifdef TARGET_STAT64_HAS_BROKEN_ST_INO
4771 __put_user(host_st
->st_ino
, &target_st
->__st_ino
);
4773 __put_user(host_st
->st_mode
, &target_st
->st_mode
);
4774 __put_user(host_st
->st_nlink
, &target_st
->st_nlink
);
4775 __put_user(host_st
->st_uid
, &target_st
->st_uid
);
4776 __put_user(host_st
->st_gid
, &target_st
->st_gid
);
4777 __put_user(host_st
->st_rdev
, &target_st
->st_rdev
);
4778 __put_user(host_st
->st_size
, &target_st
->st_size
);
4779 __put_user(host_st
->st_blksize
, &target_st
->st_blksize
);
4780 __put_user(host_st
->st_blocks
, &target_st
->st_blocks
);
4781 __put_user(host_st
->st_atime
, &target_st
->target_st_atime
);
4782 __put_user(host_st
->st_mtime
, &target_st
->target_st_mtime
);
4783 __put_user(host_st
->st_ctime
, &target_st
->target_st_ctime
);
4784 unlock_user_struct(target_st
, target_addr
, 1);
4788 #if TARGET_ABI_BITS == 64 && !defined(TARGET_ALPHA)
4789 struct target_stat
*target_st
;
4791 struct target_stat64
*target_st
;
4794 if (!lock_user_struct(VERIFY_WRITE
, target_st
, target_addr
, 0))
4795 return -TARGET_EFAULT
;
4796 memset(target_st
, 0, sizeof(*target_st
));
4797 __put_user(host_st
->st_dev
, &target_st
->st_dev
);
4798 __put_user(host_st
->st_ino
, &target_st
->st_ino
);
4799 #ifdef TARGET_STAT64_HAS_BROKEN_ST_INO
4800 __put_user(host_st
->st_ino
, &target_st
->__st_ino
);
4802 __put_user(host_st
->st_mode
, &target_st
->st_mode
);
4803 __put_user(host_st
->st_nlink
, &target_st
->st_nlink
);
4804 __put_user(host_st
->st_uid
, &target_st
->st_uid
);
4805 __put_user(host_st
->st_gid
, &target_st
->st_gid
);
4806 __put_user(host_st
->st_rdev
, &target_st
->st_rdev
);
4807 /* XXX: better use of kernel struct */
4808 __put_user(host_st
->st_size
, &target_st
->st_size
);
4809 __put_user(host_st
->st_blksize
, &target_st
->st_blksize
);
4810 __put_user(host_st
->st_blocks
, &target_st
->st_blocks
);
4811 __put_user(host_st
->st_atime
, &target_st
->target_st_atime
);
4812 __put_user(host_st
->st_mtime
, &target_st
->target_st_mtime
);
4813 __put_user(host_st
->st_ctime
, &target_st
->target_st_ctime
);
4814 unlock_user_struct(target_st
, target_addr
, 1);
4821 #if defined(CONFIG_USE_NPTL)
4822 /* ??? Using host futex calls even when target atomic operations
4823 are not really atomic probably breaks things. However implementing
4824 futexes locally would make futexes shared between multiple processes
4825 tricky. However they're probably useless because guest atomic
4826 operations won't work either. */
4827 static int do_futex(target_ulong uaddr
, int op
, int val
, target_ulong timeout
,
4828 target_ulong uaddr2
, int val3
)
4830 struct timespec ts
, *pts
;
4833 /* ??? We assume FUTEX_* constants are the same on both host
4835 #ifdef FUTEX_CMD_MASK
4836 base_op
= op
& FUTEX_CMD_MASK
;
4844 target_to_host_timespec(pts
, timeout
);
4848 return get_errno(sys_futex(g2h(uaddr
), op
, tswap32(val
),
4851 return get_errno(sys_futex(g2h(uaddr
), op
, val
, NULL
, NULL
, 0));
4853 return get_errno(sys_futex(g2h(uaddr
), op
, val
, NULL
, NULL
, 0));
4855 case FUTEX_CMP_REQUEUE
:
4857 /* For FUTEX_REQUEUE, FUTEX_CMP_REQUEUE, and FUTEX_WAKE_OP, the
4858 TIMEOUT parameter is interpreted as a uint32_t by the kernel.
4859 But the prototype takes a `struct timespec *'; insert casts
4860 to satisfy the compiler. We do not need to tswap TIMEOUT
4861 since it's not compared to guest memory. */
4862 pts
= (struct timespec
*)(uintptr_t) timeout
;
4863 return get_errno(sys_futex(g2h(uaddr
), op
, val
, pts
,
4865 (base_op
== FUTEX_CMP_REQUEUE
4869 return -TARGET_ENOSYS
;
4874 /* Map host to target signal numbers for the wait family of syscalls.
4875 Assume all other status bits are the same. */
4876 static int host_to_target_waitstatus(int status
)
4878 if (WIFSIGNALED(status
)) {
4879 return host_to_target_signal(WTERMSIG(status
)) | (status
& ~0x7f);
4881 if (WIFSTOPPED(status
)) {
4882 return (host_to_target_signal(WSTOPSIG(status
)) << 8)
4888 int get_osversion(void)
4890 static int osversion
;
4891 struct new_utsname buf
;
4896 if (qemu_uname_release
&& *qemu_uname_release
) {
4897 s
= qemu_uname_release
;
4899 if (sys_uname(&buf
))
4904 for (i
= 0; i
< 3; i
++) {
4906 while (*s
>= '0' && *s
<= '9') {
4911 tmp
= (tmp
<< 8) + n
;
4920 static int open_self_maps(void *cpu_env
, int fd
)
4922 #if defined(TARGET_ARM) || defined(TARGET_M68K) || defined(TARGET_UNICORE32)
4923 TaskState
*ts
= ((CPUArchState
*)cpu_env
)->opaque
;
4930 fp
= fopen("/proc/self/maps", "r");
4935 while ((read
= getline(&line
, &len
, fp
)) != -1) {
4936 int fields
, dev_maj
, dev_min
, inode
;
4937 uint64_t min
, max
, offset
;
4938 char flag_r
, flag_w
, flag_x
, flag_p
;
4939 char path
[512] = "";
4940 fields
= sscanf(line
, "%"PRIx64
"-%"PRIx64
" %c%c%c%c %"PRIx64
" %x:%x %d"
4941 " %512s", &min
, &max
, &flag_r
, &flag_w
, &flag_x
,
4942 &flag_p
, &offset
, &dev_maj
, &dev_min
, &inode
, path
);
4944 if ((fields
< 10) || (fields
> 11)) {
4947 if (!strncmp(path
, "[stack]", 7)) {
4950 if (h2g_valid(min
) && h2g_valid(max
)) {
4951 dprintf(fd
, TARGET_ABI_FMT_lx
"-" TARGET_ABI_FMT_lx
4952 " %c%c%c%c %08" PRIx64
" %02x:%02x %d%s%s\n",
4953 h2g(min
), h2g(max
), flag_r
, flag_w
,
4954 flag_x
, flag_p
, offset
, dev_maj
, dev_min
, inode
,
4955 path
[0] ? " " : "", path
);
4962 #if defined(TARGET_ARM) || defined(TARGET_M68K) || defined(TARGET_UNICORE32)
4963 dprintf(fd
, "%08llx-%08llx rw-p %08llx 00:00 0 [stack]\n",
4964 (unsigned long long)ts
->info
->stack_limit
,
4965 (unsigned long long)(ts
->stack_base
+ (TARGET_PAGE_SIZE
- 1))
4967 (unsigned long long)0);
4973 static int open_self_stat(void *cpu_env
, int fd
)
4975 TaskState
*ts
= ((CPUArchState
*)cpu_env
)->opaque
;
4976 abi_ulong start_stack
= ts
->info
->start_stack
;
4979 for (i
= 0; i
< 44; i
++) {
4987 snprintf(buf
, sizeof(buf
), "%"PRId64
" ", val
);
4988 } else if (i
== 1) {
4990 snprintf(buf
, sizeof(buf
), "(%s) ", ts
->bprm
->argv
[0]);
4991 } else if (i
== 27) {
4994 snprintf(buf
, sizeof(buf
), "%"PRId64
" ", val
);
4996 /* for the rest, there is MasterCard */
4997 snprintf(buf
, sizeof(buf
), "0%c", i
== 43 ? '\n' : ' ');
5001 if (write(fd
, buf
, len
) != len
) {
5009 static int open_self_auxv(void *cpu_env
, int fd
)
5011 TaskState
*ts
= ((CPUArchState
*)cpu_env
)->opaque
;
5012 abi_ulong auxv
= ts
->info
->saved_auxv
;
5013 abi_ulong len
= ts
->info
->auxv_len
;
5017 * Auxiliary vector is stored in target process stack.
5018 * read in whole auxv vector and copy it to file
5020 ptr
= lock_user(VERIFY_READ
, auxv
, len
, 0);
5024 r
= write(fd
, ptr
, len
);
5031 lseek(fd
, 0, SEEK_SET
);
5032 unlock_user(ptr
, auxv
, len
);
5038 static int do_open(void *cpu_env
, const char *pathname
, int flags
, mode_t mode
)
5041 const char *filename
;
5042 int (*fill
)(void *cpu_env
, int fd
);
5044 const struct fake_open
*fake_open
;
5045 static const struct fake_open fakes
[] = {
5046 { "/proc/self/maps", open_self_maps
},
5047 { "/proc/self/stat", open_self_stat
},
5048 { "/proc/self/auxv", open_self_auxv
},
5052 for (fake_open
= fakes
; fake_open
->filename
; fake_open
++) {
5053 if (!strncmp(pathname
, fake_open
->filename
,
5054 strlen(fake_open
->filename
))) {
5059 if (fake_open
->filename
) {
5061 char filename
[PATH_MAX
];
5064 /* create temporary file to map stat to */
5065 tmpdir
= getenv("TMPDIR");
5068 snprintf(filename
, sizeof(filename
), "%s/qemu-open.XXXXXX", tmpdir
);
5069 fd
= mkstemp(filename
);
5075 if ((r
= fake_open
->fill(cpu_env
, fd
))) {
5079 lseek(fd
, 0, SEEK_SET
);
5084 return get_errno(open(path(pathname
), flags
, mode
));
5087 /* do_syscall() should always have a single exit point at the end so
5088 that actions, such as logging of syscall results, can be performed.
5089 All errnos that do_syscall() returns must be -TARGET_<errcode>. */
5090 abi_long
do_syscall(void *cpu_env
, int num
, abi_long arg1
,
5091 abi_long arg2
, abi_long arg3
, abi_long arg4
,
5092 abi_long arg5
, abi_long arg6
, abi_long arg7
,
5101 gemu_log("syscall %d", num
);
5104 print_syscall(num
, arg1
, arg2
, arg3
, arg4
, arg5
, arg6
);
5107 case TARGET_NR_exit
:
5108 #ifdef CONFIG_USE_NPTL
5109 /* In old applications this may be used to implement _exit(2).
5110 However in threaded applictions it is used for thread termination,
5111 and _exit_group is used for application termination.
5112 Do thread termination if we have more then one thread. */
5113 /* FIXME: This probably breaks if a signal arrives. We should probably
5114 be disabling signals. */
5115 if (first_cpu
->next_cpu
) {
5117 CPUArchState
**lastp
;
5123 while (p
&& p
!= (CPUArchState
*)cpu_env
) {
5124 lastp
= &p
->next_cpu
;
5127 /* If we didn't find the CPU for this thread then something is
5131 /* Remove the CPU from the list. */
5132 *lastp
= p
->next_cpu
;
5134 ts
= ((CPUArchState
*)cpu_env
)->opaque
;
5135 if (ts
->child_tidptr
) {
5136 put_user_u32(0, ts
->child_tidptr
);
5137 sys_futex(g2h(ts
->child_tidptr
), FUTEX_WAKE
, INT_MAX
,
5141 object_delete(OBJECT(ENV_GET_CPU(cpu_env
)));
5149 gdb_exit(cpu_env
, arg1
);
5151 ret
= 0; /* avoid warning */
5153 case TARGET_NR_read
:
5157 if (!(p
= lock_user(VERIFY_WRITE
, arg2
, arg3
, 0)))
5159 ret
= get_errno(read(arg1
, p
, arg3
));
5160 unlock_user(p
, arg2
, ret
);
5163 case TARGET_NR_write
:
5164 if (!(p
= lock_user(VERIFY_READ
, arg2
, arg3
, 1)))
5166 ret
= get_errno(write(arg1
, p
, arg3
));
5167 unlock_user(p
, arg2
, 0);
5169 case TARGET_NR_open
:
5170 if (!(p
= lock_user_string(arg1
)))
5172 ret
= get_errno(do_open(cpu_env
, p
,
5173 target_to_host_bitmask(arg2
, fcntl_flags_tbl
),
5175 unlock_user(p
, arg1
, 0);
5177 #if defined(TARGET_NR_openat) && defined(__NR_openat)
5178 case TARGET_NR_openat
:
5179 if (!(p
= lock_user_string(arg2
)))
5181 ret
= get_errno(sys_openat(arg1
,
5183 target_to_host_bitmask(arg3
, fcntl_flags_tbl
),
5185 unlock_user(p
, arg2
, 0);
5188 case TARGET_NR_close
:
5189 ret
= get_errno(close(arg1
));
5194 case TARGET_NR_fork
:
5195 ret
= get_errno(do_fork(cpu_env
, SIGCHLD
, 0, 0, 0, 0));
5197 #ifdef TARGET_NR_waitpid
5198 case TARGET_NR_waitpid
:
5201 ret
= get_errno(waitpid(arg1
, &status
, arg3
));
5202 if (!is_error(ret
) && arg2
&& ret
5203 && put_user_s32(host_to_target_waitstatus(status
), arg2
))
5208 #ifdef TARGET_NR_waitid
5209 case TARGET_NR_waitid
:
5213 ret
= get_errno(waitid(arg1
, arg2
, &info
, arg4
));
5214 if (!is_error(ret
) && arg3
&& info
.si_pid
!= 0) {
5215 if (!(p
= lock_user(VERIFY_WRITE
, arg3
, sizeof(target_siginfo_t
), 0)))
5217 host_to_target_siginfo(p
, &info
);
5218 unlock_user(p
, arg3
, sizeof(target_siginfo_t
));
5223 #ifdef TARGET_NR_creat /* not on alpha */
5224 case TARGET_NR_creat
:
5225 if (!(p
= lock_user_string(arg1
)))
5227 ret
= get_errno(creat(p
, arg2
));
5228 unlock_user(p
, arg1
, 0);
5231 case TARGET_NR_link
:
5234 p
= lock_user_string(arg1
);
5235 p2
= lock_user_string(arg2
);
5237 ret
= -TARGET_EFAULT
;
5239 ret
= get_errno(link(p
, p2
));
5240 unlock_user(p2
, arg2
, 0);
5241 unlock_user(p
, arg1
, 0);
5244 #if defined(TARGET_NR_linkat) && defined(__NR_linkat)
5245 case TARGET_NR_linkat
:
5250 p
= lock_user_string(arg2
);
5251 p2
= lock_user_string(arg4
);
5253 ret
= -TARGET_EFAULT
;
5255 ret
= get_errno(sys_linkat(arg1
, p
, arg3
, p2
, arg5
));
5256 unlock_user(p
, arg2
, 0);
5257 unlock_user(p2
, arg4
, 0);
5261 case TARGET_NR_unlink
:
5262 if (!(p
= lock_user_string(arg1
)))
5264 ret
= get_errno(unlink(p
));
5265 unlock_user(p
, arg1
, 0);
5267 #if defined(TARGET_NR_unlinkat) && defined(__NR_unlinkat)
5268 case TARGET_NR_unlinkat
:
5269 if (!(p
= lock_user_string(arg2
)))
5271 ret
= get_errno(sys_unlinkat(arg1
, p
, arg3
));
5272 unlock_user(p
, arg2
, 0);
5275 case TARGET_NR_execve
:
5277 char **argp
, **envp
;
5280 abi_ulong guest_argp
;
5281 abi_ulong guest_envp
;
5288 for (gp
= guest_argp
; gp
; gp
+= sizeof(abi_ulong
)) {
5289 if (get_user_ual(addr
, gp
))
5297 for (gp
= guest_envp
; gp
; gp
+= sizeof(abi_ulong
)) {
5298 if (get_user_ual(addr
, gp
))
5305 argp
= alloca((argc
+ 1) * sizeof(void *));
5306 envp
= alloca((envc
+ 1) * sizeof(void *));
5308 for (gp
= guest_argp
, q
= argp
; gp
;
5309 gp
+= sizeof(abi_ulong
), q
++) {
5310 if (get_user_ual(addr
, gp
))
5314 if (!(*q
= lock_user_string(addr
)))
5316 total_size
+= strlen(*q
) + 1;
5320 for (gp
= guest_envp
, q
= envp
; gp
;
5321 gp
+= sizeof(abi_ulong
), q
++) {
5322 if (get_user_ual(addr
, gp
))
5326 if (!(*q
= lock_user_string(addr
)))
5328 total_size
+= strlen(*q
) + 1;
5332 /* This case will not be caught by the host's execve() if its
5333 page size is bigger than the target's. */
5334 if (total_size
> MAX_ARG_PAGES
* TARGET_PAGE_SIZE
) {
5335 ret
= -TARGET_E2BIG
;
5338 if (!(p
= lock_user_string(arg1
)))
5340 ret
= get_errno(execve(p
, argp
, envp
));
5341 unlock_user(p
, arg1
, 0);
5346 ret
= -TARGET_EFAULT
;
5349 for (gp
= guest_argp
, q
= argp
; *q
;
5350 gp
+= sizeof(abi_ulong
), q
++) {
5351 if (get_user_ual(addr
, gp
)
5354 unlock_user(*q
, addr
, 0);
5356 for (gp
= guest_envp
, q
= envp
; *q
;
5357 gp
+= sizeof(abi_ulong
), q
++) {
5358 if (get_user_ual(addr
, gp
)
5361 unlock_user(*q
, addr
, 0);
5365 case TARGET_NR_chdir
:
5366 if (!(p
= lock_user_string(arg1
)))
5368 ret
= get_errno(chdir(p
));
5369 unlock_user(p
, arg1
, 0);
5371 #ifdef TARGET_NR_time
5372 case TARGET_NR_time
:
5375 ret
= get_errno(time(&host_time
));
5378 && put_user_sal(host_time
, arg1
))
5383 case TARGET_NR_mknod
:
5384 if (!(p
= lock_user_string(arg1
)))
5386 ret
= get_errno(mknod(p
, arg2
, arg3
));
5387 unlock_user(p
, arg1
, 0);
5389 #if defined(TARGET_NR_mknodat) && defined(__NR_mknodat)
5390 case TARGET_NR_mknodat
:
5391 if (!(p
= lock_user_string(arg2
)))
5393 ret
= get_errno(sys_mknodat(arg1
, p
, arg3
, arg4
));
5394 unlock_user(p
, arg2
, 0);
5397 case TARGET_NR_chmod
:
5398 if (!(p
= lock_user_string(arg1
)))
5400 ret
= get_errno(chmod(p
, arg2
));
5401 unlock_user(p
, arg1
, 0);
5403 #ifdef TARGET_NR_break
5404 case TARGET_NR_break
:
5407 #ifdef TARGET_NR_oldstat
5408 case TARGET_NR_oldstat
:
5411 case TARGET_NR_lseek
:
5412 ret
= get_errno(lseek(arg1
, arg2
, arg3
));
5414 #if defined(TARGET_NR_getxpid) && defined(TARGET_ALPHA)
5415 /* Alpha specific */
5416 case TARGET_NR_getxpid
:
5417 ((CPUAlphaState
*)cpu_env
)->ir
[IR_A4
] = getppid();
5418 ret
= get_errno(getpid());
5421 #ifdef TARGET_NR_getpid
5422 case TARGET_NR_getpid
:
5423 ret
= get_errno(getpid());
5426 case TARGET_NR_mount
:
5428 /* need to look at the data field */
5430 p
= lock_user_string(arg1
);
5431 p2
= lock_user_string(arg2
);
5432 p3
= lock_user_string(arg3
);
5433 if (!p
|| !p2
|| !p3
)
5434 ret
= -TARGET_EFAULT
;
5436 /* FIXME - arg5 should be locked, but it isn't clear how to
5437 * do that since it's not guaranteed to be a NULL-terminated
5441 ret
= get_errno(mount(p
, p2
, p3
, (unsigned long)arg4
, NULL
));
5443 ret
= get_errno(mount(p
, p2
, p3
, (unsigned long)arg4
, g2h(arg5
)));
5445 unlock_user(p
, arg1
, 0);
5446 unlock_user(p2
, arg2
, 0);
5447 unlock_user(p3
, arg3
, 0);
5450 #ifdef TARGET_NR_umount
5451 case TARGET_NR_umount
:
5452 if (!(p
= lock_user_string(arg1
)))
5454 ret
= get_errno(umount(p
));
5455 unlock_user(p
, arg1
, 0);
5458 #ifdef TARGET_NR_stime /* not on alpha */
5459 case TARGET_NR_stime
:
5462 if (get_user_sal(host_time
, arg1
))
5464 ret
= get_errno(stime(&host_time
));
5468 case TARGET_NR_ptrace
:
5470 #ifdef TARGET_NR_alarm /* not on alpha */
5471 case TARGET_NR_alarm
:
5475 #ifdef TARGET_NR_oldfstat
5476 case TARGET_NR_oldfstat
:
5479 #ifdef TARGET_NR_pause /* not on alpha */
5480 case TARGET_NR_pause
:
5481 ret
= get_errno(pause());
5484 #ifdef TARGET_NR_utime
5485 case TARGET_NR_utime
:
5487 struct utimbuf tbuf
, *host_tbuf
;
5488 struct target_utimbuf
*target_tbuf
;
5490 if (!lock_user_struct(VERIFY_READ
, target_tbuf
, arg2
, 1))
5492 tbuf
.actime
= tswapal(target_tbuf
->actime
);
5493 tbuf
.modtime
= tswapal(target_tbuf
->modtime
);
5494 unlock_user_struct(target_tbuf
, arg2
, 0);
5499 if (!(p
= lock_user_string(arg1
)))
5501 ret
= get_errno(utime(p
, host_tbuf
));
5502 unlock_user(p
, arg1
, 0);
5506 case TARGET_NR_utimes
:
5508 struct timeval
*tvp
, tv
[2];
5510 if (copy_from_user_timeval(&tv
[0], arg2
)
5511 || copy_from_user_timeval(&tv
[1],
5512 arg2
+ sizeof(struct target_timeval
)))
5518 if (!(p
= lock_user_string(arg1
)))
5520 ret
= get_errno(utimes(p
, tvp
));
5521 unlock_user(p
, arg1
, 0);
5524 #if defined(TARGET_NR_futimesat) && defined(__NR_futimesat)
5525 case TARGET_NR_futimesat
:
5527 struct timeval
*tvp
, tv
[2];
5529 if (copy_from_user_timeval(&tv
[0], arg3
)
5530 || copy_from_user_timeval(&tv
[1],
5531 arg3
+ sizeof(struct target_timeval
)))
5537 if (!(p
= lock_user_string(arg2
)))
5539 ret
= get_errno(sys_futimesat(arg1
, path(p
), tvp
));
5540 unlock_user(p
, arg2
, 0);
5544 #ifdef TARGET_NR_stty
5545 case TARGET_NR_stty
:
5548 #ifdef TARGET_NR_gtty
5549 case TARGET_NR_gtty
:
5552 case TARGET_NR_access
:
5553 if (!(p
= lock_user_string(arg1
)))
5555 ret
= get_errno(access(path(p
), arg2
));
5556 unlock_user(p
, arg1
, 0);
5558 #if defined(TARGET_NR_faccessat) && defined(__NR_faccessat)
5559 case TARGET_NR_faccessat
:
5560 if (!(p
= lock_user_string(arg2
)))
5562 ret
= get_errno(sys_faccessat(arg1
, p
, arg3
));
5563 unlock_user(p
, arg2
, 0);
5566 #ifdef TARGET_NR_nice /* not on alpha */
5567 case TARGET_NR_nice
:
5568 ret
= get_errno(nice(arg1
));
5571 #ifdef TARGET_NR_ftime
5572 case TARGET_NR_ftime
:
5575 case TARGET_NR_sync
:
5579 case TARGET_NR_kill
:
5580 ret
= get_errno(kill(arg1
, target_to_host_signal(arg2
)));
5582 case TARGET_NR_rename
:
5585 p
= lock_user_string(arg1
);
5586 p2
= lock_user_string(arg2
);
5588 ret
= -TARGET_EFAULT
;
5590 ret
= get_errno(rename(p
, p2
));
5591 unlock_user(p2
, arg2
, 0);
5592 unlock_user(p
, arg1
, 0);
5595 #if defined(TARGET_NR_renameat) && defined(__NR_renameat)
5596 case TARGET_NR_renameat
:
5599 p
= lock_user_string(arg2
);
5600 p2
= lock_user_string(arg4
);
5602 ret
= -TARGET_EFAULT
;
5604 ret
= get_errno(sys_renameat(arg1
, p
, arg3
, p2
));
5605 unlock_user(p2
, arg4
, 0);
5606 unlock_user(p
, arg2
, 0);
5610 case TARGET_NR_mkdir
:
5611 if (!(p
= lock_user_string(arg1
)))
5613 ret
= get_errno(mkdir(p
, arg2
));
5614 unlock_user(p
, arg1
, 0);
5616 #if defined(TARGET_NR_mkdirat) && defined(__NR_mkdirat)
5617 case TARGET_NR_mkdirat
:
5618 if (!(p
= lock_user_string(arg2
)))
5620 ret
= get_errno(sys_mkdirat(arg1
, p
, arg3
));
5621 unlock_user(p
, arg2
, 0);
5624 case TARGET_NR_rmdir
:
5625 if (!(p
= lock_user_string(arg1
)))
5627 ret
= get_errno(rmdir(p
));
5628 unlock_user(p
, arg1
, 0);
5631 ret
= get_errno(dup(arg1
));
5633 case TARGET_NR_pipe
:
5634 ret
= do_pipe(cpu_env
, arg1
, 0, 0);
5636 #ifdef TARGET_NR_pipe2
5637 case TARGET_NR_pipe2
:
5638 ret
= do_pipe(cpu_env
, arg1
,
5639 target_to_host_bitmask(arg2
, fcntl_flags_tbl
), 1);
5642 case TARGET_NR_times
:
5644 struct target_tms
*tmsp
;
5646 ret
= get_errno(times(&tms
));
5648 tmsp
= lock_user(VERIFY_WRITE
, arg1
, sizeof(struct target_tms
), 0);
5651 tmsp
->tms_utime
= tswapal(host_to_target_clock_t(tms
.tms_utime
));
5652 tmsp
->tms_stime
= tswapal(host_to_target_clock_t(tms
.tms_stime
));
5653 tmsp
->tms_cutime
= tswapal(host_to_target_clock_t(tms
.tms_cutime
));
5654 tmsp
->tms_cstime
= tswapal(host_to_target_clock_t(tms
.tms_cstime
));
5657 ret
= host_to_target_clock_t(ret
);
5660 #ifdef TARGET_NR_prof
5661 case TARGET_NR_prof
:
5664 #ifdef TARGET_NR_signal
5665 case TARGET_NR_signal
:
5668 case TARGET_NR_acct
:
5670 ret
= get_errno(acct(NULL
));
5672 if (!(p
= lock_user_string(arg1
)))
5674 ret
= get_errno(acct(path(p
)));
5675 unlock_user(p
, arg1
, 0);
5678 #ifdef TARGET_NR_umount2 /* not on alpha */
5679 case TARGET_NR_umount2
:
5680 if (!(p
= lock_user_string(arg1
)))
5682 ret
= get_errno(umount2(p
, arg2
));
5683 unlock_user(p
, arg1
, 0);
5686 #ifdef TARGET_NR_lock
5687 case TARGET_NR_lock
:
5690 case TARGET_NR_ioctl
:
5691 ret
= do_ioctl(arg1
, arg2
, arg3
);
5693 case TARGET_NR_fcntl
:
5694 ret
= do_fcntl(arg1
, arg2
, arg3
);
5696 #ifdef TARGET_NR_mpx
5700 case TARGET_NR_setpgid
:
5701 ret
= get_errno(setpgid(arg1
, arg2
));
5703 #ifdef TARGET_NR_ulimit
5704 case TARGET_NR_ulimit
:
5707 #ifdef TARGET_NR_oldolduname
5708 case TARGET_NR_oldolduname
:
5711 case TARGET_NR_umask
:
5712 ret
= get_errno(umask(arg1
));
5714 case TARGET_NR_chroot
:
5715 if (!(p
= lock_user_string(arg1
)))
5717 ret
= get_errno(chroot(p
));
5718 unlock_user(p
, arg1
, 0);
5720 case TARGET_NR_ustat
:
5722 case TARGET_NR_dup2
:
5723 ret
= get_errno(dup2(arg1
, arg2
));
5725 #if defined(CONFIG_DUP3) && defined(TARGET_NR_dup3)
5726 case TARGET_NR_dup3
:
5727 ret
= get_errno(dup3(arg1
, arg2
, arg3
));
5730 #ifdef TARGET_NR_getppid /* not on alpha */
5731 case TARGET_NR_getppid
:
5732 ret
= get_errno(getppid());
5735 case TARGET_NR_getpgrp
:
5736 ret
= get_errno(getpgrp());
5738 case TARGET_NR_setsid
:
5739 ret
= get_errno(setsid());
5741 #ifdef TARGET_NR_sigaction
5742 case TARGET_NR_sigaction
:
5744 #if defined(TARGET_ALPHA)
5745 struct target_sigaction act
, oact
, *pact
= 0;
5746 struct target_old_sigaction
*old_act
;
5748 if (!lock_user_struct(VERIFY_READ
, old_act
, arg2
, 1))
5750 act
._sa_handler
= old_act
->_sa_handler
;
5751 target_siginitset(&act
.sa_mask
, old_act
->sa_mask
);
5752 act
.sa_flags
= old_act
->sa_flags
;
5753 act
.sa_restorer
= 0;
5754 unlock_user_struct(old_act
, arg2
, 0);
5757 ret
= get_errno(do_sigaction(arg1
, pact
, &oact
));
5758 if (!is_error(ret
) && arg3
) {
5759 if (!lock_user_struct(VERIFY_WRITE
, old_act
, arg3
, 0))
5761 old_act
->_sa_handler
= oact
._sa_handler
;
5762 old_act
->sa_mask
= oact
.sa_mask
.sig
[0];
5763 old_act
->sa_flags
= oact
.sa_flags
;
5764 unlock_user_struct(old_act
, arg3
, 1);
5766 #elif defined(TARGET_MIPS)
5767 struct target_sigaction act
, oact
, *pact
, *old_act
;
5770 if (!lock_user_struct(VERIFY_READ
, old_act
, arg2
, 1))
5772 act
._sa_handler
= old_act
->_sa_handler
;
5773 target_siginitset(&act
.sa_mask
, old_act
->sa_mask
.sig
[0]);
5774 act
.sa_flags
= old_act
->sa_flags
;
5775 unlock_user_struct(old_act
, arg2
, 0);
5781 ret
= get_errno(do_sigaction(arg1
, pact
, &oact
));
5783 if (!is_error(ret
) && arg3
) {
5784 if (!lock_user_struct(VERIFY_WRITE
, old_act
, arg3
, 0))
5786 old_act
->_sa_handler
= oact
._sa_handler
;
5787 old_act
->sa_flags
= oact
.sa_flags
;
5788 old_act
->sa_mask
.sig
[0] = oact
.sa_mask
.sig
[0];
5789 old_act
->sa_mask
.sig
[1] = 0;
5790 old_act
->sa_mask
.sig
[2] = 0;
5791 old_act
->sa_mask
.sig
[3] = 0;
5792 unlock_user_struct(old_act
, arg3
, 1);
5795 struct target_old_sigaction
*old_act
;
5796 struct target_sigaction act
, oact
, *pact
;
5798 if (!lock_user_struct(VERIFY_READ
, old_act
, arg2
, 1))
5800 act
._sa_handler
= old_act
->_sa_handler
;
5801 target_siginitset(&act
.sa_mask
, old_act
->sa_mask
);
5802 act
.sa_flags
= old_act
->sa_flags
;
5803 act
.sa_restorer
= old_act
->sa_restorer
;
5804 unlock_user_struct(old_act
, arg2
, 0);
5809 ret
= get_errno(do_sigaction(arg1
, pact
, &oact
));
5810 if (!is_error(ret
) && arg3
) {
5811 if (!lock_user_struct(VERIFY_WRITE
, old_act
, arg3
, 0))
5813 old_act
->_sa_handler
= oact
._sa_handler
;
5814 old_act
->sa_mask
= oact
.sa_mask
.sig
[0];
5815 old_act
->sa_flags
= oact
.sa_flags
;
5816 old_act
->sa_restorer
= oact
.sa_restorer
;
5817 unlock_user_struct(old_act
, arg3
, 1);
5823 case TARGET_NR_rt_sigaction
:
5825 #if defined(TARGET_ALPHA)
5826 struct target_sigaction act
, oact
, *pact
= 0;
5827 struct target_rt_sigaction
*rt_act
;
5828 /* ??? arg4 == sizeof(sigset_t). */
5830 if (!lock_user_struct(VERIFY_READ
, rt_act
, arg2
, 1))
5832 act
._sa_handler
= rt_act
->_sa_handler
;
5833 act
.sa_mask
= rt_act
->sa_mask
;
5834 act
.sa_flags
= rt_act
->sa_flags
;
5835 act
.sa_restorer
= arg5
;
5836 unlock_user_struct(rt_act
, arg2
, 0);
5839 ret
= get_errno(do_sigaction(arg1
, pact
, &oact
));
5840 if (!is_error(ret
) && arg3
) {
5841 if (!lock_user_struct(VERIFY_WRITE
, rt_act
, arg3
, 0))
5843 rt_act
->_sa_handler
= oact
._sa_handler
;
5844 rt_act
->sa_mask
= oact
.sa_mask
;
5845 rt_act
->sa_flags
= oact
.sa_flags
;
5846 unlock_user_struct(rt_act
, arg3
, 1);
5849 struct target_sigaction
*act
;
5850 struct target_sigaction
*oact
;
5853 if (!lock_user_struct(VERIFY_READ
, act
, arg2
, 1))
5858 if (!lock_user_struct(VERIFY_WRITE
, oact
, arg3
, 0)) {
5859 ret
= -TARGET_EFAULT
;
5860 goto rt_sigaction_fail
;
5864 ret
= get_errno(do_sigaction(arg1
, act
, oact
));
5867 unlock_user_struct(act
, arg2
, 0);
5869 unlock_user_struct(oact
, arg3
, 1);
5873 #ifdef TARGET_NR_sgetmask /* not on alpha */
5874 case TARGET_NR_sgetmask
:
5877 abi_ulong target_set
;
5878 sigprocmask(0, NULL
, &cur_set
);
5879 host_to_target_old_sigset(&target_set
, &cur_set
);
5884 #ifdef TARGET_NR_ssetmask /* not on alpha */
5885 case TARGET_NR_ssetmask
:
5887 sigset_t set
, oset
, cur_set
;
5888 abi_ulong target_set
= arg1
;
5889 sigprocmask(0, NULL
, &cur_set
);
5890 target_to_host_old_sigset(&set
, &target_set
);
5891 sigorset(&set
, &set
, &cur_set
);
5892 sigprocmask(SIG_SETMASK
, &set
, &oset
);
5893 host_to_target_old_sigset(&target_set
, &oset
);
5898 #ifdef TARGET_NR_sigprocmask
5899 case TARGET_NR_sigprocmask
:
5901 #if defined(TARGET_ALPHA)
5902 sigset_t set
, oldset
;
5907 case TARGET_SIG_BLOCK
:
5910 case TARGET_SIG_UNBLOCK
:
5913 case TARGET_SIG_SETMASK
:
5917 ret
= -TARGET_EINVAL
;
5921 target_to_host_old_sigset(&set
, &mask
);
5923 ret
= get_errno(sigprocmask(how
, &set
, &oldset
));
5924 if (!is_error(ret
)) {
5925 host_to_target_old_sigset(&mask
, &oldset
);
5927 ((CPUAlphaState
*)cpu_env
)->ir
[IR_V0
] = 0; /* force no error */
5930 sigset_t set
, oldset
, *set_ptr
;
5935 case TARGET_SIG_BLOCK
:
5938 case TARGET_SIG_UNBLOCK
:
5941 case TARGET_SIG_SETMASK
:
5945 ret
= -TARGET_EINVAL
;
5948 if (!(p
= lock_user(VERIFY_READ
, arg2
, sizeof(target_sigset_t
), 1)))
5950 target_to_host_old_sigset(&set
, p
);
5951 unlock_user(p
, arg2
, 0);
5957 ret
= get_errno(sigprocmask(how
, set_ptr
, &oldset
));
5958 if (!is_error(ret
) && arg3
) {
5959 if (!(p
= lock_user(VERIFY_WRITE
, arg3
, sizeof(target_sigset_t
), 0)))
5961 host_to_target_old_sigset(p
, &oldset
);
5962 unlock_user(p
, arg3
, sizeof(target_sigset_t
));
5968 case TARGET_NR_rt_sigprocmask
:
5971 sigset_t set
, oldset
, *set_ptr
;
5975 case TARGET_SIG_BLOCK
:
5978 case TARGET_SIG_UNBLOCK
:
5981 case TARGET_SIG_SETMASK
:
5985 ret
= -TARGET_EINVAL
;
5988 if (!(p
= lock_user(VERIFY_READ
, arg2
, sizeof(target_sigset_t
), 1)))
5990 target_to_host_sigset(&set
, p
);
5991 unlock_user(p
, arg2
, 0);
5997 ret
= get_errno(sigprocmask(how
, set_ptr
, &oldset
));
5998 if (!is_error(ret
) && arg3
) {
5999 if (!(p
= lock_user(VERIFY_WRITE
, arg3
, sizeof(target_sigset_t
), 0)))
6001 host_to_target_sigset(p
, &oldset
);
6002 unlock_user(p
, arg3
, sizeof(target_sigset_t
));
6006 #ifdef TARGET_NR_sigpending
6007 case TARGET_NR_sigpending
:
6010 ret
= get_errno(sigpending(&set
));
6011 if (!is_error(ret
)) {
6012 if (!(p
= lock_user(VERIFY_WRITE
, arg1
, sizeof(target_sigset_t
), 0)))
6014 host_to_target_old_sigset(p
, &set
);
6015 unlock_user(p
, arg1
, sizeof(target_sigset_t
));
6020 case TARGET_NR_rt_sigpending
:
6023 ret
= get_errno(sigpending(&set
));
6024 if (!is_error(ret
)) {
6025 if (!(p
= lock_user(VERIFY_WRITE
, arg1
, sizeof(target_sigset_t
), 0)))
6027 host_to_target_sigset(p
, &set
);
6028 unlock_user(p
, arg1
, sizeof(target_sigset_t
));
6032 #ifdef TARGET_NR_sigsuspend
6033 case TARGET_NR_sigsuspend
:
6036 #if defined(TARGET_ALPHA)
6037 abi_ulong mask
= arg1
;
6038 target_to_host_old_sigset(&set
, &mask
);
6040 if (!(p
= lock_user(VERIFY_READ
, arg1
, sizeof(target_sigset_t
), 1)))
6042 target_to_host_old_sigset(&set
, p
);
6043 unlock_user(p
, arg1
, 0);
6045 ret
= get_errno(sigsuspend(&set
));
6049 case TARGET_NR_rt_sigsuspend
:
6052 if (!(p
= lock_user(VERIFY_READ
, arg1
, sizeof(target_sigset_t
), 1)))
6054 target_to_host_sigset(&set
, p
);
6055 unlock_user(p
, arg1
, 0);
6056 ret
= get_errno(sigsuspend(&set
));
6059 case TARGET_NR_rt_sigtimedwait
:
6062 struct timespec uts
, *puts
;
6065 if (!(p
= lock_user(VERIFY_READ
, arg1
, sizeof(target_sigset_t
), 1)))
6067 target_to_host_sigset(&set
, p
);
6068 unlock_user(p
, arg1
, 0);
6071 target_to_host_timespec(puts
, arg3
);
6075 ret
= get_errno(sigtimedwait(&set
, &uinfo
, puts
));
6076 if (!is_error(ret
) && arg2
) {
6077 if (!(p
= lock_user(VERIFY_WRITE
, arg2
, sizeof(target_siginfo_t
), 0)))
6079 host_to_target_siginfo(p
, &uinfo
);
6080 unlock_user(p
, arg2
, sizeof(target_siginfo_t
));
6084 case TARGET_NR_rt_sigqueueinfo
:
6087 if (!(p
= lock_user(VERIFY_READ
, arg3
, sizeof(target_sigset_t
), 1)))
6089 target_to_host_siginfo(&uinfo
, p
);
6090 unlock_user(p
, arg1
, 0);
6091 ret
= get_errno(sys_rt_sigqueueinfo(arg1
, arg2
, &uinfo
));
6094 #ifdef TARGET_NR_sigreturn
6095 case TARGET_NR_sigreturn
:
6096 /* NOTE: ret is eax, so not transcoding must be done */
6097 ret
= do_sigreturn(cpu_env
);
6100 case TARGET_NR_rt_sigreturn
:
6101 /* NOTE: ret is eax, so not transcoding must be done */
6102 ret
= do_rt_sigreturn(cpu_env
);
6104 case TARGET_NR_sethostname
:
6105 if (!(p
= lock_user_string(arg1
)))
6107 ret
= get_errno(sethostname(p
, arg2
));
6108 unlock_user(p
, arg1
, 0);
6110 case TARGET_NR_setrlimit
:
6112 int resource
= target_to_host_resource(arg1
);
6113 struct target_rlimit
*target_rlim
;
6115 if (!lock_user_struct(VERIFY_READ
, target_rlim
, arg2
, 1))
6117 rlim
.rlim_cur
= target_to_host_rlim(target_rlim
->rlim_cur
);
6118 rlim
.rlim_max
= target_to_host_rlim(target_rlim
->rlim_max
);
6119 unlock_user_struct(target_rlim
, arg2
, 0);
6120 ret
= get_errno(setrlimit(resource
, &rlim
));
6123 case TARGET_NR_getrlimit
:
6125 int resource
= target_to_host_resource(arg1
);
6126 struct target_rlimit
*target_rlim
;
6129 ret
= get_errno(getrlimit(resource
, &rlim
));
6130 if (!is_error(ret
)) {
6131 if (!lock_user_struct(VERIFY_WRITE
, target_rlim
, arg2
, 0))
6133 target_rlim
->rlim_cur
= host_to_target_rlim(rlim
.rlim_cur
);
6134 target_rlim
->rlim_max
= host_to_target_rlim(rlim
.rlim_max
);
6135 unlock_user_struct(target_rlim
, arg2
, 1);
6139 case TARGET_NR_getrusage
:
6141 struct rusage rusage
;
6142 ret
= get_errno(getrusage(arg1
, &rusage
));
6143 if (!is_error(ret
)) {
6144 host_to_target_rusage(arg2
, &rusage
);
6148 case TARGET_NR_gettimeofday
:
6151 ret
= get_errno(gettimeofday(&tv
, NULL
));
6152 if (!is_error(ret
)) {
6153 if (copy_to_user_timeval(arg1
, &tv
))
6158 case TARGET_NR_settimeofday
:
6161 if (copy_from_user_timeval(&tv
, arg1
))
6163 ret
= get_errno(settimeofday(&tv
, NULL
));
6166 #if defined(TARGET_NR_select) && !defined(TARGET_S390X) && !defined(TARGET_S390)
6167 case TARGET_NR_select
:
6169 struct target_sel_arg_struct
*sel
;
6170 abi_ulong inp
, outp
, exp
, tvp
;
6173 if (!lock_user_struct(VERIFY_READ
, sel
, arg1
, 1))
6175 nsel
= tswapal(sel
->n
);
6176 inp
= tswapal(sel
->inp
);
6177 outp
= tswapal(sel
->outp
);
6178 exp
= tswapal(sel
->exp
);
6179 tvp
= tswapal(sel
->tvp
);
6180 unlock_user_struct(sel
, arg1
, 0);
6181 ret
= do_select(nsel
, inp
, outp
, exp
, tvp
);
6185 #ifdef TARGET_NR_pselect6
6186 case TARGET_NR_pselect6
:
6188 abi_long rfd_addr
, wfd_addr
, efd_addr
, n
, ts_addr
;
6189 fd_set rfds
, wfds
, efds
;
6190 fd_set
*rfds_ptr
, *wfds_ptr
, *efds_ptr
;
6191 struct timespec ts
, *ts_ptr
;
6194 * The 6th arg is actually two args smashed together,
6195 * so we cannot use the C library.
6203 abi_ulong arg_sigset
, arg_sigsize
, *arg7
;
6204 target_sigset_t
*target_sigset
;
6212 ret
= copy_from_user_fdset_ptr(&rfds
, &rfds_ptr
, rfd_addr
, n
);
6216 ret
= copy_from_user_fdset_ptr(&wfds
, &wfds_ptr
, wfd_addr
, n
);
6220 ret
= copy_from_user_fdset_ptr(&efds
, &efds_ptr
, efd_addr
, n
);
6226 * This takes a timespec, and not a timeval, so we cannot
6227 * use the do_select() helper ...
6230 if (target_to_host_timespec(&ts
, ts_addr
)) {
6238 /* Extract the two packed args for the sigset */
6241 sig
.size
= _NSIG
/ 8;
6243 arg7
= lock_user(VERIFY_READ
, arg6
, sizeof(*arg7
) * 2, 1);
6247 arg_sigset
= tswapal(arg7
[0]);
6248 arg_sigsize
= tswapal(arg7
[1]);
6249 unlock_user(arg7
, arg6
, 0);
6253 if (arg_sigsize
!= sizeof(*target_sigset
)) {
6254 /* Like the kernel, we enforce correct size sigsets */
6255 ret
= -TARGET_EINVAL
;
6258 target_sigset
= lock_user(VERIFY_READ
, arg_sigset
,
6259 sizeof(*target_sigset
), 1);
6260 if (!target_sigset
) {
6263 target_to_host_sigset(&set
, target_sigset
);
6264 unlock_user(target_sigset
, arg_sigset
, 0);
6272 ret
= get_errno(sys_pselect6(n
, rfds_ptr
, wfds_ptr
, efds_ptr
,
6275 if (!is_error(ret
)) {
6276 if (rfd_addr
&& copy_to_user_fdset(rfd_addr
, &rfds
, n
))
6278 if (wfd_addr
&& copy_to_user_fdset(wfd_addr
, &wfds
, n
))
6280 if (efd_addr
&& copy_to_user_fdset(efd_addr
, &efds
, n
))
6283 if (ts_addr
&& host_to_target_timespec(ts_addr
, &ts
))
6289 case TARGET_NR_symlink
:
6292 p
= lock_user_string(arg1
);
6293 p2
= lock_user_string(arg2
);
6295 ret
= -TARGET_EFAULT
;
6297 ret
= get_errno(symlink(p
, p2
));
6298 unlock_user(p2
, arg2
, 0);
6299 unlock_user(p
, arg1
, 0);
6302 #if defined(TARGET_NR_symlinkat) && defined(__NR_symlinkat)
6303 case TARGET_NR_symlinkat
:
6306 p
= lock_user_string(arg1
);
6307 p2
= lock_user_string(arg3
);
6309 ret
= -TARGET_EFAULT
;
6311 ret
= get_errno(sys_symlinkat(p
, arg2
, p2
));
6312 unlock_user(p2
, arg3
, 0);
6313 unlock_user(p
, arg1
, 0);
6317 #ifdef TARGET_NR_oldlstat
6318 case TARGET_NR_oldlstat
:
6321 case TARGET_NR_readlink
:
6324 p
= lock_user_string(arg1
);
6325 p2
= lock_user(VERIFY_WRITE
, arg2
, arg3
, 0);
6327 ret
= -TARGET_EFAULT
;
6329 if (strncmp((const char *)p
, "/proc/self/exe", 14) == 0) {
6330 char real
[PATH_MAX
];
6331 temp
= realpath(exec_path
,real
);
6332 ret
= (temp
==NULL
) ? get_errno(-1) : strlen(real
) ;
6333 snprintf((char *)p2
, arg3
, "%s", real
);
6336 ret
= get_errno(readlink(path(p
), p2
, arg3
));
6338 unlock_user(p2
, arg2
, ret
);
6339 unlock_user(p
, arg1
, 0);
6342 #if defined(TARGET_NR_readlinkat) && defined(__NR_readlinkat)
6343 case TARGET_NR_readlinkat
:
6346 p
= lock_user_string(arg2
);
6347 p2
= lock_user(VERIFY_WRITE
, arg3
, arg4
, 0);
6349 ret
= -TARGET_EFAULT
;
6351 ret
= get_errno(sys_readlinkat(arg1
, path(p
), p2
, arg4
));
6352 unlock_user(p2
, arg3
, ret
);
6353 unlock_user(p
, arg2
, 0);
6357 #ifdef TARGET_NR_uselib
6358 case TARGET_NR_uselib
:
6361 #ifdef TARGET_NR_swapon
6362 case TARGET_NR_swapon
:
6363 if (!(p
= lock_user_string(arg1
)))
6365 ret
= get_errno(swapon(p
, arg2
));
6366 unlock_user(p
, arg1
, 0);
6369 case TARGET_NR_reboot
:
6370 if (!(p
= lock_user_string(arg4
)))
6372 ret
= reboot(arg1
, arg2
, arg3
, p
);
6373 unlock_user(p
, arg4
, 0);
6375 #ifdef TARGET_NR_readdir
6376 case TARGET_NR_readdir
:
6379 #ifdef TARGET_NR_mmap
6380 case TARGET_NR_mmap
:
6381 #if (defined(TARGET_I386) && defined(TARGET_ABI32)) || defined(TARGET_ARM) || \
6382 defined(TARGET_M68K) || defined(TARGET_CRIS) || defined(TARGET_MICROBLAZE) \
6383 || defined(TARGET_S390X)
6386 abi_ulong v1
, v2
, v3
, v4
, v5
, v6
;
6387 if (!(v
= lock_user(VERIFY_READ
, arg1
, 6 * sizeof(abi_ulong
), 1)))
6395 unlock_user(v
, arg1
, 0);
6396 ret
= get_errno(target_mmap(v1
, v2
, v3
,
6397 target_to_host_bitmask(v4
, mmap_flags_tbl
),
6401 ret
= get_errno(target_mmap(arg1
, arg2
, arg3
,
6402 target_to_host_bitmask(arg4
, mmap_flags_tbl
),
6408 #ifdef TARGET_NR_mmap2
6409 case TARGET_NR_mmap2
:
6411 #define MMAP_SHIFT 12
6413 ret
= get_errno(target_mmap(arg1
, arg2
, arg3
,
6414 target_to_host_bitmask(arg4
, mmap_flags_tbl
),
6416 arg6
<< MMAP_SHIFT
));
6419 case TARGET_NR_munmap
:
6420 ret
= get_errno(target_munmap(arg1
, arg2
));
6422 case TARGET_NR_mprotect
:
6424 TaskState
*ts
= ((CPUArchState
*)cpu_env
)->opaque
;
6425 /* Special hack to detect libc making the stack executable. */
6426 if ((arg3
& PROT_GROWSDOWN
)
6427 && arg1
>= ts
->info
->stack_limit
6428 && arg1
<= ts
->info
->start_stack
) {
6429 arg3
&= ~PROT_GROWSDOWN
;
6430 arg2
= arg2
+ arg1
- ts
->info
->stack_limit
;
6431 arg1
= ts
->info
->stack_limit
;
6434 ret
= get_errno(target_mprotect(arg1
, arg2
, arg3
));
6436 #ifdef TARGET_NR_mremap
6437 case TARGET_NR_mremap
:
6438 ret
= get_errno(target_mremap(arg1
, arg2
, arg3
, arg4
, arg5
));
6441 /* ??? msync/mlock/munlock are broken for softmmu. */
6442 #ifdef TARGET_NR_msync
6443 case TARGET_NR_msync
:
6444 ret
= get_errno(msync(g2h(arg1
), arg2
, arg3
));
6447 #ifdef TARGET_NR_mlock
6448 case TARGET_NR_mlock
:
6449 ret
= get_errno(mlock(g2h(arg1
), arg2
));
6452 #ifdef TARGET_NR_munlock
6453 case TARGET_NR_munlock
:
6454 ret
= get_errno(munlock(g2h(arg1
), arg2
));
6457 #ifdef TARGET_NR_mlockall
6458 case TARGET_NR_mlockall
:
6459 ret
= get_errno(mlockall(arg1
));
6462 #ifdef TARGET_NR_munlockall
6463 case TARGET_NR_munlockall
:
6464 ret
= get_errno(munlockall());
6467 case TARGET_NR_truncate
:
6468 if (!(p
= lock_user_string(arg1
)))
6470 ret
= get_errno(truncate(p
, arg2
));
6471 unlock_user(p
, arg1
, 0);
6473 case TARGET_NR_ftruncate
:
6474 ret
= get_errno(ftruncate(arg1
, arg2
));
6476 case TARGET_NR_fchmod
:
6477 ret
= get_errno(fchmod(arg1
, arg2
));
6479 #if defined(TARGET_NR_fchmodat) && defined(__NR_fchmodat)
6480 case TARGET_NR_fchmodat
:
6481 if (!(p
= lock_user_string(arg2
)))
6483 ret
= get_errno(sys_fchmodat(arg1
, p
, arg3
));
6484 unlock_user(p
, arg2
, 0);
6487 case TARGET_NR_getpriority
:
6488 /* Note that negative values are valid for getpriority, so we must
6489 differentiate based on errno settings. */
6491 ret
= getpriority(arg1
, arg2
);
6492 if (ret
== -1 && errno
!= 0) {
6493 ret
= -host_to_target_errno(errno
);
6497 /* Return value is the unbiased priority. Signal no error. */
6498 ((CPUAlphaState
*)cpu_env
)->ir
[IR_V0
] = 0;
6500 /* Return value is a biased priority to avoid negative numbers. */
6504 case TARGET_NR_setpriority
:
6505 ret
= get_errno(setpriority(arg1
, arg2
, arg3
));
6507 #ifdef TARGET_NR_profil
6508 case TARGET_NR_profil
:
6511 case TARGET_NR_statfs
:
6512 if (!(p
= lock_user_string(arg1
)))
6514 ret
= get_errno(statfs(path(p
), &stfs
));
6515 unlock_user(p
, arg1
, 0);
6517 if (!is_error(ret
)) {
6518 struct target_statfs
*target_stfs
;
6520 if (!lock_user_struct(VERIFY_WRITE
, target_stfs
, arg2
, 0))
6522 __put_user(stfs
.f_type
, &target_stfs
->f_type
);
6523 __put_user(stfs
.f_bsize
, &target_stfs
->f_bsize
);
6524 __put_user(stfs
.f_blocks
, &target_stfs
->f_blocks
);
6525 __put_user(stfs
.f_bfree
, &target_stfs
->f_bfree
);
6526 __put_user(stfs
.f_bavail
, &target_stfs
->f_bavail
);
6527 __put_user(stfs
.f_files
, &target_stfs
->f_files
);
6528 __put_user(stfs
.f_ffree
, &target_stfs
->f_ffree
);
6529 __put_user(stfs
.f_fsid
.__val
[0], &target_stfs
->f_fsid
.val
[0]);
6530 __put_user(stfs
.f_fsid
.__val
[1], &target_stfs
->f_fsid
.val
[1]);
6531 __put_user(stfs
.f_namelen
, &target_stfs
->f_namelen
);
6532 unlock_user_struct(target_stfs
, arg2
, 1);
6535 case TARGET_NR_fstatfs
:
6536 ret
= get_errno(fstatfs(arg1
, &stfs
));
6537 goto convert_statfs
;
6538 #ifdef TARGET_NR_statfs64
6539 case TARGET_NR_statfs64
:
6540 if (!(p
= lock_user_string(arg1
)))
6542 ret
= get_errno(statfs(path(p
), &stfs
));
6543 unlock_user(p
, arg1
, 0);
6545 if (!is_error(ret
)) {
6546 struct target_statfs64
*target_stfs
;
6548 if (!lock_user_struct(VERIFY_WRITE
, target_stfs
, arg3
, 0))
6550 __put_user(stfs
.f_type
, &target_stfs
->f_type
);
6551 __put_user(stfs
.f_bsize
, &target_stfs
->f_bsize
);
6552 __put_user(stfs
.f_blocks
, &target_stfs
->f_blocks
);
6553 __put_user(stfs
.f_bfree
, &target_stfs
->f_bfree
);
6554 __put_user(stfs
.f_bavail
, &target_stfs
->f_bavail
);
6555 __put_user(stfs
.f_files
, &target_stfs
->f_files
);
6556 __put_user(stfs
.f_ffree
, &target_stfs
->f_ffree
);
6557 __put_user(stfs
.f_fsid
.__val
[0], &target_stfs
->f_fsid
.val
[0]);
6558 __put_user(stfs
.f_fsid
.__val
[1], &target_stfs
->f_fsid
.val
[1]);
6559 __put_user(stfs
.f_namelen
, &target_stfs
->f_namelen
);
6560 unlock_user_struct(target_stfs
, arg3
, 1);
6563 case TARGET_NR_fstatfs64
:
6564 ret
= get_errno(fstatfs(arg1
, &stfs
));
6565 goto convert_statfs64
;
6567 #ifdef TARGET_NR_ioperm
6568 case TARGET_NR_ioperm
:
6571 #ifdef TARGET_NR_socketcall
6572 case TARGET_NR_socketcall
:
6573 ret
= do_socketcall(arg1
, arg2
);
6576 #ifdef TARGET_NR_accept
6577 case TARGET_NR_accept
:
6578 ret
= do_accept(arg1
, arg2
, arg3
);
6581 #ifdef TARGET_NR_bind
6582 case TARGET_NR_bind
:
6583 ret
= do_bind(arg1
, arg2
, arg3
);
6586 #ifdef TARGET_NR_connect
6587 case TARGET_NR_connect
:
6588 ret
= do_connect(arg1
, arg2
, arg3
);
6591 #ifdef TARGET_NR_getpeername
6592 case TARGET_NR_getpeername
:
6593 ret
= do_getpeername(arg1
, arg2
, arg3
);
6596 #ifdef TARGET_NR_getsockname
6597 case TARGET_NR_getsockname
:
6598 ret
= do_getsockname(arg1
, arg2
, arg3
);
6601 #ifdef TARGET_NR_getsockopt
6602 case TARGET_NR_getsockopt
:
6603 ret
= do_getsockopt(arg1
, arg2
, arg3
, arg4
, arg5
);
6606 #ifdef TARGET_NR_listen
6607 case TARGET_NR_listen
:
6608 ret
= get_errno(listen(arg1
, arg2
));
6611 #ifdef TARGET_NR_recv
6612 case TARGET_NR_recv
:
6613 ret
= do_recvfrom(arg1
, arg2
, arg3
, arg4
, 0, 0);
6616 #ifdef TARGET_NR_recvfrom
6617 case TARGET_NR_recvfrom
:
6618 ret
= do_recvfrom(arg1
, arg2
, arg3
, arg4
, arg5
, arg6
);
6621 #ifdef TARGET_NR_recvmsg
6622 case TARGET_NR_recvmsg
:
6623 ret
= do_sendrecvmsg(arg1
, arg2
, arg3
, 0);
6626 #ifdef TARGET_NR_send
6627 case TARGET_NR_send
:
6628 ret
= do_sendto(arg1
, arg2
, arg3
, arg4
, 0, 0);
6631 #ifdef TARGET_NR_sendmsg
6632 case TARGET_NR_sendmsg
:
6633 ret
= do_sendrecvmsg(arg1
, arg2
, arg3
, 1);
6636 #ifdef TARGET_NR_sendto
6637 case TARGET_NR_sendto
:
6638 ret
= do_sendto(arg1
, arg2
, arg3
, arg4
, arg5
, arg6
);
6641 #ifdef TARGET_NR_shutdown
6642 case TARGET_NR_shutdown
:
6643 ret
= get_errno(shutdown(arg1
, arg2
));
6646 #ifdef TARGET_NR_socket
6647 case TARGET_NR_socket
:
6648 ret
= do_socket(arg1
, arg2
, arg3
);
6651 #ifdef TARGET_NR_socketpair
6652 case TARGET_NR_socketpair
:
6653 ret
= do_socketpair(arg1
, arg2
, arg3
, arg4
);
6656 #ifdef TARGET_NR_setsockopt
6657 case TARGET_NR_setsockopt
:
6658 ret
= do_setsockopt(arg1
, arg2
, arg3
, arg4
, (socklen_t
) arg5
);
6662 case TARGET_NR_syslog
:
6663 if (!(p
= lock_user_string(arg2
)))
6665 ret
= get_errno(sys_syslog((int)arg1
, p
, (int)arg3
));
6666 unlock_user(p
, arg2
, 0);
6669 case TARGET_NR_setitimer
:
6671 struct itimerval value
, ovalue
, *pvalue
;
6675 if (copy_from_user_timeval(&pvalue
->it_interval
, arg2
)
6676 || copy_from_user_timeval(&pvalue
->it_value
,
6677 arg2
+ sizeof(struct target_timeval
)))
6682 ret
= get_errno(setitimer(arg1
, pvalue
, &ovalue
));
6683 if (!is_error(ret
) && arg3
) {
6684 if (copy_to_user_timeval(arg3
,
6685 &ovalue
.it_interval
)
6686 || copy_to_user_timeval(arg3
+ sizeof(struct target_timeval
),
6692 case TARGET_NR_getitimer
:
6694 struct itimerval value
;
6696 ret
= get_errno(getitimer(arg1
, &value
));
6697 if (!is_error(ret
) && arg2
) {
6698 if (copy_to_user_timeval(arg2
,
6700 || copy_to_user_timeval(arg2
+ sizeof(struct target_timeval
),
6706 case TARGET_NR_stat
:
6707 if (!(p
= lock_user_string(arg1
)))
6709 ret
= get_errno(stat(path(p
), &st
));
6710 unlock_user(p
, arg1
, 0);
6712 case TARGET_NR_lstat
:
6713 if (!(p
= lock_user_string(arg1
)))
6715 ret
= get_errno(lstat(path(p
), &st
));
6716 unlock_user(p
, arg1
, 0);
6718 case TARGET_NR_fstat
:
6720 ret
= get_errno(fstat(arg1
, &st
));
6722 if (!is_error(ret
)) {
6723 struct target_stat
*target_st
;
6725 if (!lock_user_struct(VERIFY_WRITE
, target_st
, arg2
, 0))
6727 memset(target_st
, 0, sizeof(*target_st
));
6728 __put_user(st
.st_dev
, &target_st
->st_dev
);
6729 __put_user(st
.st_ino
, &target_st
->st_ino
);
6730 __put_user(st
.st_mode
, &target_st
->st_mode
);
6731 __put_user(st
.st_uid
, &target_st
->st_uid
);
6732 __put_user(st
.st_gid
, &target_st
->st_gid
);
6733 __put_user(st
.st_nlink
, &target_st
->st_nlink
);
6734 __put_user(st
.st_rdev
, &target_st
->st_rdev
);
6735 __put_user(st
.st_size
, &target_st
->st_size
);
6736 __put_user(st
.st_blksize
, &target_st
->st_blksize
);
6737 __put_user(st
.st_blocks
, &target_st
->st_blocks
);
6738 __put_user(st
.st_atime
, &target_st
->target_st_atime
);
6739 __put_user(st
.st_mtime
, &target_st
->target_st_mtime
);
6740 __put_user(st
.st_ctime
, &target_st
->target_st_ctime
);
6741 unlock_user_struct(target_st
, arg2
, 1);
6745 #ifdef TARGET_NR_olduname
6746 case TARGET_NR_olduname
:
6749 #ifdef TARGET_NR_iopl
6750 case TARGET_NR_iopl
:
6753 case TARGET_NR_vhangup
:
6754 ret
= get_errno(vhangup());
6756 #ifdef TARGET_NR_idle
6757 case TARGET_NR_idle
:
6760 #ifdef TARGET_NR_syscall
6761 case TARGET_NR_syscall
:
6762 ret
= do_syscall(cpu_env
, arg1
& 0xffff, arg2
, arg3
, arg4
, arg5
,
6763 arg6
, arg7
, arg8
, 0);
6766 case TARGET_NR_wait4
:
6769 abi_long status_ptr
= arg2
;
6770 struct rusage rusage
, *rusage_ptr
;
6771 abi_ulong target_rusage
= arg4
;
6773 rusage_ptr
= &rusage
;
6776 ret
= get_errno(wait4(arg1
, &status
, arg3
, rusage_ptr
));
6777 if (!is_error(ret
)) {
6778 if (status_ptr
&& ret
) {
6779 status
= host_to_target_waitstatus(status
);
6780 if (put_user_s32(status
, status_ptr
))
6784 host_to_target_rusage(target_rusage
, &rusage
);
6788 #ifdef TARGET_NR_swapoff
6789 case TARGET_NR_swapoff
:
6790 if (!(p
= lock_user_string(arg1
)))
6792 ret
= get_errno(swapoff(p
));
6793 unlock_user(p
, arg1
, 0);
6796 case TARGET_NR_sysinfo
:
6798 struct target_sysinfo
*target_value
;
6799 struct sysinfo value
;
6800 ret
= get_errno(sysinfo(&value
));
6801 if (!is_error(ret
) && arg1
)
6803 if (!lock_user_struct(VERIFY_WRITE
, target_value
, arg1
, 0))
6805 __put_user(value
.uptime
, &target_value
->uptime
);
6806 __put_user(value
.loads
[0], &target_value
->loads
[0]);
6807 __put_user(value
.loads
[1], &target_value
->loads
[1]);
6808 __put_user(value
.loads
[2], &target_value
->loads
[2]);
6809 __put_user(value
.totalram
, &target_value
->totalram
);
6810 __put_user(value
.freeram
, &target_value
->freeram
);
6811 __put_user(value
.sharedram
, &target_value
->sharedram
);
6812 __put_user(value
.bufferram
, &target_value
->bufferram
);
6813 __put_user(value
.totalswap
, &target_value
->totalswap
);
6814 __put_user(value
.freeswap
, &target_value
->freeswap
);
6815 __put_user(value
.procs
, &target_value
->procs
);
6816 __put_user(value
.totalhigh
, &target_value
->totalhigh
);
6817 __put_user(value
.freehigh
, &target_value
->freehigh
);
6818 __put_user(value
.mem_unit
, &target_value
->mem_unit
);
6819 unlock_user_struct(target_value
, arg1
, 1);
6823 #ifdef TARGET_NR_ipc
6825 ret
= do_ipc(arg1
, arg2
, arg3
, arg4
, arg5
, arg6
);
6828 #ifdef TARGET_NR_semget
6829 case TARGET_NR_semget
:
6830 ret
= get_errno(semget(arg1
, arg2
, arg3
));
6833 #ifdef TARGET_NR_semop
6834 case TARGET_NR_semop
:
6835 ret
= get_errno(do_semop(arg1
, arg2
, arg3
));
6838 #ifdef TARGET_NR_semctl
6839 case TARGET_NR_semctl
:
6840 ret
= do_semctl(arg1
, arg2
, arg3
, (union target_semun
)(abi_ulong
)arg4
);
6843 #ifdef TARGET_NR_msgctl
6844 case TARGET_NR_msgctl
:
6845 ret
= do_msgctl(arg1
, arg2
, arg3
);
6848 #ifdef TARGET_NR_msgget
6849 case TARGET_NR_msgget
:
6850 ret
= get_errno(msgget(arg1
, arg2
));
6853 #ifdef TARGET_NR_msgrcv
6854 case TARGET_NR_msgrcv
:
6855 ret
= do_msgrcv(arg1
, arg2
, arg3
, arg4
, arg5
);
6858 #ifdef TARGET_NR_msgsnd
6859 case TARGET_NR_msgsnd
:
6860 ret
= do_msgsnd(arg1
, arg2
, arg3
, arg4
);
6863 #ifdef TARGET_NR_shmget
6864 case TARGET_NR_shmget
:
6865 ret
= get_errno(shmget(arg1
, arg2
, arg3
));
6868 #ifdef TARGET_NR_shmctl
6869 case TARGET_NR_shmctl
:
6870 ret
= do_shmctl(arg1
, arg2
, arg3
);
6873 #ifdef TARGET_NR_shmat
6874 case TARGET_NR_shmat
:
6875 ret
= do_shmat(arg1
, arg2
, arg3
);
6878 #ifdef TARGET_NR_shmdt
6879 case TARGET_NR_shmdt
:
6880 ret
= do_shmdt(arg1
);
6883 case TARGET_NR_fsync
:
6884 ret
= get_errno(fsync(arg1
));
6886 case TARGET_NR_clone
:
6887 #if defined(TARGET_SH4) || defined(TARGET_ALPHA)
6888 ret
= get_errno(do_fork(cpu_env
, arg1
, arg2
, arg3
, arg5
, arg4
));
6889 #elif defined(TARGET_CRIS)
6890 ret
= get_errno(do_fork(cpu_env
, arg2
, arg1
, arg3
, arg4
, arg5
));
6891 #elif defined(TARGET_S390X)
6892 ret
= get_errno(do_fork(cpu_env
, arg2
, arg1
, arg3
, arg5
, arg4
));
6894 ret
= get_errno(do_fork(cpu_env
, arg1
, arg2
, arg3
, arg4
, arg5
));
6897 #ifdef __NR_exit_group
6898 /* new thread calls */
6899 case TARGET_NR_exit_group
:
6903 gdb_exit(cpu_env
, arg1
);
6904 ret
= get_errno(exit_group(arg1
));
6907 case TARGET_NR_setdomainname
:
6908 if (!(p
= lock_user_string(arg1
)))
6910 ret
= get_errno(setdomainname(p
, arg2
));
6911 unlock_user(p
, arg1
, 0);
6913 case TARGET_NR_uname
:
6914 /* no need to transcode because we use the linux syscall */
6916 struct new_utsname
* buf
;
6918 if (!lock_user_struct(VERIFY_WRITE
, buf
, arg1
, 0))
6920 ret
= get_errno(sys_uname(buf
));
6921 if (!is_error(ret
)) {
6922 /* Overrite the native machine name with whatever is being
6924 strcpy (buf
->machine
, cpu_to_uname_machine(cpu_env
));
6925 /* Allow the user to override the reported release. */
6926 if (qemu_uname_release
&& *qemu_uname_release
)
6927 strcpy (buf
->release
, qemu_uname_release
);
6929 unlock_user_struct(buf
, arg1
, 1);
6933 case TARGET_NR_modify_ldt
:
6934 ret
= do_modify_ldt(cpu_env
, arg1
, arg2
, arg3
);
6936 #if !defined(TARGET_X86_64)
6937 case TARGET_NR_vm86old
:
6939 case TARGET_NR_vm86
:
6940 ret
= do_vm86(cpu_env
, arg1
, arg2
);
6944 case TARGET_NR_adjtimex
:
6946 #ifdef TARGET_NR_create_module
6947 case TARGET_NR_create_module
:
6949 case TARGET_NR_init_module
:
6950 case TARGET_NR_delete_module
:
6951 #ifdef TARGET_NR_get_kernel_syms
6952 case TARGET_NR_get_kernel_syms
:
6955 case TARGET_NR_quotactl
:
6957 case TARGET_NR_getpgid
:
6958 ret
= get_errno(getpgid(arg1
));
6960 case TARGET_NR_fchdir
:
6961 ret
= get_errno(fchdir(arg1
));
6963 #ifdef TARGET_NR_bdflush /* not on x86_64 */
6964 case TARGET_NR_bdflush
:
6967 #ifdef TARGET_NR_sysfs
6968 case TARGET_NR_sysfs
:
6971 case TARGET_NR_personality
:
6972 ret
= get_errno(personality(arg1
));
6974 #ifdef TARGET_NR_afs_syscall
6975 case TARGET_NR_afs_syscall
:
6978 #ifdef TARGET_NR__llseek /* Not on alpha */
6979 case TARGET_NR__llseek
:
6982 #if !defined(__NR_llseek)
6983 res
= lseek(arg1
, ((uint64_t)arg2
<< 32) | arg3
, arg5
);
6985 ret
= get_errno(res
);
6990 ret
= get_errno(_llseek(arg1
, arg2
, arg3
, &res
, arg5
));
6992 if ((ret
== 0) && put_user_s64(res
, arg4
)) {
6998 case TARGET_NR_getdents
:
6999 #if TARGET_ABI_BITS == 32 && HOST_LONG_BITS == 64
7001 struct target_dirent
*target_dirp
;
7002 struct linux_dirent
*dirp
;
7003 abi_long count
= arg3
;
7005 dirp
= malloc(count
);
7007 ret
= -TARGET_ENOMEM
;
7011 ret
= get_errno(sys_getdents(arg1
, dirp
, count
));
7012 if (!is_error(ret
)) {
7013 struct linux_dirent
*de
;
7014 struct target_dirent
*tde
;
7016 int reclen
, treclen
;
7017 int count1
, tnamelen
;
7021 if (!(target_dirp
= lock_user(VERIFY_WRITE
, arg2
, count
, 0)))
7025 reclen
= de
->d_reclen
;
7026 tnamelen
= reclen
- offsetof(struct linux_dirent
, d_name
);
7027 assert(tnamelen
>= 0);
7028 treclen
= tnamelen
+ offsetof(struct target_dirent
, d_name
);
7029 assert(count1
+ treclen
<= count
);
7030 tde
->d_reclen
= tswap16(treclen
);
7031 tde
->d_ino
= tswapal(de
->d_ino
);
7032 tde
->d_off
= tswapal(de
->d_off
);
7033 memcpy(tde
->d_name
, de
->d_name
, tnamelen
);
7034 de
= (struct linux_dirent
*)((char *)de
+ reclen
);
7036 tde
= (struct target_dirent
*)((char *)tde
+ treclen
);
7040 unlock_user(target_dirp
, arg2
, ret
);
7046 struct linux_dirent
*dirp
;
7047 abi_long count
= arg3
;
7049 if (!(dirp
= lock_user(VERIFY_WRITE
, arg2
, count
, 0)))
7051 ret
= get_errno(sys_getdents(arg1
, dirp
, count
));
7052 if (!is_error(ret
)) {
7053 struct linux_dirent
*de
;
7058 reclen
= de
->d_reclen
;
7061 de
->d_reclen
= tswap16(reclen
);
7062 tswapls(&de
->d_ino
);
7063 tswapls(&de
->d_off
);
7064 de
= (struct linux_dirent
*)((char *)de
+ reclen
);
7068 unlock_user(dirp
, arg2
, ret
);
7072 #if defined(TARGET_NR_getdents64) && defined(__NR_getdents64)
7073 case TARGET_NR_getdents64
:
7075 struct linux_dirent64
*dirp
;
7076 abi_long count
= arg3
;
7077 if (!(dirp
= lock_user(VERIFY_WRITE
, arg2
, count
, 0)))
7079 ret
= get_errno(sys_getdents64(arg1
, dirp
, count
));
7080 if (!is_error(ret
)) {
7081 struct linux_dirent64
*de
;
7086 reclen
= de
->d_reclen
;
7089 de
->d_reclen
= tswap16(reclen
);
7090 tswap64s((uint64_t *)&de
->d_ino
);
7091 tswap64s((uint64_t *)&de
->d_off
);
7092 de
= (struct linux_dirent64
*)((char *)de
+ reclen
);
7096 unlock_user(dirp
, arg2
, ret
);
7099 #endif /* TARGET_NR_getdents64 */
7100 #if defined(TARGET_NR__newselect) || defined(TARGET_S390X)
7102 case TARGET_NR_select
:
7104 case TARGET_NR__newselect
:
7106 ret
= do_select(arg1
, arg2
, arg3
, arg4
, arg5
);
7109 #if defined(TARGET_NR_poll) || defined(TARGET_NR_ppoll)
7110 # ifdef TARGET_NR_poll
7111 case TARGET_NR_poll
:
7113 # ifdef TARGET_NR_ppoll
7114 case TARGET_NR_ppoll
:
7117 struct target_pollfd
*target_pfd
;
7118 unsigned int nfds
= arg2
;
7123 target_pfd
= lock_user(VERIFY_WRITE
, arg1
, sizeof(struct target_pollfd
) * nfds
, 1);
7127 pfd
= alloca(sizeof(struct pollfd
) * nfds
);
7128 for(i
= 0; i
< nfds
; i
++) {
7129 pfd
[i
].fd
= tswap32(target_pfd
[i
].fd
);
7130 pfd
[i
].events
= tswap16(target_pfd
[i
].events
);
7133 # ifdef TARGET_NR_ppoll
7134 if (num
== TARGET_NR_ppoll
) {
7135 struct timespec _timeout_ts
, *timeout_ts
= &_timeout_ts
;
7136 target_sigset_t
*target_set
;
7137 sigset_t _set
, *set
= &_set
;
7140 if (target_to_host_timespec(timeout_ts
, arg3
)) {
7141 unlock_user(target_pfd
, arg1
, 0);
7149 target_set
= lock_user(VERIFY_READ
, arg4
, sizeof(target_sigset_t
), 1);
7151 unlock_user(target_pfd
, arg1
, 0);
7154 target_to_host_sigset(set
, target_set
);
7159 ret
= get_errno(sys_ppoll(pfd
, nfds
, timeout_ts
, set
, _NSIG
/8));
7161 if (!is_error(ret
) && arg3
) {
7162 host_to_target_timespec(arg3
, timeout_ts
);
7165 unlock_user(target_set
, arg4
, 0);
7169 ret
= get_errno(poll(pfd
, nfds
, timeout
));
7171 if (!is_error(ret
)) {
7172 for(i
= 0; i
< nfds
; i
++) {
7173 target_pfd
[i
].revents
= tswap16(pfd
[i
].revents
);
7176 unlock_user(target_pfd
, arg1
, sizeof(struct target_pollfd
) * nfds
);
7180 case TARGET_NR_flock
:
7181 /* NOTE: the flock constant seems to be the same for every
7183 ret
= get_errno(flock(arg1
, arg2
));
7185 case TARGET_NR_readv
:
7190 vec
= alloca(count
* sizeof(struct iovec
));
7191 if (lock_iovec(VERIFY_WRITE
, vec
, arg2
, count
, 0) < 0)
7193 ret
= get_errno(readv(arg1
, vec
, count
));
7194 unlock_iovec(vec
, arg2
, count
, 1);
7197 case TARGET_NR_writev
:
7202 vec
= alloca(count
* sizeof(struct iovec
));
7203 if (lock_iovec(VERIFY_READ
, vec
, arg2
, count
, 1) < 0)
7205 ret
= get_errno(writev(arg1
, vec
, count
));
7206 unlock_iovec(vec
, arg2
, count
, 0);
7209 case TARGET_NR_getsid
:
7210 ret
= get_errno(getsid(arg1
));
7212 #if defined(TARGET_NR_fdatasync) /* Not on alpha (osf_datasync ?) */
7213 case TARGET_NR_fdatasync
:
7214 ret
= get_errno(fdatasync(arg1
));
7217 case TARGET_NR__sysctl
:
7218 /* We don't implement this, but ENOTDIR is always a safe
7220 ret
= -TARGET_ENOTDIR
;
7222 case TARGET_NR_sched_getaffinity
:
7224 unsigned int mask_size
;
7225 unsigned long *mask
;
7228 * sched_getaffinity needs multiples of ulong, so need to take
7229 * care of mismatches between target ulong and host ulong sizes.
7231 if (arg2
& (sizeof(abi_ulong
) - 1)) {
7232 ret
= -TARGET_EINVAL
;
7235 mask_size
= (arg2
+ (sizeof(*mask
) - 1)) & ~(sizeof(*mask
) - 1);
7237 mask
= alloca(mask_size
);
7238 ret
= get_errno(sys_sched_getaffinity(arg1
, mask_size
, mask
));
7240 if (!is_error(ret
)) {
7241 if (copy_to_user(arg3
, mask
, ret
)) {
7247 case TARGET_NR_sched_setaffinity
:
7249 unsigned int mask_size
;
7250 unsigned long *mask
;
7253 * sched_setaffinity needs multiples of ulong, so need to take
7254 * care of mismatches between target ulong and host ulong sizes.
7256 if (arg2
& (sizeof(abi_ulong
) - 1)) {
7257 ret
= -TARGET_EINVAL
;
7260 mask_size
= (arg2
+ (sizeof(*mask
) - 1)) & ~(sizeof(*mask
) - 1);
7262 mask
= alloca(mask_size
);
7263 if (!lock_user_struct(VERIFY_READ
, p
, arg3
, 1)) {
7266 memcpy(mask
, p
, arg2
);
7267 unlock_user_struct(p
, arg2
, 0);
7269 ret
= get_errno(sys_sched_setaffinity(arg1
, mask_size
, mask
));
7272 case TARGET_NR_sched_setparam
:
7274 struct sched_param
*target_schp
;
7275 struct sched_param schp
;
7277 if (!lock_user_struct(VERIFY_READ
, target_schp
, arg2
, 1))
7279 schp
.sched_priority
= tswap32(target_schp
->sched_priority
);
7280 unlock_user_struct(target_schp
, arg2
, 0);
7281 ret
= get_errno(sched_setparam(arg1
, &schp
));
7284 case TARGET_NR_sched_getparam
:
7286 struct sched_param
*target_schp
;
7287 struct sched_param schp
;
7288 ret
= get_errno(sched_getparam(arg1
, &schp
));
7289 if (!is_error(ret
)) {
7290 if (!lock_user_struct(VERIFY_WRITE
, target_schp
, arg2
, 0))
7292 target_schp
->sched_priority
= tswap32(schp
.sched_priority
);
7293 unlock_user_struct(target_schp
, arg2
, 1);
7297 case TARGET_NR_sched_setscheduler
:
7299 struct sched_param
*target_schp
;
7300 struct sched_param schp
;
7301 if (!lock_user_struct(VERIFY_READ
, target_schp
, arg3
, 1))
7303 schp
.sched_priority
= tswap32(target_schp
->sched_priority
);
7304 unlock_user_struct(target_schp
, arg3
, 0);
7305 ret
= get_errno(sched_setscheduler(arg1
, arg2
, &schp
));
7308 case TARGET_NR_sched_getscheduler
:
7309 ret
= get_errno(sched_getscheduler(arg1
));
7311 case TARGET_NR_sched_yield
:
7312 ret
= get_errno(sched_yield());
7314 case TARGET_NR_sched_get_priority_max
:
7315 ret
= get_errno(sched_get_priority_max(arg1
));
7317 case TARGET_NR_sched_get_priority_min
:
7318 ret
= get_errno(sched_get_priority_min(arg1
));
7320 case TARGET_NR_sched_rr_get_interval
:
7323 ret
= get_errno(sched_rr_get_interval(arg1
, &ts
));
7324 if (!is_error(ret
)) {
7325 host_to_target_timespec(arg2
, &ts
);
7329 case TARGET_NR_nanosleep
:
7331 struct timespec req
, rem
;
7332 target_to_host_timespec(&req
, arg1
);
7333 ret
= get_errno(nanosleep(&req
, &rem
));
7334 if (is_error(ret
) && arg2
) {
7335 host_to_target_timespec(arg2
, &rem
);
7339 #ifdef TARGET_NR_query_module
7340 case TARGET_NR_query_module
:
7343 #ifdef TARGET_NR_nfsservctl
7344 case TARGET_NR_nfsservctl
:
7347 case TARGET_NR_prctl
:
7349 case PR_GET_PDEATHSIG
:
7352 ret
= get_errno(prctl(arg1
, &deathsig
, arg3
, arg4
, arg5
));
7353 if (!is_error(ret
) && arg2
7354 && put_user_ual(deathsig
, arg2
)) {
7362 void *name
= lock_user(VERIFY_WRITE
, arg2
, 16, 1);
7366 ret
= get_errno(prctl(arg1
, (unsigned long)name
,
7368 unlock_user(name
, arg2
, 16);
7373 void *name
= lock_user(VERIFY_READ
, arg2
, 16, 1);
7377 ret
= get_errno(prctl(arg1
, (unsigned long)name
,
7379 unlock_user(name
, arg2
, 0);
7384 /* Most prctl options have no pointer arguments */
7385 ret
= get_errno(prctl(arg1
, arg2
, arg3
, arg4
, arg5
));
7389 #ifdef TARGET_NR_arch_prctl
7390 case TARGET_NR_arch_prctl
:
7391 #if defined(TARGET_I386) && !defined(TARGET_ABI32)
7392 ret
= do_arch_prctl(cpu_env
, arg1
, arg2
);
7398 #ifdef TARGET_NR_pread
7399 case TARGET_NR_pread
:
7400 if (regpairs_aligned(cpu_env
))
7402 if (!(p
= lock_user(VERIFY_WRITE
, arg2
, arg3
, 0)))
7404 ret
= get_errno(pread(arg1
, p
, arg3
, arg4
));
7405 unlock_user(p
, arg2
, ret
);
7407 case TARGET_NR_pwrite
:
7408 if (regpairs_aligned(cpu_env
))
7410 if (!(p
= lock_user(VERIFY_READ
, arg2
, arg3
, 1)))
7412 ret
= get_errno(pwrite(arg1
, p
, arg3
, arg4
));
7413 unlock_user(p
, arg2
, 0);
7416 #ifdef TARGET_NR_pread64
7417 case TARGET_NR_pread64
:
7418 if (!(p
= lock_user(VERIFY_WRITE
, arg2
, arg3
, 0)))
7420 ret
= get_errno(pread64(arg1
, p
, arg3
, target_offset64(arg4
, arg5
)));
7421 unlock_user(p
, arg2
, ret
);
7423 case TARGET_NR_pwrite64
:
7424 if (!(p
= lock_user(VERIFY_READ
, arg2
, arg3
, 1)))
7426 ret
= get_errno(pwrite64(arg1
, p
, arg3
, target_offset64(arg4
, arg5
)));
7427 unlock_user(p
, arg2
, 0);
7430 case TARGET_NR_getcwd
:
7431 if (!(p
= lock_user(VERIFY_WRITE
, arg1
, arg2
, 0)))
7433 ret
= get_errno(sys_getcwd1(p
, arg2
));
7434 unlock_user(p
, arg1
, ret
);
7436 case TARGET_NR_capget
:
7438 case TARGET_NR_capset
:
7440 case TARGET_NR_sigaltstack
:
7441 #if defined(TARGET_I386) || defined(TARGET_ARM) || defined(TARGET_MIPS) || \
7442 defined(TARGET_SPARC) || defined(TARGET_PPC) || defined(TARGET_ALPHA) || \
7443 defined(TARGET_M68K) || defined(TARGET_S390X) || defined(TARGET_OPENRISC)
7444 ret
= do_sigaltstack(arg1
, arg2
, get_sp_from_cpustate((CPUArchState
*)cpu_env
));
7449 case TARGET_NR_sendfile
:
7451 #ifdef TARGET_NR_getpmsg
7452 case TARGET_NR_getpmsg
:
7455 #ifdef TARGET_NR_putpmsg
7456 case TARGET_NR_putpmsg
:
7459 #ifdef TARGET_NR_vfork
7460 case TARGET_NR_vfork
:
7461 ret
= get_errno(do_fork(cpu_env
, CLONE_VFORK
| CLONE_VM
| SIGCHLD
,
7465 #ifdef TARGET_NR_ugetrlimit
7466 case TARGET_NR_ugetrlimit
:
7469 int resource
= target_to_host_resource(arg1
);
7470 ret
= get_errno(getrlimit(resource
, &rlim
));
7471 if (!is_error(ret
)) {
7472 struct target_rlimit
*target_rlim
;
7473 if (!lock_user_struct(VERIFY_WRITE
, target_rlim
, arg2
, 0))
7475 target_rlim
->rlim_cur
= host_to_target_rlim(rlim
.rlim_cur
);
7476 target_rlim
->rlim_max
= host_to_target_rlim(rlim
.rlim_max
);
7477 unlock_user_struct(target_rlim
, arg2
, 1);
7482 #ifdef TARGET_NR_truncate64
7483 case TARGET_NR_truncate64
:
7484 if (!(p
= lock_user_string(arg1
)))
7486 ret
= target_truncate64(cpu_env
, p
, arg2
, arg3
, arg4
);
7487 unlock_user(p
, arg1
, 0);
7490 #ifdef TARGET_NR_ftruncate64
7491 case TARGET_NR_ftruncate64
:
7492 ret
= target_ftruncate64(cpu_env
, arg1
, arg2
, arg3
, arg4
);
7495 #ifdef TARGET_NR_stat64
7496 case TARGET_NR_stat64
:
7497 if (!(p
= lock_user_string(arg1
)))
7499 ret
= get_errno(stat(path(p
), &st
));
7500 unlock_user(p
, arg1
, 0);
7502 ret
= host_to_target_stat64(cpu_env
, arg2
, &st
);
7505 #ifdef TARGET_NR_lstat64
7506 case TARGET_NR_lstat64
:
7507 if (!(p
= lock_user_string(arg1
)))
7509 ret
= get_errno(lstat(path(p
), &st
));
7510 unlock_user(p
, arg1
, 0);
7512 ret
= host_to_target_stat64(cpu_env
, arg2
, &st
);
7515 #ifdef TARGET_NR_fstat64
7516 case TARGET_NR_fstat64
:
7517 ret
= get_errno(fstat(arg1
, &st
));
7519 ret
= host_to_target_stat64(cpu_env
, arg2
, &st
);
7522 #if (defined(TARGET_NR_fstatat64) || defined(TARGET_NR_newfstatat)) && \
7523 (defined(__NR_fstatat64) || defined(__NR_newfstatat))
7524 #ifdef TARGET_NR_fstatat64
7525 case TARGET_NR_fstatat64
:
7527 #ifdef TARGET_NR_newfstatat
7528 case TARGET_NR_newfstatat
:
7530 if (!(p
= lock_user_string(arg2
)))
7532 #ifdef __NR_fstatat64
7533 ret
= get_errno(sys_fstatat64(arg1
, path(p
), &st
, arg4
));
7535 ret
= get_errno(sys_newfstatat(arg1
, path(p
), &st
, arg4
));
7538 ret
= host_to_target_stat64(cpu_env
, arg3
, &st
);
7541 case TARGET_NR_lchown
:
7542 if (!(p
= lock_user_string(arg1
)))
7544 ret
= get_errno(lchown(p
, low2highuid(arg2
), low2highgid(arg3
)));
7545 unlock_user(p
, arg1
, 0);
7547 #ifdef TARGET_NR_getuid
7548 case TARGET_NR_getuid
:
7549 ret
= get_errno(high2lowuid(getuid()));
7552 #ifdef TARGET_NR_getgid
7553 case TARGET_NR_getgid
:
7554 ret
= get_errno(high2lowgid(getgid()));
7557 #ifdef TARGET_NR_geteuid
7558 case TARGET_NR_geteuid
:
7559 ret
= get_errno(high2lowuid(geteuid()));
7562 #ifdef TARGET_NR_getegid
7563 case TARGET_NR_getegid
:
7564 ret
= get_errno(high2lowgid(getegid()));
7567 case TARGET_NR_setreuid
:
7568 ret
= get_errno(setreuid(low2highuid(arg1
), low2highuid(arg2
)));
7570 case TARGET_NR_setregid
:
7571 ret
= get_errno(setregid(low2highgid(arg1
), low2highgid(arg2
)));
7573 case TARGET_NR_getgroups
:
7575 int gidsetsize
= arg1
;
7576 target_id
*target_grouplist
;
7580 grouplist
= alloca(gidsetsize
* sizeof(gid_t
));
7581 ret
= get_errno(getgroups(gidsetsize
, grouplist
));
7582 if (gidsetsize
== 0)
7584 if (!is_error(ret
)) {
7585 target_grouplist
= lock_user(VERIFY_WRITE
, arg2
, gidsetsize
* 2, 0);
7586 if (!target_grouplist
)
7588 for(i
= 0;i
< ret
; i
++)
7589 target_grouplist
[i
] = tswapid(high2lowgid(grouplist
[i
]));
7590 unlock_user(target_grouplist
, arg2
, gidsetsize
* 2);
7594 case TARGET_NR_setgroups
:
7596 int gidsetsize
= arg1
;
7597 target_id
*target_grouplist
;
7601 grouplist
= alloca(gidsetsize
* sizeof(gid_t
));
7602 target_grouplist
= lock_user(VERIFY_READ
, arg2
, gidsetsize
* 2, 1);
7603 if (!target_grouplist
) {
7604 ret
= -TARGET_EFAULT
;
7607 for(i
= 0;i
< gidsetsize
; i
++)
7608 grouplist
[i
] = low2highgid(tswapid(target_grouplist
[i
]));
7609 unlock_user(target_grouplist
, arg2
, 0);
7610 ret
= get_errno(setgroups(gidsetsize
, grouplist
));
7613 case TARGET_NR_fchown
:
7614 ret
= get_errno(fchown(arg1
, low2highuid(arg2
), low2highgid(arg3
)));
7616 #if defined(TARGET_NR_fchownat) && defined(__NR_fchownat)
7617 case TARGET_NR_fchownat
:
7618 if (!(p
= lock_user_string(arg2
)))
7620 ret
= get_errno(sys_fchownat(arg1
, p
, low2highuid(arg3
), low2highgid(arg4
), arg5
));
7621 unlock_user(p
, arg2
, 0);
7624 #ifdef TARGET_NR_setresuid
7625 case TARGET_NR_setresuid
:
7626 ret
= get_errno(setresuid(low2highuid(arg1
),
7628 low2highuid(arg3
)));
7631 #ifdef TARGET_NR_getresuid
7632 case TARGET_NR_getresuid
:
7634 uid_t ruid
, euid
, suid
;
7635 ret
= get_errno(getresuid(&ruid
, &euid
, &suid
));
7636 if (!is_error(ret
)) {
7637 if (put_user_u16(high2lowuid(ruid
), arg1
)
7638 || put_user_u16(high2lowuid(euid
), arg2
)
7639 || put_user_u16(high2lowuid(suid
), arg3
))
7645 #ifdef TARGET_NR_getresgid
7646 case TARGET_NR_setresgid
:
7647 ret
= get_errno(setresgid(low2highgid(arg1
),
7649 low2highgid(arg3
)));
7652 #ifdef TARGET_NR_getresgid
7653 case TARGET_NR_getresgid
:
7655 gid_t rgid
, egid
, sgid
;
7656 ret
= get_errno(getresgid(&rgid
, &egid
, &sgid
));
7657 if (!is_error(ret
)) {
7658 if (put_user_u16(high2lowgid(rgid
), arg1
)
7659 || put_user_u16(high2lowgid(egid
), arg2
)
7660 || put_user_u16(high2lowgid(sgid
), arg3
))
7666 case TARGET_NR_chown
:
7667 if (!(p
= lock_user_string(arg1
)))
7669 ret
= get_errno(chown(p
, low2highuid(arg2
), low2highgid(arg3
)));
7670 unlock_user(p
, arg1
, 0);
7672 case TARGET_NR_setuid
:
7673 ret
= get_errno(setuid(low2highuid(arg1
)));
7675 case TARGET_NR_setgid
:
7676 ret
= get_errno(setgid(low2highgid(arg1
)));
7678 case TARGET_NR_setfsuid
:
7679 ret
= get_errno(setfsuid(arg1
));
7681 case TARGET_NR_setfsgid
:
7682 ret
= get_errno(setfsgid(arg1
));
7685 #ifdef TARGET_NR_lchown32
7686 case TARGET_NR_lchown32
:
7687 if (!(p
= lock_user_string(arg1
)))
7689 ret
= get_errno(lchown(p
, arg2
, arg3
));
7690 unlock_user(p
, arg1
, 0);
7693 #ifdef TARGET_NR_getuid32
7694 case TARGET_NR_getuid32
:
7695 ret
= get_errno(getuid());
7699 #if defined(TARGET_NR_getxuid) && defined(TARGET_ALPHA)
7700 /* Alpha specific */
7701 case TARGET_NR_getxuid
:
7705 ((CPUAlphaState
*)cpu_env
)->ir
[IR_A4
]=euid
;
7707 ret
= get_errno(getuid());
7710 #if defined(TARGET_NR_getxgid) && defined(TARGET_ALPHA)
7711 /* Alpha specific */
7712 case TARGET_NR_getxgid
:
7716 ((CPUAlphaState
*)cpu_env
)->ir
[IR_A4
]=egid
;
7718 ret
= get_errno(getgid());
7721 #if defined(TARGET_NR_osf_getsysinfo) && defined(TARGET_ALPHA)
7722 /* Alpha specific */
7723 case TARGET_NR_osf_getsysinfo
:
7724 ret
= -TARGET_EOPNOTSUPP
;
7726 case TARGET_GSI_IEEE_FP_CONTROL
:
7728 uint64_t swcr
, fpcr
= cpu_alpha_load_fpcr (cpu_env
);
7730 /* Copied from linux ieee_fpcr_to_swcr. */
7731 swcr
= (fpcr
>> 35) & SWCR_STATUS_MASK
;
7732 swcr
|= (fpcr
>> 36) & SWCR_MAP_DMZ
;
7733 swcr
|= (~fpcr
>> 48) & (SWCR_TRAP_ENABLE_INV
7734 | SWCR_TRAP_ENABLE_DZE
7735 | SWCR_TRAP_ENABLE_OVF
);
7736 swcr
|= (~fpcr
>> 57) & (SWCR_TRAP_ENABLE_UNF
7737 | SWCR_TRAP_ENABLE_INE
);
7738 swcr
|= (fpcr
>> 47) & SWCR_MAP_UMZ
;
7739 swcr
|= (~fpcr
>> 41) & SWCR_TRAP_ENABLE_DNO
;
7741 if (put_user_u64 (swcr
, arg2
))
7747 /* case GSI_IEEE_STATE_AT_SIGNAL:
7748 -- Not implemented in linux kernel.
7750 -- Retrieves current unaligned access state; not much used.
7752 -- Retrieves implver information; surely not used.
7754 -- Grabs a copy of the HWRPB; surely not used.
7759 #if defined(TARGET_NR_osf_setsysinfo) && defined(TARGET_ALPHA)
7760 /* Alpha specific */
7761 case TARGET_NR_osf_setsysinfo
:
7762 ret
= -TARGET_EOPNOTSUPP
;
7764 case TARGET_SSI_IEEE_FP_CONTROL
:
7766 uint64_t swcr
, fpcr
, orig_fpcr
;
7768 if (get_user_u64 (swcr
, arg2
)) {
7771 orig_fpcr
= cpu_alpha_load_fpcr(cpu_env
);
7772 fpcr
= orig_fpcr
& FPCR_DYN_MASK
;
7774 /* Copied from linux ieee_swcr_to_fpcr. */
7775 fpcr
|= (swcr
& SWCR_STATUS_MASK
) << 35;
7776 fpcr
|= (swcr
& SWCR_MAP_DMZ
) << 36;
7777 fpcr
|= (~swcr
& (SWCR_TRAP_ENABLE_INV
7778 | SWCR_TRAP_ENABLE_DZE
7779 | SWCR_TRAP_ENABLE_OVF
)) << 48;
7780 fpcr
|= (~swcr
& (SWCR_TRAP_ENABLE_UNF
7781 | SWCR_TRAP_ENABLE_INE
)) << 57;
7782 fpcr
|= (swcr
& SWCR_MAP_UMZ
? FPCR_UNDZ
| FPCR_UNFD
: 0);
7783 fpcr
|= (~swcr
& SWCR_TRAP_ENABLE_DNO
) << 41;
7785 cpu_alpha_store_fpcr(cpu_env
, fpcr
);
7790 case TARGET_SSI_IEEE_RAISE_EXCEPTION
:
7792 uint64_t exc
, fpcr
, orig_fpcr
;
7795 if (get_user_u64(exc
, arg2
)) {
7799 orig_fpcr
= cpu_alpha_load_fpcr(cpu_env
);
7801 /* We only add to the exception status here. */
7802 fpcr
= orig_fpcr
| ((exc
& SWCR_STATUS_MASK
) << 35);
7804 cpu_alpha_store_fpcr(cpu_env
, fpcr
);
7807 /* Old exceptions are not signaled. */
7808 fpcr
&= ~(orig_fpcr
& FPCR_STATUS_MASK
);
7810 /* If any exceptions set by this call,
7811 and are unmasked, send a signal. */
7813 if ((fpcr
& (FPCR_INE
| FPCR_INED
)) == FPCR_INE
) {
7814 si_code
= TARGET_FPE_FLTRES
;
7816 if ((fpcr
& (FPCR_UNF
| FPCR_UNFD
)) == FPCR_UNF
) {
7817 si_code
= TARGET_FPE_FLTUND
;
7819 if ((fpcr
& (FPCR_OVF
| FPCR_OVFD
)) == FPCR_OVF
) {
7820 si_code
= TARGET_FPE_FLTOVF
;
7822 if ((fpcr
& (FPCR_DZE
| FPCR_DZED
)) == FPCR_DZE
) {
7823 si_code
= TARGET_FPE_FLTDIV
;
7825 if ((fpcr
& (FPCR_INV
| FPCR_INVD
)) == FPCR_INV
) {
7826 si_code
= TARGET_FPE_FLTINV
;
7829 target_siginfo_t info
;
7830 info
.si_signo
= SIGFPE
;
7832 info
.si_code
= si_code
;
7833 info
._sifields
._sigfault
._addr
7834 = ((CPUArchState
*)cpu_env
)->pc
;
7835 queue_signal((CPUArchState
*)cpu_env
, info
.si_signo
, &info
);
7840 /* case SSI_NVPAIRS:
7841 -- Used with SSIN_UACPROC to enable unaligned accesses.
7842 case SSI_IEEE_STATE_AT_SIGNAL:
7843 case SSI_IEEE_IGNORE_STATE_AT_SIGNAL:
7844 -- Not implemented in linux kernel
7849 #ifdef TARGET_NR_osf_sigprocmask
7850 /* Alpha specific. */
7851 case TARGET_NR_osf_sigprocmask
:
7855 sigset_t set
, oldset
;
7858 case TARGET_SIG_BLOCK
:
7861 case TARGET_SIG_UNBLOCK
:
7864 case TARGET_SIG_SETMASK
:
7868 ret
= -TARGET_EINVAL
;
7872 target_to_host_old_sigset(&set
, &mask
);
7873 sigprocmask(how
, &set
, &oldset
);
7874 host_to_target_old_sigset(&mask
, &oldset
);
7880 #ifdef TARGET_NR_getgid32
7881 case TARGET_NR_getgid32
:
7882 ret
= get_errno(getgid());
7885 #ifdef TARGET_NR_geteuid32
7886 case TARGET_NR_geteuid32
:
7887 ret
= get_errno(geteuid());
7890 #ifdef TARGET_NR_getegid32
7891 case TARGET_NR_getegid32
:
7892 ret
= get_errno(getegid());
7895 #ifdef TARGET_NR_setreuid32
7896 case TARGET_NR_setreuid32
:
7897 ret
= get_errno(setreuid(arg1
, arg2
));
7900 #ifdef TARGET_NR_setregid32
7901 case TARGET_NR_setregid32
:
7902 ret
= get_errno(setregid(arg1
, arg2
));
7905 #ifdef TARGET_NR_getgroups32
7906 case TARGET_NR_getgroups32
:
7908 int gidsetsize
= arg1
;
7909 uint32_t *target_grouplist
;
7913 grouplist
= alloca(gidsetsize
* sizeof(gid_t
));
7914 ret
= get_errno(getgroups(gidsetsize
, grouplist
));
7915 if (gidsetsize
== 0)
7917 if (!is_error(ret
)) {
7918 target_grouplist
= lock_user(VERIFY_WRITE
, arg2
, gidsetsize
* 4, 0);
7919 if (!target_grouplist
) {
7920 ret
= -TARGET_EFAULT
;
7923 for(i
= 0;i
< ret
; i
++)
7924 target_grouplist
[i
] = tswap32(grouplist
[i
]);
7925 unlock_user(target_grouplist
, arg2
, gidsetsize
* 4);
7930 #ifdef TARGET_NR_setgroups32
7931 case TARGET_NR_setgroups32
:
7933 int gidsetsize
= arg1
;
7934 uint32_t *target_grouplist
;
7938 grouplist
= alloca(gidsetsize
* sizeof(gid_t
));
7939 target_grouplist
= lock_user(VERIFY_READ
, arg2
, gidsetsize
* 4, 1);
7940 if (!target_grouplist
) {
7941 ret
= -TARGET_EFAULT
;
7944 for(i
= 0;i
< gidsetsize
; i
++)
7945 grouplist
[i
] = tswap32(target_grouplist
[i
]);
7946 unlock_user(target_grouplist
, arg2
, 0);
7947 ret
= get_errno(setgroups(gidsetsize
, grouplist
));
7951 #ifdef TARGET_NR_fchown32
7952 case TARGET_NR_fchown32
:
7953 ret
= get_errno(fchown(arg1
, arg2
, arg3
));
7956 #ifdef TARGET_NR_setresuid32
7957 case TARGET_NR_setresuid32
:
7958 ret
= get_errno(setresuid(arg1
, arg2
, arg3
));
7961 #ifdef TARGET_NR_getresuid32
7962 case TARGET_NR_getresuid32
:
7964 uid_t ruid
, euid
, suid
;
7965 ret
= get_errno(getresuid(&ruid
, &euid
, &suid
));
7966 if (!is_error(ret
)) {
7967 if (put_user_u32(ruid
, arg1
)
7968 || put_user_u32(euid
, arg2
)
7969 || put_user_u32(suid
, arg3
))
7975 #ifdef TARGET_NR_setresgid32
7976 case TARGET_NR_setresgid32
:
7977 ret
= get_errno(setresgid(arg1
, arg2
, arg3
));
7980 #ifdef TARGET_NR_getresgid32
7981 case TARGET_NR_getresgid32
:
7983 gid_t rgid
, egid
, sgid
;
7984 ret
= get_errno(getresgid(&rgid
, &egid
, &sgid
));
7985 if (!is_error(ret
)) {
7986 if (put_user_u32(rgid
, arg1
)
7987 || put_user_u32(egid
, arg2
)
7988 || put_user_u32(sgid
, arg3
))
7994 #ifdef TARGET_NR_chown32
7995 case TARGET_NR_chown32
:
7996 if (!(p
= lock_user_string(arg1
)))
7998 ret
= get_errno(chown(p
, arg2
, arg3
));
7999 unlock_user(p
, arg1
, 0);
8002 #ifdef TARGET_NR_setuid32
8003 case TARGET_NR_setuid32
:
8004 ret
= get_errno(setuid(arg1
));
8007 #ifdef TARGET_NR_setgid32
8008 case TARGET_NR_setgid32
:
8009 ret
= get_errno(setgid(arg1
));
8012 #ifdef TARGET_NR_setfsuid32
8013 case TARGET_NR_setfsuid32
:
8014 ret
= get_errno(setfsuid(arg1
));
8017 #ifdef TARGET_NR_setfsgid32
8018 case TARGET_NR_setfsgid32
:
8019 ret
= get_errno(setfsgid(arg1
));
8023 case TARGET_NR_pivot_root
:
8025 #ifdef TARGET_NR_mincore
8026 case TARGET_NR_mincore
:
8029 ret
= -TARGET_EFAULT
;
8030 if (!(a
= lock_user(VERIFY_READ
, arg1
,arg2
, 0)))
8032 if (!(p
= lock_user_string(arg3
)))
8034 ret
= get_errno(mincore(a
, arg2
, p
));
8035 unlock_user(p
, arg3
, ret
);
8037 unlock_user(a
, arg1
, 0);
8041 #ifdef TARGET_NR_arm_fadvise64_64
8042 case TARGET_NR_arm_fadvise64_64
:
8045 * arm_fadvise64_64 looks like fadvise64_64 but
8046 * with different argument order
8054 #if defined(TARGET_NR_fadvise64_64) || defined(TARGET_NR_arm_fadvise64_64) || defined(TARGET_NR_fadvise64)
8055 #ifdef TARGET_NR_fadvise64_64
8056 case TARGET_NR_fadvise64_64
:
8058 #ifdef TARGET_NR_fadvise64
8059 case TARGET_NR_fadvise64
:
8063 case 4: arg4
= POSIX_FADV_NOREUSE
+ 1; break; /* make sure it's an invalid value */
8064 case 5: arg4
= POSIX_FADV_NOREUSE
+ 2; break; /* ditto */
8065 case 6: arg4
= POSIX_FADV_DONTNEED
; break;
8066 case 7: arg4
= POSIX_FADV_NOREUSE
; break;
8070 ret
= -posix_fadvise(arg1
, arg2
, arg3
, arg4
);
8073 #ifdef TARGET_NR_madvise
8074 case TARGET_NR_madvise
:
8075 /* A straight passthrough may not be safe because qemu sometimes
8076 turns private flie-backed mappings into anonymous mappings.
8077 This will break MADV_DONTNEED.
8078 This is a hint, so ignoring and returning success is ok. */
8082 #if TARGET_ABI_BITS == 32
8083 case TARGET_NR_fcntl64
:
8087 struct target_flock64
*target_fl
;
8089 struct target_eabi_flock64
*target_efl
;
8092 cmd
= target_to_host_fcntl_cmd(arg2
);
8093 if (cmd
== -TARGET_EINVAL
) {
8099 case TARGET_F_GETLK64
:
8101 if (((CPUARMState
*)cpu_env
)->eabi
) {
8102 if (!lock_user_struct(VERIFY_READ
, target_efl
, arg3
, 1))
8104 fl
.l_type
= tswap16(target_efl
->l_type
);
8105 fl
.l_whence
= tswap16(target_efl
->l_whence
);
8106 fl
.l_start
= tswap64(target_efl
->l_start
);
8107 fl
.l_len
= tswap64(target_efl
->l_len
);
8108 fl
.l_pid
= tswap32(target_efl
->l_pid
);
8109 unlock_user_struct(target_efl
, arg3
, 0);
8113 if (!lock_user_struct(VERIFY_READ
, target_fl
, arg3
, 1))
8115 fl
.l_type
= tswap16(target_fl
->l_type
);
8116 fl
.l_whence
= tswap16(target_fl
->l_whence
);
8117 fl
.l_start
= tswap64(target_fl
->l_start
);
8118 fl
.l_len
= tswap64(target_fl
->l_len
);
8119 fl
.l_pid
= tswap32(target_fl
->l_pid
);
8120 unlock_user_struct(target_fl
, arg3
, 0);
8122 ret
= get_errno(fcntl(arg1
, cmd
, &fl
));
8125 if (((CPUARMState
*)cpu_env
)->eabi
) {
8126 if (!lock_user_struct(VERIFY_WRITE
, target_efl
, arg3
, 0))
8128 target_efl
->l_type
= tswap16(fl
.l_type
);
8129 target_efl
->l_whence
= tswap16(fl
.l_whence
);
8130 target_efl
->l_start
= tswap64(fl
.l_start
);
8131 target_efl
->l_len
= tswap64(fl
.l_len
);
8132 target_efl
->l_pid
= tswap32(fl
.l_pid
);
8133 unlock_user_struct(target_efl
, arg3
, 1);
8137 if (!lock_user_struct(VERIFY_WRITE
, target_fl
, arg3
, 0))
8139 target_fl
->l_type
= tswap16(fl
.l_type
);
8140 target_fl
->l_whence
= tswap16(fl
.l_whence
);
8141 target_fl
->l_start
= tswap64(fl
.l_start
);
8142 target_fl
->l_len
= tswap64(fl
.l_len
);
8143 target_fl
->l_pid
= tswap32(fl
.l_pid
);
8144 unlock_user_struct(target_fl
, arg3
, 1);
8149 case TARGET_F_SETLK64
:
8150 case TARGET_F_SETLKW64
:
8152 if (((CPUARMState
*)cpu_env
)->eabi
) {
8153 if (!lock_user_struct(VERIFY_READ
, target_efl
, arg3
, 1))
8155 fl
.l_type
= tswap16(target_efl
->l_type
);
8156 fl
.l_whence
= tswap16(target_efl
->l_whence
);
8157 fl
.l_start
= tswap64(target_efl
->l_start
);
8158 fl
.l_len
= tswap64(target_efl
->l_len
);
8159 fl
.l_pid
= tswap32(target_efl
->l_pid
);
8160 unlock_user_struct(target_efl
, arg3
, 0);
8164 if (!lock_user_struct(VERIFY_READ
, target_fl
, arg3
, 1))
8166 fl
.l_type
= tswap16(target_fl
->l_type
);
8167 fl
.l_whence
= tswap16(target_fl
->l_whence
);
8168 fl
.l_start
= tswap64(target_fl
->l_start
);
8169 fl
.l_len
= tswap64(target_fl
->l_len
);
8170 fl
.l_pid
= tswap32(target_fl
->l_pid
);
8171 unlock_user_struct(target_fl
, arg3
, 0);
8173 ret
= get_errno(fcntl(arg1
, cmd
, &fl
));
8176 ret
= do_fcntl(arg1
, arg2
, arg3
);
8182 #ifdef TARGET_NR_cacheflush
8183 case TARGET_NR_cacheflush
:
8184 /* self-modifying code is handled automatically, so nothing needed */
8188 #ifdef TARGET_NR_security
8189 case TARGET_NR_security
:
8192 #ifdef TARGET_NR_getpagesize
8193 case TARGET_NR_getpagesize
:
8194 ret
= TARGET_PAGE_SIZE
;
8197 case TARGET_NR_gettid
:
8198 ret
= get_errno(gettid());
8200 #ifdef TARGET_NR_readahead
8201 case TARGET_NR_readahead
:
8202 #if TARGET_ABI_BITS == 32
8203 if (regpairs_aligned(cpu_env
)) {
8208 ret
= get_errno(readahead(arg1
, ((off64_t
)arg3
<< 32) | arg2
, arg4
));
8210 ret
= get_errno(readahead(arg1
, arg2
, arg3
));
8215 #ifdef TARGET_NR_setxattr
8216 case TARGET_NR_listxattr
:
8217 case TARGET_NR_llistxattr
:
8221 b
= lock_user(VERIFY_WRITE
, arg2
, arg3
, 0);
8223 ret
= -TARGET_EFAULT
;
8227 p
= lock_user_string(arg1
);
8229 if (num
== TARGET_NR_listxattr
) {
8230 ret
= get_errno(listxattr(p
, b
, arg3
));
8232 ret
= get_errno(llistxattr(p
, b
, arg3
));
8235 ret
= -TARGET_EFAULT
;
8237 unlock_user(p
, arg1
, 0);
8238 unlock_user(b
, arg2
, arg3
);
8241 case TARGET_NR_flistxattr
:
8245 b
= lock_user(VERIFY_WRITE
, arg2
, arg3
, 0);
8247 ret
= -TARGET_EFAULT
;
8251 ret
= get_errno(flistxattr(arg1
, b
, arg3
));
8252 unlock_user(b
, arg2
, arg3
);
8255 case TARGET_NR_setxattr
:
8256 case TARGET_NR_lsetxattr
:
8258 void *p
, *n
, *v
= 0;
8260 v
= lock_user(VERIFY_READ
, arg3
, arg4
, 1);
8262 ret
= -TARGET_EFAULT
;
8266 p
= lock_user_string(arg1
);
8267 n
= lock_user_string(arg2
);
8269 if (num
== TARGET_NR_setxattr
) {
8270 ret
= get_errno(setxattr(p
, n
, v
, arg4
, arg5
));
8272 ret
= get_errno(lsetxattr(p
, n
, v
, arg4
, arg5
));
8275 ret
= -TARGET_EFAULT
;
8277 unlock_user(p
, arg1
, 0);
8278 unlock_user(n
, arg2
, 0);
8279 unlock_user(v
, arg3
, 0);
8282 case TARGET_NR_fsetxattr
:
8286 v
= lock_user(VERIFY_READ
, arg3
, arg4
, 1);
8288 ret
= -TARGET_EFAULT
;
8292 n
= lock_user_string(arg2
);
8294 ret
= get_errno(fsetxattr(arg1
, n
, v
, arg4
, arg5
));
8296 ret
= -TARGET_EFAULT
;
8298 unlock_user(n
, arg2
, 0);
8299 unlock_user(v
, arg3
, 0);
8302 case TARGET_NR_getxattr
:
8303 case TARGET_NR_lgetxattr
:
8305 void *p
, *n
, *v
= 0;
8307 v
= lock_user(VERIFY_WRITE
, arg3
, arg4
, 0);
8309 ret
= -TARGET_EFAULT
;
8313 p
= lock_user_string(arg1
);
8314 n
= lock_user_string(arg2
);
8316 if (num
== TARGET_NR_getxattr
) {
8317 ret
= get_errno(getxattr(p
, n
, v
, arg4
));
8319 ret
= get_errno(lgetxattr(p
, n
, v
, arg4
));
8322 ret
= -TARGET_EFAULT
;
8324 unlock_user(p
, arg1
, 0);
8325 unlock_user(n
, arg2
, 0);
8326 unlock_user(v
, arg3
, arg4
);
8329 case TARGET_NR_fgetxattr
:
8333 v
= lock_user(VERIFY_WRITE
, arg3
, arg4
, 0);
8335 ret
= -TARGET_EFAULT
;
8339 n
= lock_user_string(arg2
);
8341 ret
= get_errno(fgetxattr(arg1
, n
, v
, arg4
));
8343 ret
= -TARGET_EFAULT
;
8345 unlock_user(n
, arg2
, 0);
8346 unlock_user(v
, arg3
, arg4
);
8349 case TARGET_NR_removexattr
:
8350 case TARGET_NR_lremovexattr
:
8353 p
= lock_user_string(arg1
);
8354 n
= lock_user_string(arg2
);
8356 if (num
== TARGET_NR_removexattr
) {
8357 ret
= get_errno(removexattr(p
, n
));
8359 ret
= get_errno(lremovexattr(p
, n
));
8362 ret
= -TARGET_EFAULT
;
8364 unlock_user(p
, arg1
, 0);
8365 unlock_user(n
, arg2
, 0);
8368 case TARGET_NR_fremovexattr
:
8371 n
= lock_user_string(arg2
);
8373 ret
= get_errno(fremovexattr(arg1
, n
));
8375 ret
= -TARGET_EFAULT
;
8377 unlock_user(n
, arg2
, 0);
8381 #endif /* CONFIG_ATTR */
8382 #ifdef TARGET_NR_set_thread_area
8383 case TARGET_NR_set_thread_area
:
8384 #if defined(TARGET_MIPS)
8385 ((CPUMIPSState
*) cpu_env
)->tls_value
= arg1
;
8388 #elif defined(TARGET_CRIS)
8390 ret
= -TARGET_EINVAL
;
8392 ((CPUCRISState
*) cpu_env
)->pregs
[PR_PID
] = arg1
;
8396 #elif defined(TARGET_I386) && defined(TARGET_ABI32)
8397 ret
= do_set_thread_area(cpu_env
, arg1
);
8400 goto unimplemented_nowarn
;
8403 #ifdef TARGET_NR_get_thread_area
8404 case TARGET_NR_get_thread_area
:
8405 #if defined(TARGET_I386) && defined(TARGET_ABI32)
8406 ret
= do_get_thread_area(cpu_env
, arg1
);
8408 goto unimplemented_nowarn
;
8411 #ifdef TARGET_NR_getdomainname
8412 case TARGET_NR_getdomainname
:
8413 goto unimplemented_nowarn
;
8416 #ifdef TARGET_NR_clock_gettime
8417 case TARGET_NR_clock_gettime
:
8420 ret
= get_errno(clock_gettime(arg1
, &ts
));
8421 if (!is_error(ret
)) {
8422 host_to_target_timespec(arg2
, &ts
);
8427 #ifdef TARGET_NR_clock_getres
8428 case TARGET_NR_clock_getres
:
8431 ret
= get_errno(clock_getres(arg1
, &ts
));
8432 if (!is_error(ret
)) {
8433 host_to_target_timespec(arg2
, &ts
);
8438 #ifdef TARGET_NR_clock_nanosleep
8439 case TARGET_NR_clock_nanosleep
:
8442 target_to_host_timespec(&ts
, arg3
);
8443 ret
= get_errno(clock_nanosleep(arg1
, arg2
, &ts
, arg4
? &ts
: NULL
));
8445 host_to_target_timespec(arg4
, &ts
);
8450 #if defined(TARGET_NR_set_tid_address) && defined(__NR_set_tid_address)
8451 case TARGET_NR_set_tid_address
:
8452 ret
= get_errno(set_tid_address((int *)g2h(arg1
)));
8456 #if defined(TARGET_NR_tkill) && defined(__NR_tkill)
8457 case TARGET_NR_tkill
:
8458 ret
= get_errno(sys_tkill((int)arg1
, target_to_host_signal(arg2
)));
8462 #if defined(TARGET_NR_tgkill) && defined(__NR_tgkill)
8463 case TARGET_NR_tgkill
:
8464 ret
= get_errno(sys_tgkill((int)arg1
, (int)arg2
,
8465 target_to_host_signal(arg3
)));
8469 #ifdef TARGET_NR_set_robust_list
8470 case TARGET_NR_set_robust_list
:
8471 goto unimplemented_nowarn
;
8474 #if defined(TARGET_NR_utimensat) && defined(__NR_utimensat)
8475 case TARGET_NR_utimensat
:
8477 struct timespec
*tsp
, ts
[2];
8481 target_to_host_timespec(ts
, arg3
);
8482 target_to_host_timespec(ts
+1, arg3
+sizeof(struct target_timespec
));
8486 ret
= get_errno(sys_utimensat(arg1
, NULL
, tsp
, arg4
));
8488 if (!(p
= lock_user_string(arg2
))) {
8489 ret
= -TARGET_EFAULT
;
8492 ret
= get_errno(sys_utimensat(arg1
, path(p
), tsp
, arg4
));
8493 unlock_user(p
, arg2
, 0);
8498 #if defined(CONFIG_USE_NPTL)
8499 case TARGET_NR_futex
:
8500 ret
= do_futex(arg1
, arg2
, arg3
, arg4
, arg5
, arg6
);
8503 #if defined(TARGET_NR_inotify_init) && defined(__NR_inotify_init)
8504 case TARGET_NR_inotify_init
:
8505 ret
= get_errno(sys_inotify_init());
8508 #ifdef CONFIG_INOTIFY1
8509 #if defined(TARGET_NR_inotify_init1) && defined(__NR_inotify_init1)
8510 case TARGET_NR_inotify_init1
:
8511 ret
= get_errno(sys_inotify_init1(arg1
));
8515 #if defined(TARGET_NR_inotify_add_watch) && defined(__NR_inotify_add_watch)
8516 case TARGET_NR_inotify_add_watch
:
8517 p
= lock_user_string(arg2
);
8518 ret
= get_errno(sys_inotify_add_watch(arg1
, path(p
), arg3
));
8519 unlock_user(p
, arg2
, 0);
8522 #if defined(TARGET_NR_inotify_rm_watch) && defined(__NR_inotify_rm_watch)
8523 case TARGET_NR_inotify_rm_watch
:
8524 ret
= get_errno(sys_inotify_rm_watch(arg1
, arg2
));
8528 #if defined(TARGET_NR_mq_open) && defined(__NR_mq_open)
8529 case TARGET_NR_mq_open
:
8531 struct mq_attr posix_mq_attr
;
8533 p
= lock_user_string(arg1
- 1);
8535 copy_from_user_mq_attr (&posix_mq_attr
, arg4
);
8536 ret
= get_errno(mq_open(p
, arg2
, arg3
, &posix_mq_attr
));
8537 unlock_user (p
, arg1
, 0);
8541 case TARGET_NR_mq_unlink
:
8542 p
= lock_user_string(arg1
- 1);
8543 ret
= get_errno(mq_unlink(p
));
8544 unlock_user (p
, arg1
, 0);
8547 case TARGET_NR_mq_timedsend
:
8551 p
= lock_user (VERIFY_READ
, arg2
, arg3
, 1);
8553 target_to_host_timespec(&ts
, arg5
);
8554 ret
= get_errno(mq_timedsend(arg1
, p
, arg3
, arg4
, &ts
));
8555 host_to_target_timespec(arg5
, &ts
);
8558 ret
= get_errno(mq_send(arg1
, p
, arg3
, arg4
));
8559 unlock_user (p
, arg2
, arg3
);
8563 case TARGET_NR_mq_timedreceive
:
8568 p
= lock_user (VERIFY_READ
, arg2
, arg3
, 1);
8570 target_to_host_timespec(&ts
, arg5
);
8571 ret
= get_errno(mq_timedreceive(arg1
, p
, arg3
, &prio
, &ts
));
8572 host_to_target_timespec(arg5
, &ts
);
8575 ret
= get_errno(mq_receive(arg1
, p
, arg3
, &prio
));
8576 unlock_user (p
, arg2
, arg3
);
8578 put_user_u32(prio
, arg4
);
8582 /* Not implemented for now... */
8583 /* case TARGET_NR_mq_notify: */
8586 case TARGET_NR_mq_getsetattr
:
8588 struct mq_attr posix_mq_attr_in
, posix_mq_attr_out
;
8591 ret
= mq_getattr(arg1
, &posix_mq_attr_out
);
8592 copy_to_user_mq_attr(arg3
, &posix_mq_attr_out
);
8595 copy_from_user_mq_attr(&posix_mq_attr_in
, arg2
);
8596 ret
|= mq_setattr(arg1
, &posix_mq_attr_in
, &posix_mq_attr_out
);
8603 #ifdef CONFIG_SPLICE
8604 #ifdef TARGET_NR_tee
8607 ret
= get_errno(tee(arg1
,arg2
,arg3
,arg4
));
8611 #ifdef TARGET_NR_splice
8612 case TARGET_NR_splice
:
8614 loff_t loff_in
, loff_out
;
8615 loff_t
*ploff_in
= NULL
, *ploff_out
= NULL
;
8617 get_user_u64(loff_in
, arg2
);
8618 ploff_in
= &loff_in
;
8621 get_user_u64(loff_out
, arg2
);
8622 ploff_out
= &loff_out
;
8624 ret
= get_errno(splice(arg1
, ploff_in
, arg3
, ploff_out
, arg5
, arg6
));
8628 #ifdef TARGET_NR_vmsplice
8629 case TARGET_NR_vmsplice
:
8634 vec
= alloca(count
* sizeof(struct iovec
));
8635 if (lock_iovec(VERIFY_READ
, vec
, arg2
, count
, 1) < 0)
8637 ret
= get_errno(vmsplice(arg1
, vec
, count
, arg4
));
8638 unlock_iovec(vec
, arg2
, count
, 0);
8642 #endif /* CONFIG_SPLICE */
8643 #ifdef CONFIG_EVENTFD
8644 #if defined(TARGET_NR_eventfd)
8645 case TARGET_NR_eventfd
:
8646 ret
= get_errno(eventfd(arg1
, 0));
8649 #if defined(TARGET_NR_eventfd2)
8650 case TARGET_NR_eventfd2
:
8651 ret
= get_errno(eventfd(arg1
, arg2
));
8654 #endif /* CONFIG_EVENTFD */
8655 #if defined(CONFIG_FALLOCATE) && defined(TARGET_NR_fallocate)
8656 case TARGET_NR_fallocate
:
8657 #if TARGET_ABI_BITS == 32
8658 ret
= get_errno(fallocate(arg1
, arg2
, target_offset64(arg3
, arg4
),
8659 target_offset64(arg5
, arg6
)));
8661 ret
= get_errno(fallocate(arg1
, arg2
, arg3
, arg4
));
8665 #if defined(CONFIG_SYNC_FILE_RANGE)
8666 #if defined(TARGET_NR_sync_file_range)
8667 case TARGET_NR_sync_file_range
:
8668 #if TARGET_ABI_BITS == 32
8669 #if defined(TARGET_MIPS)
8670 ret
= get_errno(sync_file_range(arg1
, target_offset64(arg3
, arg4
),
8671 target_offset64(arg5
, arg6
), arg7
));
8673 ret
= get_errno(sync_file_range(arg1
, target_offset64(arg2
, arg3
),
8674 target_offset64(arg4
, arg5
), arg6
));
8675 #endif /* !TARGET_MIPS */
8677 ret
= get_errno(sync_file_range(arg1
, arg2
, arg3
, arg4
));
8681 #if defined(TARGET_NR_sync_file_range2)
8682 case TARGET_NR_sync_file_range2
:
8683 /* This is like sync_file_range but the arguments are reordered */
8684 #if TARGET_ABI_BITS == 32
8685 ret
= get_errno(sync_file_range(arg1
, target_offset64(arg3
, arg4
),
8686 target_offset64(arg5
, arg6
), arg2
));
8688 ret
= get_errno(sync_file_range(arg1
, arg3
, arg4
, arg2
));
8693 #if defined(CONFIG_EPOLL)
8694 #if defined(TARGET_NR_epoll_create)
8695 case TARGET_NR_epoll_create
:
8696 ret
= get_errno(epoll_create(arg1
));
8699 #if defined(TARGET_NR_epoll_create1) && defined(CONFIG_EPOLL_CREATE1)
8700 case TARGET_NR_epoll_create1
:
8701 ret
= get_errno(epoll_create1(arg1
));
8704 #if defined(TARGET_NR_epoll_ctl)
8705 case TARGET_NR_epoll_ctl
:
8707 struct epoll_event ep
;
8708 struct epoll_event
*epp
= 0;
8710 struct target_epoll_event
*target_ep
;
8711 if (!lock_user_struct(VERIFY_READ
, target_ep
, arg4
, 1)) {
8714 ep
.events
= tswap32(target_ep
->events
);
8715 /* The epoll_data_t union is just opaque data to the kernel,
8716 * so we transfer all 64 bits across and need not worry what
8717 * actual data type it is.
8719 ep
.data
.u64
= tswap64(target_ep
->data
.u64
);
8720 unlock_user_struct(target_ep
, arg4
, 0);
8723 ret
= get_errno(epoll_ctl(arg1
, arg2
, arg3
, epp
));
8728 #if defined(TARGET_NR_epoll_pwait) && defined(CONFIG_EPOLL_PWAIT)
8729 #define IMPLEMENT_EPOLL_PWAIT
8731 #if defined(TARGET_NR_epoll_wait) || defined(IMPLEMENT_EPOLL_PWAIT)
8732 #if defined(TARGET_NR_epoll_wait)
8733 case TARGET_NR_epoll_wait
:
8735 #if defined(IMPLEMENT_EPOLL_PWAIT)
8736 case TARGET_NR_epoll_pwait
:
8739 struct target_epoll_event
*target_ep
;
8740 struct epoll_event
*ep
;
8742 int maxevents
= arg3
;
8745 target_ep
= lock_user(VERIFY_WRITE
, arg2
,
8746 maxevents
* sizeof(struct target_epoll_event
), 1);
8751 ep
= alloca(maxevents
* sizeof(struct epoll_event
));
8754 #if defined(IMPLEMENT_EPOLL_PWAIT)
8755 case TARGET_NR_epoll_pwait
:
8757 target_sigset_t
*target_set
;
8758 sigset_t _set
, *set
= &_set
;
8761 target_set
= lock_user(VERIFY_READ
, arg5
,
8762 sizeof(target_sigset_t
), 1);
8764 unlock_user(target_ep
, arg2
, 0);
8767 target_to_host_sigset(set
, target_set
);
8768 unlock_user(target_set
, arg5
, 0);
8773 ret
= get_errno(epoll_pwait(epfd
, ep
, maxevents
, timeout
, set
));
8777 #if defined(TARGET_NR_epoll_wait)
8778 case TARGET_NR_epoll_wait
:
8779 ret
= get_errno(epoll_wait(epfd
, ep
, maxevents
, timeout
));
8783 ret
= -TARGET_ENOSYS
;
8785 if (!is_error(ret
)) {
8787 for (i
= 0; i
< ret
; i
++) {
8788 target_ep
[i
].events
= tswap32(ep
[i
].events
);
8789 target_ep
[i
].data
.u64
= tswap64(ep
[i
].data
.u64
);
8792 unlock_user(target_ep
, arg2
, ret
* sizeof(struct target_epoll_event
));
8797 #ifdef TARGET_NR_prlimit64
8798 case TARGET_NR_prlimit64
:
8800 /* args: pid, resource number, ptr to new rlimit, ptr to old rlimit */
8801 struct target_rlimit64
*target_rnew
, *target_rold
;
8802 struct host_rlimit64 rnew
, rold
, *rnewp
= 0;
8804 if (!lock_user_struct(VERIFY_READ
, target_rnew
, arg3
, 1)) {
8807 rnew
.rlim_cur
= tswap64(target_rnew
->rlim_cur
);
8808 rnew
.rlim_max
= tswap64(target_rnew
->rlim_max
);
8809 unlock_user_struct(target_rnew
, arg3
, 0);
8813 ret
= get_errno(sys_prlimit64(arg1
, arg2
, rnewp
, arg4
? &rold
: 0));
8814 if (!is_error(ret
) && arg4
) {
8815 if (!lock_user_struct(VERIFY_WRITE
, target_rold
, arg4
, 1)) {
8818 target_rold
->rlim_cur
= tswap64(rold
.rlim_cur
);
8819 target_rold
->rlim_max
= tswap64(rold
.rlim_max
);
8820 unlock_user_struct(target_rold
, arg4
, 1);
8827 gemu_log("qemu: Unsupported syscall: %d\n", num
);
8828 #if defined(TARGET_NR_setxattr) || defined(TARGET_NR_get_thread_area) || defined(TARGET_NR_getdomainname) || defined(TARGET_NR_set_robust_list)
8829 unimplemented_nowarn
:
8831 ret
= -TARGET_ENOSYS
;
8836 gemu_log(" = " TARGET_ABI_FMT_ld
"\n", ret
);
8839 print_syscall_ret(num
, ret
);
8842 ret
= -TARGET_EFAULT
;