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, write to the Free Software
18 * Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston,
33 #include <sys/types.h>
39 #include <sys/mount.h>
40 #include <sys/prctl.h>
41 #include <sys/resource.h>
46 #include <sys/socket.h>
50 #include <sys/times.h>
53 #include <sys/statfs.h>
55 #include <sys/sysinfo.h>
56 #include <sys/utsname.h>
57 //#include <sys/user.h>
58 #include <netinet/ip.h>
59 #include <netinet/tcp.h>
60 #include <qemu-common.h>
65 #define termios host_termios
66 #define winsize host_winsize
67 #define termio host_termio
68 #define sgttyb host_sgttyb /* same as target */
69 #define tchars host_tchars /* same as target */
70 #define ltchars host_ltchars /* same as target */
72 #include <linux/termios.h>
73 #include <linux/unistd.h>
74 #include <linux/utsname.h>
75 #include <linux/cdrom.h>
76 #include <linux/hdreg.h>
77 #include <linux/soundcard.h>
79 #include <linux/mtio.h>
81 #include "linux_loop.h"
84 #include "qemu-common.h"
87 #include <linux/futex.h>
88 #define CLONE_NPTL_FLAGS2 (CLONE_SETTLS | \
89 CLONE_PARENT_SETTID | CLONE_CHILD_SETTID | CLONE_CHILD_CLEARTID)
91 /* XXX: Hardcode the above values. */
92 #define CLONE_NPTL_FLAGS2 0
97 //#include <linux/msdos_fs.h>
98 #define VFAT_IOCTL_READDIR_BOTH _IOR('r', 1, struct linux_dirent [2])
99 #define VFAT_IOCTL_READDIR_SHORT _IOR('r', 2, struct linux_dirent [2])
110 #define _syscall0(type,name) \
111 static type name (void) \
113 return syscall(__NR_##name); \
116 #define _syscall1(type,name,type1,arg1) \
117 static type name (type1 arg1) \
119 return syscall(__NR_##name, arg1); \
122 #define _syscall2(type,name,type1,arg1,type2,arg2) \
123 static type name (type1 arg1,type2 arg2) \
125 return syscall(__NR_##name, arg1, arg2); \
128 #define _syscall3(type,name,type1,arg1,type2,arg2,type3,arg3) \
129 static type name (type1 arg1,type2 arg2,type3 arg3) \
131 return syscall(__NR_##name, arg1, arg2, arg3); \
134 #define _syscall4(type,name,type1,arg1,type2,arg2,type3,arg3,type4,arg4) \
135 static type name (type1 arg1,type2 arg2,type3 arg3,type4 arg4) \
137 return syscall(__NR_##name, arg1, arg2, arg3, arg4); \
140 #define _syscall5(type,name,type1,arg1,type2,arg2,type3,arg3,type4,arg4, \
142 static type name (type1 arg1,type2 arg2,type3 arg3,type4 arg4,type5 arg5) \
144 return syscall(__NR_##name, arg1, arg2, arg3, arg4, arg5); \
148 #define _syscall6(type,name,type1,arg1,type2,arg2,type3,arg3,type4,arg4, \
149 type5,arg5,type6,arg6) \
150 static type name (type1 arg1,type2 arg2,type3 arg3,type4 arg4,type5 arg5, \
153 return syscall(__NR_##name, arg1, arg2, arg3, arg4, arg5, arg6); \
157 #define __NR_sys_uname __NR_uname
158 #define __NR_sys_faccessat __NR_faccessat
159 #define __NR_sys_fchmodat __NR_fchmodat
160 #define __NR_sys_fchownat __NR_fchownat
161 #define __NR_sys_fstatat64 __NR_fstatat64
162 #define __NR_sys_futimesat __NR_futimesat
163 #define __NR_sys_getcwd1 __NR_getcwd
164 #define __NR_sys_getdents __NR_getdents
165 #define __NR_sys_getdents64 __NR_getdents64
166 #define __NR_sys_getpriority __NR_getpriority
167 #define __NR_sys_linkat __NR_linkat
168 #define __NR_sys_mkdirat __NR_mkdirat
169 #define __NR_sys_mknodat __NR_mknodat
170 #define __NR_sys_newfstatat __NR_newfstatat
171 #define __NR_sys_openat __NR_openat
172 #define __NR_sys_readlinkat __NR_readlinkat
173 #define __NR_sys_renameat __NR_renameat
174 #define __NR_sys_rt_sigqueueinfo __NR_rt_sigqueueinfo
175 #define __NR_sys_symlinkat __NR_symlinkat
176 #define __NR_sys_syslog __NR_syslog
177 #define __NR_sys_tgkill __NR_tgkill
178 #define __NR_sys_tkill __NR_tkill
179 #define __NR_sys_unlinkat __NR_unlinkat
180 #define __NR_sys_utimensat __NR_utimensat
181 #define __NR_sys_futex __NR_futex
182 #define __NR_sys_inotify_init __NR_inotify_init
183 #define __NR_sys_inotify_add_watch __NR_inotify_add_watch
184 #define __NR_sys_inotify_rm_watch __NR_inotify_rm_watch
186 #if defined(__alpha__) || defined (__ia64__) || defined(__x86_64__)
187 #define __NR__llseek __NR_lseek
191 _syscall0(int, gettid
)
193 /* This is a replacement for the host gettid() and must return a host
195 static int gettid(void) {
199 #if TARGET_ABI_BITS == 32
200 _syscall3(int, sys_getdents
, uint
, fd
, struct linux_dirent
*, dirp
, uint
, count
);
202 #if defined(TARGET_NR_getdents64) && defined(__NR_getdents64)
203 _syscall3(int, sys_getdents64
, uint
, fd
, struct linux_dirent64
*, dirp
, uint
, count
);
205 _syscall2(int, sys_getpriority
, int, which
, int, who
);
206 #if defined(TARGET_NR__llseek) && !defined (__x86_64__)
207 _syscall5(int, _llseek
, uint
, fd
, ulong
, hi
, ulong
, lo
,
208 loff_t
*, res
, uint
, wh
);
210 _syscall3(int,sys_rt_sigqueueinfo
,int,pid
,int,sig
,siginfo_t
*,uinfo
)
211 _syscall3(int,sys_syslog
,int,type
,char*,bufp
,int,len
)
212 #if defined(TARGET_NR_tgkill) && defined(__NR_tgkill)
213 _syscall3(int,sys_tgkill
,int,tgid
,int,pid
,int,sig
)
215 #if defined(TARGET_NR_tkill) && defined(__NR_tkill)
216 _syscall2(int,sys_tkill
,int,tid
,int,sig
)
218 #ifdef __NR_exit_group
219 _syscall1(int,exit_group
,int,error_code
)
221 #if defined(TARGET_NR_set_tid_address) && defined(__NR_set_tid_address)
222 _syscall1(int,set_tid_address
,int *,tidptr
)
224 #if defined(USE_NPTL)
225 #if defined(TARGET_NR_futex) && defined(__NR_futex)
226 _syscall6(int,sys_futex
,int *,uaddr
,int,op
,int,val
,
227 const struct timespec
*,timeout
,int *,uaddr2
,int,val3
)
231 static bitmask_transtbl fcntl_flags_tbl
[] = {
232 { TARGET_O_ACCMODE
, TARGET_O_WRONLY
, O_ACCMODE
, O_WRONLY
, },
233 { TARGET_O_ACCMODE
, TARGET_O_RDWR
, O_ACCMODE
, O_RDWR
, },
234 { TARGET_O_CREAT
, TARGET_O_CREAT
, O_CREAT
, O_CREAT
, },
235 { TARGET_O_EXCL
, TARGET_O_EXCL
, O_EXCL
, O_EXCL
, },
236 { TARGET_O_NOCTTY
, TARGET_O_NOCTTY
, O_NOCTTY
, O_NOCTTY
, },
237 { TARGET_O_TRUNC
, TARGET_O_TRUNC
, O_TRUNC
, O_TRUNC
, },
238 { TARGET_O_APPEND
, TARGET_O_APPEND
, O_APPEND
, O_APPEND
, },
239 { TARGET_O_NONBLOCK
, TARGET_O_NONBLOCK
, O_NONBLOCK
, O_NONBLOCK
, },
240 { TARGET_O_SYNC
, TARGET_O_SYNC
, O_SYNC
, O_SYNC
, },
241 { TARGET_FASYNC
, TARGET_FASYNC
, FASYNC
, FASYNC
, },
242 { TARGET_O_DIRECTORY
, TARGET_O_DIRECTORY
, O_DIRECTORY
, O_DIRECTORY
, },
243 { TARGET_O_NOFOLLOW
, TARGET_O_NOFOLLOW
, O_NOFOLLOW
, O_NOFOLLOW
, },
244 { TARGET_O_LARGEFILE
, TARGET_O_LARGEFILE
, O_LARGEFILE
, O_LARGEFILE
, },
245 #if defined(O_DIRECT)
246 { TARGET_O_DIRECT
, TARGET_O_DIRECT
, O_DIRECT
, O_DIRECT
, },
251 #define COPY_UTSNAME_FIELD(dest, src) \
253 /* __NEW_UTS_LEN doesn't include terminating null */ \
254 (void) strncpy((dest), (src), __NEW_UTS_LEN); \
255 (dest)[__NEW_UTS_LEN] = '\0'; \
258 static int sys_uname(struct new_utsname
*buf
)
260 struct utsname uts_buf
;
262 if (uname(&uts_buf
) < 0)
266 * Just in case these have some differences, we
267 * translate utsname to new_utsname (which is the
268 * struct linux kernel uses).
271 bzero(buf
, sizeof (*buf
));
272 COPY_UTSNAME_FIELD(buf
->sysname
, uts_buf
.sysname
);
273 COPY_UTSNAME_FIELD(buf
->nodename
, uts_buf
.nodename
);
274 COPY_UTSNAME_FIELD(buf
->release
, uts_buf
.release
);
275 COPY_UTSNAME_FIELD(buf
->version
, uts_buf
.version
);
276 COPY_UTSNAME_FIELD(buf
->machine
, uts_buf
.machine
);
278 COPY_UTSNAME_FIELD(buf
->domainname
, uts_buf
.domainname
);
282 #undef COPY_UTSNAME_FIELD
285 static int sys_getcwd1(char *buf
, size_t size
)
287 if (getcwd(buf
, size
) == NULL
) {
288 /* getcwd() sets errno */
291 return strlen(buf
)+1;
296 * Host system seems to have atfile syscall stubs available. We
297 * now enable them one by one as specified by target syscall_nr.h.
300 #ifdef TARGET_NR_faccessat
301 static int sys_faccessat(int dirfd
, const char *pathname
, int mode
)
303 return (faccessat(dirfd
, pathname
, mode
, 0));
306 #ifdef TARGET_NR_fchmodat
307 static int sys_fchmodat(int dirfd
, const char *pathname
, mode_t mode
)
309 return (fchmodat(dirfd
, pathname
, mode
, 0));
312 #if defined(TARGET_NR_fchownat) && defined(USE_UID16)
313 static int sys_fchownat(int dirfd
, const char *pathname
, uid_t owner
,
314 gid_t group
, int flags
)
316 return (fchownat(dirfd
, pathname
, owner
, group
, flags
));
319 #ifdef __NR_fstatat64
320 static int sys_fstatat64(int dirfd
, const char *pathname
, struct stat
*buf
,
323 return (fstatat(dirfd
, pathname
, buf
, flags
));
326 #ifdef __NR_newfstatat
327 static int sys_newfstatat(int dirfd
, const char *pathname
, struct stat
*buf
,
330 return (fstatat(dirfd
, pathname
, buf
, flags
));
333 #ifdef TARGET_NR_futimesat
334 static int sys_futimesat(int dirfd
, const char *pathname
,
335 const struct timeval times
[2])
337 return (futimesat(dirfd
, pathname
, times
));
340 #ifdef TARGET_NR_linkat
341 static int sys_linkat(int olddirfd
, const char *oldpath
,
342 int newdirfd
, const char *newpath
, int flags
)
344 return (linkat(olddirfd
, oldpath
, newdirfd
, newpath
, flags
));
347 #ifdef TARGET_NR_mkdirat
348 static int sys_mkdirat(int dirfd
, const char *pathname
, mode_t mode
)
350 return (mkdirat(dirfd
, pathname
, mode
));
353 #ifdef TARGET_NR_mknodat
354 static int sys_mknodat(int dirfd
, const char *pathname
, mode_t mode
,
357 return (mknodat(dirfd
, pathname
, mode
, dev
));
360 #ifdef TARGET_NR_openat
361 static int sys_openat(int dirfd
, const char *pathname
, int flags
, ...)
364 * open(2) has extra parameter 'mode' when called with
367 if ((flags
& O_CREAT
) != 0) {
372 * Get the 'mode' parameter and translate it to
376 mode
= va_arg(ap
, mode_t
);
377 mode
= target_to_host_bitmask(mode
, fcntl_flags_tbl
);
380 return (openat(dirfd
, pathname
, flags
, mode
));
382 return (openat(dirfd
, pathname
, flags
));
385 #ifdef TARGET_NR_readlinkat
386 static int sys_readlinkat(int dirfd
, const char *pathname
, char *buf
, size_t bufsiz
)
388 return (readlinkat(dirfd
, pathname
, buf
, bufsiz
));
391 #ifdef TARGET_NR_renameat
392 static int sys_renameat(int olddirfd
, const char *oldpath
,
393 int newdirfd
, const char *newpath
)
395 return (renameat(olddirfd
, oldpath
, newdirfd
, newpath
));
398 #ifdef TARGET_NR_symlinkat
399 static int sys_symlinkat(const char *oldpath
, int newdirfd
, const char *newpath
)
401 return (symlinkat(oldpath
, newdirfd
, newpath
));
404 #ifdef TARGET_NR_unlinkat
405 static int sys_unlinkat(int dirfd
, const char *pathname
, int flags
)
407 return (unlinkat(dirfd
, pathname
, flags
));
410 #else /* !CONFIG_ATFILE */
413 * Try direct syscalls instead
415 #if defined(TARGET_NR_faccessat) && defined(__NR_faccessat)
416 _syscall3(int,sys_faccessat
,int,dirfd
,const char *,pathname
,int,mode
)
418 #if defined(TARGET_NR_fchmodat) && defined(__NR_fchmodat)
419 _syscall3(int,sys_fchmodat
,int,dirfd
,const char *,pathname
, mode_t
,mode
)
421 #if defined(TARGET_NR_fchownat) && defined(__NR_fchownat) && defined(USE_UID16)
422 _syscall5(int,sys_fchownat
,int,dirfd
,const char *,pathname
,
423 uid_t
,owner
,gid_t
,group
,int,flags
)
425 #if (defined(TARGET_NR_fstatat64) || defined(TARGET_NR_newfstatat)) && \
426 defined(__NR_fstatat64)
427 _syscall4(int,sys_fstatat64
,int,dirfd
,const char *,pathname
,
428 struct stat
*,buf
,int,flags
)
430 #if defined(TARGET_NR_futimesat) && defined(__NR_futimesat)
431 _syscall3(int,sys_futimesat
,int,dirfd
,const char *,pathname
,
432 const struct timeval
*,times
)
434 #if (defined(TARGET_NR_newfstatat) || defined(TARGET_NR_fstatat64) ) && \
435 defined(__NR_newfstatat)
436 _syscall4(int,sys_newfstatat
,int,dirfd
,const char *,pathname
,
437 struct stat
*,buf
,int,flags
)
439 #if defined(TARGET_NR_linkat) && defined(__NR_linkat)
440 _syscall5(int,sys_linkat
,int,olddirfd
,const char *,oldpath
,
441 int,newdirfd
,const char *,newpath
,int,flags
)
443 #if defined(TARGET_NR_mkdirat) && defined(__NR_mkdirat)
444 _syscall3(int,sys_mkdirat
,int,dirfd
,const char *,pathname
,mode_t
,mode
)
446 #if defined(TARGET_NR_mknodat) && defined(__NR_mknodat)
447 _syscall4(int,sys_mknodat
,int,dirfd
,const char *,pathname
,
448 mode_t
,mode
,dev_t
,dev
)
450 #if defined(TARGET_NR_openat) && defined(__NR_openat)
451 _syscall4(int,sys_openat
,int,dirfd
,const char *,pathname
,int,flags
,mode_t
,mode
)
453 #if defined(TARGET_NR_readlinkat) && defined(__NR_readlinkat)
454 _syscall4(int,sys_readlinkat
,int,dirfd
,const char *,pathname
,
455 char *,buf
,size_t,bufsize
)
457 #if defined(TARGET_NR_renameat) && defined(__NR_renameat)
458 _syscall4(int,sys_renameat
,int,olddirfd
,const char *,oldpath
,
459 int,newdirfd
,const char *,newpath
)
461 #if defined(TARGET_NR_symlinkat) && defined(__NR_symlinkat)
462 _syscall3(int,sys_symlinkat
,const char *,oldpath
,
463 int,newdirfd
,const char *,newpath
)
465 #if defined(TARGET_NR_unlinkat) && defined(__NR_unlinkat)
466 _syscall3(int,sys_unlinkat
,int,dirfd
,const char *,pathname
,int,flags
)
469 #endif /* CONFIG_ATFILE */
471 #ifdef CONFIG_UTIMENSAT
472 static int sys_utimensat(int dirfd
, const char *pathname
,
473 const struct timespec times
[2], int flags
)
475 if (pathname
== NULL
)
476 return futimens(dirfd
, times
);
478 return utimensat(dirfd
, pathname
, times
, flags
);
481 #if defined(TARGET_NR_utimensat) && defined(__NR_utimensat)
482 _syscall4(int,sys_utimensat
,int,dirfd
,const char *,pathname
,
483 const struct timespec
*,tsp
,int,flags
)
485 #endif /* CONFIG_UTIMENSAT */
487 #ifdef CONFIG_INOTIFY
488 #include <sys/inotify.h>
490 #if defined(TARGET_NR_inotify_init) && defined(__NR_inotify_init)
491 static int sys_inotify_init(void)
493 return (inotify_init());
496 #if defined(TARGET_NR_inotify_add_watch) && defined(__NR_inotify_add_watch)
497 static int sys_inotify_add_watch(int fd
,const char *pathname
, int32_t mask
)
499 return (inotify_add_watch(fd
, pathname
, mask
));
502 #if defined(TARGET_NR_inotify_rm_watch) && defined(__NR_inotify_rm_watch)
503 static int sys_inotify_rm_watch(int fd
, int32_t wd
)
505 return (inotify_rm_watch(fd
, wd
));
509 /* Userspace can usually survive runtime without inotify */
510 #undef TARGET_NR_inotify_init
511 #undef TARGET_NR_inotify_add_watch
512 #undef TARGET_NR_inotify_rm_watch
513 #endif /* CONFIG_INOTIFY */
516 extern int personality(int);
517 extern int flock(int, int);
518 extern int setfsuid(int);
519 extern int setfsgid(int);
520 extern int setgroups(int, gid_t
*);
522 #define ERRNO_TABLE_SIZE 1200
524 /* target_to_host_errno_table[] is initialized from
525 * host_to_target_errno_table[] in syscall_init(). */
526 static uint16_t target_to_host_errno_table
[ERRNO_TABLE_SIZE
] = {
530 * This list is the union of errno values overridden in asm-<arch>/errno.h
531 * minus the errnos that are not actually generic to all archs.
533 static uint16_t host_to_target_errno_table
[ERRNO_TABLE_SIZE
] = {
534 [EIDRM
] = TARGET_EIDRM
,
535 [ECHRNG
] = TARGET_ECHRNG
,
536 [EL2NSYNC
] = TARGET_EL2NSYNC
,
537 [EL3HLT
] = TARGET_EL3HLT
,
538 [EL3RST
] = TARGET_EL3RST
,
539 [ELNRNG
] = TARGET_ELNRNG
,
540 [EUNATCH
] = TARGET_EUNATCH
,
541 [ENOCSI
] = TARGET_ENOCSI
,
542 [EL2HLT
] = TARGET_EL2HLT
,
543 [EDEADLK
] = TARGET_EDEADLK
,
544 [ENOLCK
] = TARGET_ENOLCK
,
545 [EBADE
] = TARGET_EBADE
,
546 [EBADR
] = TARGET_EBADR
,
547 [EXFULL
] = TARGET_EXFULL
,
548 [ENOANO
] = TARGET_ENOANO
,
549 [EBADRQC
] = TARGET_EBADRQC
,
550 [EBADSLT
] = TARGET_EBADSLT
,
551 [EBFONT
] = TARGET_EBFONT
,
552 [ENOSTR
] = TARGET_ENOSTR
,
553 [ENODATA
] = TARGET_ENODATA
,
554 [ETIME
] = TARGET_ETIME
,
555 [ENOSR
] = TARGET_ENOSR
,
556 [ENONET
] = TARGET_ENONET
,
557 [ENOPKG
] = TARGET_ENOPKG
,
558 [EREMOTE
] = TARGET_EREMOTE
,
559 [ENOLINK
] = TARGET_ENOLINK
,
560 [EADV
] = TARGET_EADV
,
561 [ESRMNT
] = TARGET_ESRMNT
,
562 [ECOMM
] = TARGET_ECOMM
,
563 [EPROTO
] = TARGET_EPROTO
,
564 [EDOTDOT
] = TARGET_EDOTDOT
,
565 [EMULTIHOP
] = TARGET_EMULTIHOP
,
566 [EBADMSG
] = TARGET_EBADMSG
,
567 [ENAMETOOLONG
] = TARGET_ENAMETOOLONG
,
568 [EOVERFLOW
] = TARGET_EOVERFLOW
,
569 [ENOTUNIQ
] = TARGET_ENOTUNIQ
,
570 [EBADFD
] = TARGET_EBADFD
,
571 [EREMCHG
] = TARGET_EREMCHG
,
572 [ELIBACC
] = TARGET_ELIBACC
,
573 [ELIBBAD
] = TARGET_ELIBBAD
,
574 [ELIBSCN
] = TARGET_ELIBSCN
,
575 [ELIBMAX
] = TARGET_ELIBMAX
,
576 [ELIBEXEC
] = TARGET_ELIBEXEC
,
577 [EILSEQ
] = TARGET_EILSEQ
,
578 [ENOSYS
] = TARGET_ENOSYS
,
579 [ELOOP
] = TARGET_ELOOP
,
580 [ERESTART
] = TARGET_ERESTART
,
581 [ESTRPIPE
] = TARGET_ESTRPIPE
,
582 [ENOTEMPTY
] = TARGET_ENOTEMPTY
,
583 [EUSERS
] = TARGET_EUSERS
,
584 [ENOTSOCK
] = TARGET_ENOTSOCK
,
585 [EDESTADDRREQ
] = TARGET_EDESTADDRREQ
,
586 [EMSGSIZE
] = TARGET_EMSGSIZE
,
587 [EPROTOTYPE
] = TARGET_EPROTOTYPE
,
588 [ENOPROTOOPT
] = TARGET_ENOPROTOOPT
,
589 [EPROTONOSUPPORT
] = TARGET_EPROTONOSUPPORT
,
590 [ESOCKTNOSUPPORT
] = TARGET_ESOCKTNOSUPPORT
,
591 [EOPNOTSUPP
] = TARGET_EOPNOTSUPP
,
592 [EPFNOSUPPORT
] = TARGET_EPFNOSUPPORT
,
593 [EAFNOSUPPORT
] = TARGET_EAFNOSUPPORT
,
594 [EADDRINUSE
] = TARGET_EADDRINUSE
,
595 [EADDRNOTAVAIL
] = TARGET_EADDRNOTAVAIL
,
596 [ENETDOWN
] = TARGET_ENETDOWN
,
597 [ENETUNREACH
] = TARGET_ENETUNREACH
,
598 [ENETRESET
] = TARGET_ENETRESET
,
599 [ECONNABORTED
] = TARGET_ECONNABORTED
,
600 [ECONNRESET
] = TARGET_ECONNRESET
,
601 [ENOBUFS
] = TARGET_ENOBUFS
,
602 [EISCONN
] = TARGET_EISCONN
,
603 [ENOTCONN
] = TARGET_ENOTCONN
,
604 [EUCLEAN
] = TARGET_EUCLEAN
,
605 [ENOTNAM
] = TARGET_ENOTNAM
,
606 [ENAVAIL
] = TARGET_ENAVAIL
,
607 [EISNAM
] = TARGET_EISNAM
,
608 [EREMOTEIO
] = TARGET_EREMOTEIO
,
609 [ESHUTDOWN
] = TARGET_ESHUTDOWN
,
610 [ETOOMANYREFS
] = TARGET_ETOOMANYREFS
,
611 [ETIMEDOUT
] = TARGET_ETIMEDOUT
,
612 [ECONNREFUSED
] = TARGET_ECONNREFUSED
,
613 [EHOSTDOWN
] = TARGET_EHOSTDOWN
,
614 [EHOSTUNREACH
] = TARGET_EHOSTUNREACH
,
615 [EALREADY
] = TARGET_EALREADY
,
616 [EINPROGRESS
] = TARGET_EINPROGRESS
,
617 [ESTALE
] = TARGET_ESTALE
,
618 [ECANCELED
] = TARGET_ECANCELED
,
619 [ENOMEDIUM
] = TARGET_ENOMEDIUM
,
620 [EMEDIUMTYPE
] = TARGET_EMEDIUMTYPE
,
622 [ENOKEY
] = TARGET_ENOKEY
,
625 [EKEYEXPIRED
] = TARGET_EKEYEXPIRED
,
628 [EKEYREVOKED
] = TARGET_EKEYREVOKED
,
631 [EKEYREJECTED
] = TARGET_EKEYREJECTED
,
634 [EOWNERDEAD
] = TARGET_EOWNERDEAD
,
636 #ifdef ENOTRECOVERABLE
637 [ENOTRECOVERABLE
] = TARGET_ENOTRECOVERABLE
,
641 static inline int host_to_target_errno(int err
)
643 if(host_to_target_errno_table
[err
])
644 return host_to_target_errno_table
[err
];
648 static inline int target_to_host_errno(int err
)
650 if (target_to_host_errno_table
[err
])
651 return target_to_host_errno_table
[err
];
655 static inline abi_long
get_errno(abi_long ret
)
658 return -host_to_target_errno(errno
);
663 static inline int is_error(abi_long ret
)
665 return (abi_ulong
)ret
>= (abi_ulong
)(-4096);
668 char *target_strerror(int err
)
670 return strerror(target_to_host_errno(err
));
673 static abi_ulong target_brk
;
674 static abi_ulong target_original_brk
;
676 void target_set_brk(abi_ulong new_brk
)
678 target_original_brk
= target_brk
= HOST_PAGE_ALIGN(new_brk
);
681 /* do_brk() must return target values and target errnos. */
682 abi_long
do_brk(abi_ulong new_brk
)
685 abi_long mapped_addr
;
690 if (new_brk
< target_original_brk
)
693 brk_page
= HOST_PAGE_ALIGN(target_brk
);
695 /* If the new brk is less than this, set it and we're done... */
696 if (new_brk
< brk_page
) {
697 target_brk
= new_brk
;
701 /* We need to allocate more memory after the brk... */
702 new_alloc_size
= HOST_PAGE_ALIGN(new_brk
- brk_page
+ 1);
703 mapped_addr
= get_errno(target_mmap(brk_page
, new_alloc_size
,
704 PROT_READ
|PROT_WRITE
,
705 MAP_ANON
|MAP_FIXED
|MAP_PRIVATE
, 0, 0));
707 if (!is_error(mapped_addr
))
708 target_brk
= new_brk
;
713 static inline abi_long
copy_from_user_fdset(fd_set
*fds
,
714 abi_ulong target_fds_addr
,
718 abi_ulong b
, *target_fds
;
720 nw
= (n
+ TARGET_ABI_BITS
- 1) / TARGET_ABI_BITS
;
721 if (!(target_fds
= lock_user(VERIFY_READ
,
723 sizeof(abi_ulong
) * nw
,
725 return -TARGET_EFAULT
;
729 for (i
= 0; i
< nw
; i
++) {
730 /* grab the abi_ulong */
731 __get_user(b
, &target_fds
[i
]);
732 for (j
= 0; j
< TARGET_ABI_BITS
; j
++) {
733 /* check the bit inside the abi_ulong */
740 unlock_user(target_fds
, target_fds_addr
, 0);
745 static inline abi_long
copy_to_user_fdset(abi_ulong target_fds_addr
,
751 abi_ulong
*target_fds
;
753 nw
= (n
+ TARGET_ABI_BITS
- 1) / TARGET_ABI_BITS
;
754 if (!(target_fds
= lock_user(VERIFY_WRITE
,
756 sizeof(abi_ulong
) * nw
,
758 return -TARGET_EFAULT
;
761 for (i
= 0; i
< nw
; i
++) {
763 for (j
= 0; j
< TARGET_ABI_BITS
; j
++) {
764 v
|= ((FD_ISSET(k
, fds
) != 0) << j
);
767 __put_user(v
, &target_fds
[i
]);
770 unlock_user(target_fds
, target_fds_addr
, sizeof(abi_ulong
) * nw
);
775 #if defined(__alpha__)
781 static inline abi_long
host_to_target_clock_t(long ticks
)
783 #if HOST_HZ == TARGET_HZ
786 return ((int64_t)ticks
* TARGET_HZ
) / HOST_HZ
;
790 static inline abi_long
host_to_target_rusage(abi_ulong target_addr
,
791 const struct rusage
*rusage
)
793 struct target_rusage
*target_rusage
;
795 if (!lock_user_struct(VERIFY_WRITE
, target_rusage
, target_addr
, 0))
796 return -TARGET_EFAULT
;
797 target_rusage
->ru_utime
.tv_sec
= tswapl(rusage
->ru_utime
.tv_sec
);
798 target_rusage
->ru_utime
.tv_usec
= tswapl(rusage
->ru_utime
.tv_usec
);
799 target_rusage
->ru_stime
.tv_sec
= tswapl(rusage
->ru_stime
.tv_sec
);
800 target_rusage
->ru_stime
.tv_usec
= tswapl(rusage
->ru_stime
.tv_usec
);
801 target_rusage
->ru_maxrss
= tswapl(rusage
->ru_maxrss
);
802 target_rusage
->ru_ixrss
= tswapl(rusage
->ru_ixrss
);
803 target_rusage
->ru_idrss
= tswapl(rusage
->ru_idrss
);
804 target_rusage
->ru_isrss
= tswapl(rusage
->ru_isrss
);
805 target_rusage
->ru_minflt
= tswapl(rusage
->ru_minflt
);
806 target_rusage
->ru_majflt
= tswapl(rusage
->ru_majflt
);
807 target_rusage
->ru_nswap
= tswapl(rusage
->ru_nswap
);
808 target_rusage
->ru_inblock
= tswapl(rusage
->ru_inblock
);
809 target_rusage
->ru_oublock
= tswapl(rusage
->ru_oublock
);
810 target_rusage
->ru_msgsnd
= tswapl(rusage
->ru_msgsnd
);
811 target_rusage
->ru_msgrcv
= tswapl(rusage
->ru_msgrcv
);
812 target_rusage
->ru_nsignals
= tswapl(rusage
->ru_nsignals
);
813 target_rusage
->ru_nvcsw
= tswapl(rusage
->ru_nvcsw
);
814 target_rusage
->ru_nivcsw
= tswapl(rusage
->ru_nivcsw
);
815 unlock_user_struct(target_rusage
, target_addr
, 1);
820 static inline abi_long
copy_from_user_timeval(struct timeval
*tv
,
821 abi_ulong target_tv_addr
)
823 struct target_timeval
*target_tv
;
825 if (!lock_user_struct(VERIFY_READ
, target_tv
, target_tv_addr
, 1))
826 return -TARGET_EFAULT
;
828 __get_user(tv
->tv_sec
, &target_tv
->tv_sec
);
829 __get_user(tv
->tv_usec
, &target_tv
->tv_usec
);
831 unlock_user_struct(target_tv
, target_tv_addr
, 0);
836 static inline abi_long
copy_to_user_timeval(abi_ulong target_tv_addr
,
837 const struct timeval
*tv
)
839 struct target_timeval
*target_tv
;
841 if (!lock_user_struct(VERIFY_WRITE
, target_tv
, target_tv_addr
, 0))
842 return -TARGET_EFAULT
;
844 __put_user(tv
->tv_sec
, &target_tv
->tv_sec
);
845 __put_user(tv
->tv_usec
, &target_tv
->tv_usec
);
847 unlock_user_struct(target_tv
, target_tv_addr
, 1);
852 static inline abi_long
copy_from_user_mq_attr(struct mq_attr
*attr
,
853 abi_ulong target_mq_attr_addr
)
855 struct target_mq_attr
*target_mq_attr
;
857 if (!lock_user_struct(VERIFY_READ
, target_mq_attr
,
858 target_mq_attr_addr
, 1))
859 return -TARGET_EFAULT
;
861 __get_user(attr
->mq_flags
, &target_mq_attr
->mq_flags
);
862 __get_user(attr
->mq_maxmsg
, &target_mq_attr
->mq_maxmsg
);
863 __get_user(attr
->mq_msgsize
, &target_mq_attr
->mq_msgsize
);
864 __get_user(attr
->mq_curmsgs
, &target_mq_attr
->mq_curmsgs
);
866 unlock_user_struct(target_mq_attr
, target_mq_attr_addr
, 0);
871 static inline abi_long
copy_to_user_mq_attr(abi_ulong target_mq_attr_addr
,
872 const struct mq_attr
*attr
)
874 struct target_mq_attr
*target_mq_attr
;
876 if (!lock_user_struct(VERIFY_WRITE
, target_mq_attr
,
877 target_mq_attr_addr
, 0))
878 return -TARGET_EFAULT
;
880 __put_user(attr
->mq_flags
, &target_mq_attr
->mq_flags
);
881 __put_user(attr
->mq_maxmsg
, &target_mq_attr
->mq_maxmsg
);
882 __put_user(attr
->mq_msgsize
, &target_mq_attr
->mq_msgsize
);
883 __put_user(attr
->mq_curmsgs
, &target_mq_attr
->mq_curmsgs
);
885 unlock_user_struct(target_mq_attr
, target_mq_attr_addr
, 1);
890 /* do_select() must return target values and target errnos. */
891 static abi_long
do_select(int n
,
892 abi_ulong rfd_addr
, abi_ulong wfd_addr
,
893 abi_ulong efd_addr
, abi_ulong target_tv_addr
)
895 fd_set rfds
, wfds
, efds
;
896 fd_set
*rfds_ptr
, *wfds_ptr
, *efds_ptr
;
897 struct timeval tv
, *tv_ptr
;
901 if (copy_from_user_fdset(&rfds
, rfd_addr
, n
))
902 return -TARGET_EFAULT
;
908 if (copy_from_user_fdset(&wfds
, wfd_addr
, n
))
909 return -TARGET_EFAULT
;
915 if (copy_from_user_fdset(&efds
, efd_addr
, n
))
916 return -TARGET_EFAULT
;
922 if (target_tv_addr
) {
923 if (copy_from_user_timeval(&tv
, target_tv_addr
))
924 return -TARGET_EFAULT
;
930 ret
= get_errno(select(n
, rfds_ptr
, wfds_ptr
, efds_ptr
, tv_ptr
));
932 if (!is_error(ret
)) {
933 if (rfd_addr
&& copy_to_user_fdset(rfd_addr
, &rfds
, n
))
934 return -TARGET_EFAULT
;
935 if (wfd_addr
&& copy_to_user_fdset(wfd_addr
, &wfds
, n
))
936 return -TARGET_EFAULT
;
937 if (efd_addr
&& copy_to_user_fdset(efd_addr
, &efds
, n
))
938 return -TARGET_EFAULT
;
940 if (target_tv_addr
&& copy_to_user_timeval(target_tv_addr
, &tv
))
941 return -TARGET_EFAULT
;
947 static abi_long
do_pipe2(int host_pipe
[], int flags
)
950 return pipe2(host_pipe
, flags
);
956 static abi_long
do_pipe(void *cpu_env
, int pipedes
, int flags
)
960 ret
= flags
? do_pipe2(host_pipe
, flags
) : pipe(host_pipe
);
963 return get_errno(ret
);
964 #if defined(TARGET_MIPS)
965 ((CPUMIPSState
*)cpu_env
)->active_tc
.gpr
[3] = host_pipe
[1];
967 #elif defined(TARGET_SH4)
968 ((CPUSH4State
*)cpu_env
)->gregs
[1] = host_pipe
[1];
971 if (put_user_s32(host_pipe
[0], pipedes
)
972 || put_user_s32(host_pipe
[1], pipedes
+ sizeof(host_pipe
[0])))
973 return -TARGET_EFAULT
;
975 return get_errno(ret
);
978 static inline abi_long
target_to_host_ip_mreq(struct ip_mreqn
*mreqn
,
979 abi_ulong target_addr
,
982 struct target_ip_mreqn
*target_smreqn
;
984 target_smreqn
= lock_user(VERIFY_READ
, target_addr
, len
, 1);
986 return -TARGET_EFAULT
;
987 mreqn
->imr_multiaddr
.s_addr
= target_smreqn
->imr_multiaddr
.s_addr
;
988 mreqn
->imr_address
.s_addr
= target_smreqn
->imr_address
.s_addr
;
989 if (len
== sizeof(struct target_ip_mreqn
))
990 mreqn
->imr_ifindex
= tswapl(target_smreqn
->imr_ifindex
);
991 unlock_user(target_smreqn
, target_addr
, 0);
996 static inline abi_long
target_to_host_sockaddr(struct sockaddr
*addr
,
997 abi_ulong target_addr
,
1000 const socklen_t unix_maxlen
= sizeof (struct sockaddr_un
);
1001 sa_family_t sa_family
;
1002 struct target_sockaddr
*target_saddr
;
1004 target_saddr
= lock_user(VERIFY_READ
, target_addr
, len
, 1);
1006 return -TARGET_EFAULT
;
1008 sa_family
= tswap16(target_saddr
->sa_family
);
1010 /* Oops. The caller might send a incomplete sun_path; sun_path
1011 * must be terminated by \0 (see the manual page), but
1012 * unfortunately it is quite common to specify sockaddr_un
1013 * length as "strlen(x->sun_path)" while it should be
1014 * "strlen(...) + 1". We'll fix that here if needed.
1015 * Linux kernel has a similar feature.
1018 if (sa_family
== AF_UNIX
) {
1019 if (len
< unix_maxlen
&& len
> 0) {
1020 char *cp
= (char*)target_saddr
;
1022 if ( cp
[len
-1] && !cp
[len
] )
1025 if (len
> unix_maxlen
)
1029 memcpy(addr
, target_saddr
, len
);
1030 addr
->sa_family
= sa_family
;
1031 unlock_user(target_saddr
, target_addr
, 0);
1036 static inline abi_long
host_to_target_sockaddr(abi_ulong target_addr
,
1037 struct sockaddr
*addr
,
1040 struct target_sockaddr
*target_saddr
;
1042 target_saddr
= lock_user(VERIFY_WRITE
, target_addr
, len
, 0);
1044 return -TARGET_EFAULT
;
1045 memcpy(target_saddr
, addr
, len
);
1046 target_saddr
->sa_family
= tswap16(addr
->sa_family
);
1047 unlock_user(target_saddr
, target_addr
, len
);
1052 /* ??? Should this also swap msgh->name? */
1053 static inline abi_long
target_to_host_cmsg(struct msghdr
*msgh
,
1054 struct target_msghdr
*target_msgh
)
1056 struct cmsghdr
*cmsg
= CMSG_FIRSTHDR(msgh
);
1057 abi_long msg_controllen
;
1058 abi_ulong target_cmsg_addr
;
1059 struct target_cmsghdr
*target_cmsg
;
1060 socklen_t space
= 0;
1062 msg_controllen
= tswapl(target_msgh
->msg_controllen
);
1063 if (msg_controllen
< sizeof (struct target_cmsghdr
))
1065 target_cmsg_addr
= tswapl(target_msgh
->msg_control
);
1066 target_cmsg
= lock_user(VERIFY_READ
, target_cmsg_addr
, msg_controllen
, 1);
1068 return -TARGET_EFAULT
;
1070 while (cmsg
&& target_cmsg
) {
1071 void *data
= CMSG_DATA(cmsg
);
1072 void *target_data
= TARGET_CMSG_DATA(target_cmsg
);
1074 int len
= tswapl(target_cmsg
->cmsg_len
)
1075 - TARGET_CMSG_ALIGN(sizeof (struct target_cmsghdr
));
1077 space
+= CMSG_SPACE(len
);
1078 if (space
> msgh
->msg_controllen
) {
1079 space
-= CMSG_SPACE(len
);
1080 gemu_log("Host cmsg overflow\n");
1084 cmsg
->cmsg_level
= tswap32(target_cmsg
->cmsg_level
);
1085 cmsg
->cmsg_type
= tswap32(target_cmsg
->cmsg_type
);
1086 cmsg
->cmsg_len
= CMSG_LEN(len
);
1088 if (cmsg
->cmsg_level
!= TARGET_SOL_SOCKET
|| cmsg
->cmsg_type
!= SCM_RIGHTS
) {
1089 gemu_log("Unsupported ancillary data: %d/%d\n", cmsg
->cmsg_level
, cmsg
->cmsg_type
);
1090 memcpy(data
, target_data
, len
);
1092 int *fd
= (int *)data
;
1093 int *target_fd
= (int *)target_data
;
1094 int i
, numfds
= len
/ sizeof(int);
1096 for (i
= 0; i
< numfds
; i
++)
1097 fd
[i
] = tswap32(target_fd
[i
]);
1100 cmsg
= CMSG_NXTHDR(msgh
, cmsg
);
1101 target_cmsg
= TARGET_CMSG_NXTHDR(target_msgh
, target_cmsg
);
1103 unlock_user(target_cmsg
, target_cmsg_addr
, 0);
1105 msgh
->msg_controllen
= space
;
1109 /* ??? Should this also swap msgh->name? */
1110 static inline abi_long
host_to_target_cmsg(struct target_msghdr
*target_msgh
,
1111 struct msghdr
*msgh
)
1113 struct cmsghdr
*cmsg
= CMSG_FIRSTHDR(msgh
);
1114 abi_long msg_controllen
;
1115 abi_ulong target_cmsg_addr
;
1116 struct target_cmsghdr
*target_cmsg
;
1117 socklen_t space
= 0;
1119 msg_controllen
= tswapl(target_msgh
->msg_controllen
);
1120 if (msg_controllen
< sizeof (struct target_cmsghdr
))
1122 target_cmsg_addr
= tswapl(target_msgh
->msg_control
);
1123 target_cmsg
= lock_user(VERIFY_WRITE
, target_cmsg_addr
, msg_controllen
, 0);
1125 return -TARGET_EFAULT
;
1127 while (cmsg
&& target_cmsg
) {
1128 void *data
= CMSG_DATA(cmsg
);
1129 void *target_data
= TARGET_CMSG_DATA(target_cmsg
);
1131 int len
= cmsg
->cmsg_len
- CMSG_ALIGN(sizeof (struct cmsghdr
));
1133 space
+= TARGET_CMSG_SPACE(len
);
1134 if (space
> msg_controllen
) {
1135 space
-= TARGET_CMSG_SPACE(len
);
1136 gemu_log("Target cmsg overflow\n");
1140 target_cmsg
->cmsg_level
= tswap32(cmsg
->cmsg_level
);
1141 target_cmsg
->cmsg_type
= tswap32(cmsg
->cmsg_type
);
1142 target_cmsg
->cmsg_len
= tswapl(TARGET_CMSG_LEN(len
));
1144 if (cmsg
->cmsg_level
!= TARGET_SOL_SOCKET
|| cmsg
->cmsg_type
!= SCM_RIGHTS
) {
1145 gemu_log("Unsupported ancillary data: %d/%d\n", cmsg
->cmsg_level
, cmsg
->cmsg_type
);
1146 memcpy(target_data
, data
, len
);
1148 int *fd
= (int *)data
;
1149 int *target_fd
= (int *)target_data
;
1150 int i
, numfds
= len
/ sizeof(int);
1152 for (i
= 0; i
< numfds
; i
++)
1153 target_fd
[i
] = tswap32(fd
[i
]);
1156 cmsg
= CMSG_NXTHDR(msgh
, cmsg
);
1157 target_cmsg
= TARGET_CMSG_NXTHDR(target_msgh
, target_cmsg
);
1159 unlock_user(target_cmsg
, target_cmsg_addr
, space
);
1161 target_msgh
->msg_controllen
= tswapl(space
);
1165 /* do_setsockopt() Must return target values and target errnos. */
1166 static abi_long
do_setsockopt(int sockfd
, int level
, int optname
,
1167 abi_ulong optval_addr
, socklen_t optlen
)
1171 struct ip_mreqn
*ip_mreq
;
1172 struct ip_mreq_source
*ip_mreq_source
;
1176 /* TCP options all take an 'int' value. */
1177 if (optlen
< sizeof(uint32_t))
1178 return -TARGET_EINVAL
;
1180 if (get_user_u32(val
, optval_addr
))
1181 return -TARGET_EFAULT
;
1182 ret
= get_errno(setsockopt(sockfd
, level
, optname
, &val
, sizeof(val
)));
1189 case IP_ROUTER_ALERT
:
1193 case IP_MTU_DISCOVER
:
1199 case IP_MULTICAST_TTL
:
1200 case IP_MULTICAST_LOOP
:
1202 if (optlen
>= sizeof(uint32_t)) {
1203 if (get_user_u32(val
, optval_addr
))
1204 return -TARGET_EFAULT
;
1205 } else if (optlen
>= 1) {
1206 if (get_user_u8(val
, optval_addr
))
1207 return -TARGET_EFAULT
;
1209 ret
= get_errno(setsockopt(sockfd
, level
, optname
, &val
, sizeof(val
)));
1211 case IP_ADD_MEMBERSHIP
:
1212 case IP_DROP_MEMBERSHIP
:
1213 if (optlen
< sizeof (struct target_ip_mreq
) ||
1214 optlen
> sizeof (struct target_ip_mreqn
))
1215 return -TARGET_EINVAL
;
1217 ip_mreq
= (struct ip_mreqn
*) alloca(optlen
);
1218 target_to_host_ip_mreq(ip_mreq
, optval_addr
, optlen
);
1219 ret
= get_errno(setsockopt(sockfd
, level
, optname
, ip_mreq
, optlen
));
1222 case IP_BLOCK_SOURCE
:
1223 case IP_UNBLOCK_SOURCE
:
1224 case IP_ADD_SOURCE_MEMBERSHIP
:
1225 case IP_DROP_SOURCE_MEMBERSHIP
:
1226 if (optlen
!= sizeof (struct target_ip_mreq_source
))
1227 return -TARGET_EINVAL
;
1229 ip_mreq_source
= lock_user(VERIFY_READ
, optval_addr
, optlen
, 1);
1230 ret
= get_errno(setsockopt(sockfd
, level
, optname
, ip_mreq_source
, optlen
));
1231 unlock_user (ip_mreq_source
, optval_addr
, 0);
1238 case TARGET_SOL_SOCKET
:
1240 /* Options with 'int' argument. */
1241 case TARGET_SO_DEBUG
:
1244 case TARGET_SO_REUSEADDR
:
1245 optname
= SO_REUSEADDR
;
1247 case TARGET_SO_TYPE
:
1250 case TARGET_SO_ERROR
:
1253 case TARGET_SO_DONTROUTE
:
1254 optname
= SO_DONTROUTE
;
1256 case TARGET_SO_BROADCAST
:
1257 optname
= SO_BROADCAST
;
1259 case TARGET_SO_SNDBUF
:
1260 optname
= SO_SNDBUF
;
1262 case TARGET_SO_RCVBUF
:
1263 optname
= SO_RCVBUF
;
1265 case TARGET_SO_KEEPALIVE
:
1266 optname
= SO_KEEPALIVE
;
1268 case TARGET_SO_OOBINLINE
:
1269 optname
= SO_OOBINLINE
;
1271 case TARGET_SO_NO_CHECK
:
1272 optname
= SO_NO_CHECK
;
1274 case TARGET_SO_PRIORITY
:
1275 optname
= SO_PRIORITY
;
1278 case TARGET_SO_BSDCOMPAT
:
1279 optname
= SO_BSDCOMPAT
;
1282 case TARGET_SO_PASSCRED
:
1283 optname
= SO_PASSCRED
;
1285 case TARGET_SO_TIMESTAMP
:
1286 optname
= SO_TIMESTAMP
;
1288 case TARGET_SO_RCVLOWAT
:
1289 optname
= SO_RCVLOWAT
;
1291 case TARGET_SO_RCVTIMEO
:
1292 optname
= SO_RCVTIMEO
;
1294 case TARGET_SO_SNDTIMEO
:
1295 optname
= SO_SNDTIMEO
;
1301 if (optlen
< sizeof(uint32_t))
1302 return -TARGET_EINVAL
;
1304 if (get_user_u32(val
, optval_addr
))
1305 return -TARGET_EFAULT
;
1306 ret
= get_errno(setsockopt(sockfd
, SOL_SOCKET
, optname
, &val
, sizeof(val
)));
1310 gemu_log("Unsupported setsockopt level=%d optname=%d \n", level
, optname
);
1311 ret
= -TARGET_ENOPROTOOPT
;
1316 /* do_getsockopt() Must return target values and target errnos. */
1317 static abi_long
do_getsockopt(int sockfd
, int level
, int optname
,
1318 abi_ulong optval_addr
, abi_ulong optlen
)
1325 case TARGET_SOL_SOCKET
:
1328 case TARGET_SO_LINGER
:
1329 case TARGET_SO_RCVTIMEO
:
1330 case TARGET_SO_SNDTIMEO
:
1331 case TARGET_SO_PEERCRED
:
1332 case TARGET_SO_PEERNAME
:
1333 /* These don't just return a single integer */
1340 /* TCP options all take an 'int' value. */
1342 if (get_user_u32(len
, optlen
))
1343 return -TARGET_EFAULT
;
1345 return -TARGET_EINVAL
;
1347 ret
= get_errno(getsockopt(sockfd
, level
, optname
, &val
, &lv
));
1354 if (put_user_u32(val
, optval_addr
))
1355 return -TARGET_EFAULT
;
1357 if (put_user_u8(val
, optval_addr
))
1358 return -TARGET_EFAULT
;
1360 if (put_user_u32(len
, optlen
))
1361 return -TARGET_EFAULT
;
1368 case IP_ROUTER_ALERT
:
1372 case IP_MTU_DISCOVER
:
1378 case IP_MULTICAST_TTL
:
1379 case IP_MULTICAST_LOOP
:
1380 if (get_user_u32(len
, optlen
))
1381 return -TARGET_EFAULT
;
1383 return -TARGET_EINVAL
;
1385 ret
= get_errno(getsockopt(sockfd
, level
, optname
, &val
, &lv
));
1388 if (len
< sizeof(int) && len
> 0 && val
>= 0 && val
< 255) {
1390 if (put_user_u32(len
, optlen
)
1391 || put_user_u8(val
, optval_addr
))
1392 return -TARGET_EFAULT
;
1394 if (len
> sizeof(int))
1396 if (put_user_u32(len
, optlen
)
1397 || put_user_u32(val
, optval_addr
))
1398 return -TARGET_EFAULT
;
1402 ret
= -TARGET_ENOPROTOOPT
;
1408 gemu_log("getsockopt level=%d optname=%d not yet supported\n",
1410 ret
= -TARGET_EOPNOTSUPP
;
1417 * lock_iovec()/unlock_iovec() have a return code of 0 for success where
1418 * other lock functions have a return code of 0 for failure.
1420 static abi_long
lock_iovec(int type
, struct iovec
*vec
, abi_ulong target_addr
,
1421 int count
, int copy
)
1423 struct target_iovec
*target_vec
;
1427 target_vec
= lock_user(VERIFY_READ
, target_addr
, count
* sizeof(struct target_iovec
), 1);
1429 return -TARGET_EFAULT
;
1430 for(i
= 0;i
< count
; i
++) {
1431 base
= tswapl(target_vec
[i
].iov_base
);
1432 vec
[i
].iov_len
= tswapl(target_vec
[i
].iov_len
);
1433 if (vec
[i
].iov_len
!= 0) {
1434 vec
[i
].iov_base
= lock_user(type
, base
, vec
[i
].iov_len
, copy
);
1435 /* Don't check lock_user return value. We must call writev even
1436 if a element has invalid base address. */
1438 /* zero length pointer is ignored */
1439 vec
[i
].iov_base
= NULL
;
1442 unlock_user (target_vec
, target_addr
, 0);
1446 static abi_long
unlock_iovec(struct iovec
*vec
, abi_ulong target_addr
,
1447 int count
, int copy
)
1449 struct target_iovec
*target_vec
;
1453 target_vec
= lock_user(VERIFY_READ
, target_addr
, count
* sizeof(struct target_iovec
), 1);
1455 return -TARGET_EFAULT
;
1456 for(i
= 0;i
< count
; i
++) {
1457 if (target_vec
[i
].iov_base
) {
1458 base
= tswapl(target_vec
[i
].iov_base
);
1459 unlock_user(vec
[i
].iov_base
, base
, copy
? vec
[i
].iov_len
: 0);
1462 unlock_user (target_vec
, target_addr
, 0);
1467 /* do_socket() Must return target values and target errnos. */
1468 static abi_long
do_socket(int domain
, int type
, int protocol
)
1470 #if defined(TARGET_MIPS)
1472 case TARGET_SOCK_DGRAM
:
1475 case TARGET_SOCK_STREAM
:
1478 case TARGET_SOCK_RAW
:
1481 case TARGET_SOCK_RDM
:
1484 case TARGET_SOCK_SEQPACKET
:
1485 type
= SOCK_SEQPACKET
;
1487 case TARGET_SOCK_PACKET
:
1492 if (domain
== PF_NETLINK
)
1493 return -EAFNOSUPPORT
; /* do not NETLINK socket connections possible */
1494 return get_errno(socket(domain
, type
, protocol
));
1497 /* do_bind() Must return target values and target errnos. */
1498 static abi_long
do_bind(int sockfd
, abi_ulong target_addr
,
1504 return -TARGET_EINVAL
;
1506 addr
= alloca(addrlen
+1);
1508 target_to_host_sockaddr(addr
, target_addr
, addrlen
);
1509 return get_errno(bind(sockfd
, addr
, addrlen
));
1512 /* do_connect() Must return target values and target errnos. */
1513 static abi_long
do_connect(int sockfd
, abi_ulong target_addr
,
1519 return -TARGET_EINVAL
;
1521 addr
= alloca(addrlen
);
1523 target_to_host_sockaddr(addr
, target_addr
, addrlen
);
1524 return get_errno(connect(sockfd
, addr
, addrlen
));
1527 /* do_sendrecvmsg() Must return target values and target errnos. */
1528 static abi_long
do_sendrecvmsg(int fd
, abi_ulong target_msg
,
1529 int flags
, int send
)
1532 struct target_msghdr
*msgp
;
1536 abi_ulong target_vec
;
1539 if (!lock_user_struct(send
? VERIFY_READ
: VERIFY_WRITE
,
1543 return -TARGET_EFAULT
;
1544 if (msgp
->msg_name
) {
1545 msg
.msg_namelen
= tswap32(msgp
->msg_namelen
);
1546 msg
.msg_name
= alloca(msg
.msg_namelen
);
1547 target_to_host_sockaddr(msg
.msg_name
, tswapl(msgp
->msg_name
),
1550 msg
.msg_name
= NULL
;
1551 msg
.msg_namelen
= 0;
1553 msg
.msg_controllen
= 2 * tswapl(msgp
->msg_controllen
);
1554 msg
.msg_control
= alloca(msg
.msg_controllen
);
1555 msg
.msg_flags
= tswap32(msgp
->msg_flags
);
1557 count
= tswapl(msgp
->msg_iovlen
);
1558 vec
= alloca(count
* sizeof(struct iovec
));
1559 target_vec
= tswapl(msgp
->msg_iov
);
1560 lock_iovec(send
? VERIFY_READ
: VERIFY_WRITE
, vec
, target_vec
, count
, send
);
1561 msg
.msg_iovlen
= count
;
1565 ret
= target_to_host_cmsg(&msg
, msgp
);
1567 ret
= get_errno(sendmsg(fd
, &msg
, flags
));
1569 ret
= get_errno(recvmsg(fd
, &msg
, flags
));
1570 if (!is_error(ret
)) {
1572 ret
= host_to_target_cmsg(msgp
, &msg
);
1577 unlock_iovec(vec
, target_vec
, count
, !send
);
1578 unlock_user_struct(msgp
, target_msg
, send
? 0 : 1);
1582 /* do_accept() Must return target values and target errnos. */
1583 static abi_long
do_accept(int fd
, abi_ulong target_addr
,
1584 abi_ulong target_addrlen_addr
)
1590 if (get_user_u32(addrlen
, target_addrlen_addr
))
1591 return -TARGET_EFAULT
;
1594 return -TARGET_EINVAL
;
1596 addr
= alloca(addrlen
);
1598 ret
= get_errno(accept(fd
, addr
, &addrlen
));
1599 if (!is_error(ret
)) {
1600 host_to_target_sockaddr(target_addr
, addr
, addrlen
);
1601 if (put_user_u32(addrlen
, target_addrlen_addr
))
1602 ret
= -TARGET_EFAULT
;
1607 /* do_getpeername() Must return target values and target errnos. */
1608 static abi_long
do_getpeername(int fd
, abi_ulong target_addr
,
1609 abi_ulong target_addrlen_addr
)
1615 if (get_user_u32(addrlen
, target_addrlen_addr
))
1616 return -TARGET_EFAULT
;
1619 return -TARGET_EINVAL
;
1621 addr
= alloca(addrlen
);
1623 ret
= get_errno(getpeername(fd
, addr
, &addrlen
));
1624 if (!is_error(ret
)) {
1625 host_to_target_sockaddr(target_addr
, addr
, addrlen
);
1626 if (put_user_u32(addrlen
, target_addrlen_addr
))
1627 ret
= -TARGET_EFAULT
;
1632 /* do_getsockname() Must return target values and target errnos. */
1633 static abi_long
do_getsockname(int fd
, abi_ulong target_addr
,
1634 abi_ulong target_addrlen_addr
)
1640 if (target_addr
== 0)
1641 return get_errno(accept(fd
, NULL
, NULL
));
1643 if (get_user_u32(addrlen
, target_addrlen_addr
))
1644 return -TARGET_EFAULT
;
1647 return -TARGET_EINVAL
;
1649 addr
= alloca(addrlen
);
1651 ret
= get_errno(getsockname(fd
, addr
, &addrlen
));
1652 if (!is_error(ret
)) {
1653 host_to_target_sockaddr(target_addr
, addr
, addrlen
);
1654 if (put_user_u32(addrlen
, target_addrlen_addr
))
1655 ret
= -TARGET_EFAULT
;
1660 /* do_socketpair() Must return target values and target errnos. */
1661 static abi_long
do_socketpair(int domain
, int type
, int protocol
,
1662 abi_ulong target_tab_addr
)
1667 ret
= get_errno(socketpair(domain
, type
, protocol
, tab
));
1668 if (!is_error(ret
)) {
1669 if (put_user_s32(tab
[0], target_tab_addr
)
1670 || put_user_s32(tab
[1], target_tab_addr
+ sizeof(tab
[0])))
1671 ret
= -TARGET_EFAULT
;
1676 /* do_sendto() Must return target values and target errnos. */
1677 static abi_long
do_sendto(int fd
, abi_ulong msg
, size_t len
, int flags
,
1678 abi_ulong target_addr
, socklen_t addrlen
)
1685 return -TARGET_EINVAL
;
1687 host_msg
= lock_user(VERIFY_READ
, msg
, len
, 1);
1689 return -TARGET_EFAULT
;
1691 addr
= alloca(addrlen
);
1692 target_to_host_sockaddr(addr
, target_addr
, addrlen
);
1693 ret
= get_errno(sendto(fd
, host_msg
, len
, flags
, addr
, addrlen
));
1695 ret
= get_errno(send(fd
, host_msg
, len
, flags
));
1697 unlock_user(host_msg
, msg
, 0);
1701 /* do_recvfrom() Must return target values and target errnos. */
1702 static abi_long
do_recvfrom(int fd
, abi_ulong msg
, size_t len
, int flags
,
1703 abi_ulong target_addr
,
1704 abi_ulong target_addrlen
)
1711 host_msg
= lock_user(VERIFY_WRITE
, msg
, len
, 0);
1713 return -TARGET_EFAULT
;
1715 if (get_user_u32(addrlen
, target_addrlen
)) {
1716 ret
= -TARGET_EFAULT
;
1720 ret
= -TARGET_EINVAL
;
1723 addr
= alloca(addrlen
);
1724 ret
= get_errno(recvfrom(fd
, host_msg
, len
, flags
, addr
, &addrlen
));
1726 addr
= NULL
; /* To keep compiler quiet. */
1727 ret
= get_errno(recv(fd
, host_msg
, len
, flags
));
1729 if (!is_error(ret
)) {
1731 host_to_target_sockaddr(target_addr
, addr
, addrlen
);
1732 if (put_user_u32(addrlen
, target_addrlen
)) {
1733 ret
= -TARGET_EFAULT
;
1737 unlock_user(host_msg
, msg
, len
);
1740 unlock_user(host_msg
, msg
, 0);
1745 #ifdef TARGET_NR_socketcall
1746 /* do_socketcall() Must return target values and target errnos. */
1747 static abi_long
do_socketcall(int num
, abi_ulong vptr
)
1750 const int n
= sizeof(abi_ulong
);
1755 int domain
, type
, protocol
;
1757 if (get_user_s32(domain
, vptr
)
1758 || get_user_s32(type
, vptr
+ n
)
1759 || get_user_s32(protocol
, vptr
+ 2 * n
))
1760 return -TARGET_EFAULT
;
1762 ret
= do_socket(domain
, type
, protocol
);
1768 abi_ulong target_addr
;
1771 if (get_user_s32(sockfd
, vptr
)
1772 || get_user_ual(target_addr
, vptr
+ n
)
1773 || get_user_u32(addrlen
, vptr
+ 2 * n
))
1774 return -TARGET_EFAULT
;
1776 ret
= do_bind(sockfd
, target_addr
, addrlen
);
1779 case SOCKOP_connect
:
1782 abi_ulong target_addr
;
1785 if (get_user_s32(sockfd
, vptr
)
1786 || get_user_ual(target_addr
, vptr
+ n
)
1787 || get_user_u32(addrlen
, vptr
+ 2 * n
))
1788 return -TARGET_EFAULT
;
1790 ret
= do_connect(sockfd
, target_addr
, addrlen
);
1795 int sockfd
, backlog
;
1797 if (get_user_s32(sockfd
, vptr
)
1798 || get_user_s32(backlog
, vptr
+ n
))
1799 return -TARGET_EFAULT
;
1801 ret
= get_errno(listen(sockfd
, backlog
));
1807 abi_ulong target_addr
, target_addrlen
;
1809 if (get_user_s32(sockfd
, vptr
)
1810 || get_user_ual(target_addr
, vptr
+ n
)
1811 || get_user_u32(target_addrlen
, vptr
+ 2 * n
))
1812 return -TARGET_EFAULT
;
1814 ret
= do_accept(sockfd
, target_addr
, target_addrlen
);
1817 case SOCKOP_getsockname
:
1820 abi_ulong target_addr
, target_addrlen
;
1822 if (get_user_s32(sockfd
, vptr
)
1823 || get_user_ual(target_addr
, vptr
+ n
)
1824 || get_user_u32(target_addrlen
, vptr
+ 2 * n
))
1825 return -TARGET_EFAULT
;
1827 ret
= do_getsockname(sockfd
, target_addr
, target_addrlen
);
1830 case SOCKOP_getpeername
:
1833 abi_ulong target_addr
, target_addrlen
;
1835 if (get_user_s32(sockfd
, vptr
)
1836 || get_user_ual(target_addr
, vptr
+ n
)
1837 || get_user_u32(target_addrlen
, vptr
+ 2 * n
))
1838 return -TARGET_EFAULT
;
1840 ret
= do_getpeername(sockfd
, target_addr
, target_addrlen
);
1843 case SOCKOP_socketpair
:
1845 int domain
, type
, protocol
;
1848 if (get_user_s32(domain
, vptr
)
1849 || get_user_s32(type
, vptr
+ n
)
1850 || get_user_s32(protocol
, vptr
+ 2 * n
)
1851 || get_user_ual(tab
, vptr
+ 3 * n
))
1852 return -TARGET_EFAULT
;
1854 ret
= do_socketpair(domain
, type
, protocol
, tab
);
1864 if (get_user_s32(sockfd
, vptr
)
1865 || get_user_ual(msg
, vptr
+ n
)
1866 || get_user_ual(len
, vptr
+ 2 * n
)
1867 || get_user_s32(flags
, vptr
+ 3 * n
))
1868 return -TARGET_EFAULT
;
1870 ret
= do_sendto(sockfd
, msg
, len
, flags
, 0, 0);
1880 if (get_user_s32(sockfd
, vptr
)
1881 || get_user_ual(msg
, vptr
+ n
)
1882 || get_user_ual(len
, vptr
+ 2 * n
)
1883 || get_user_s32(flags
, vptr
+ 3 * n
))
1884 return -TARGET_EFAULT
;
1886 ret
= do_recvfrom(sockfd
, msg
, len
, flags
, 0, 0);
1898 if (get_user_s32(sockfd
, vptr
)
1899 || get_user_ual(msg
, vptr
+ n
)
1900 || get_user_ual(len
, vptr
+ 2 * n
)
1901 || get_user_s32(flags
, vptr
+ 3 * n
)
1902 || get_user_ual(addr
, vptr
+ 4 * n
)
1903 || get_user_u32(addrlen
, vptr
+ 5 * n
))
1904 return -TARGET_EFAULT
;
1906 ret
= do_sendto(sockfd
, msg
, len
, flags
, addr
, addrlen
);
1909 case SOCKOP_recvfrom
:
1918 if (get_user_s32(sockfd
, vptr
)
1919 || get_user_ual(msg
, vptr
+ n
)
1920 || get_user_ual(len
, vptr
+ 2 * n
)
1921 || get_user_s32(flags
, vptr
+ 3 * n
)
1922 || get_user_ual(addr
, vptr
+ 4 * n
)
1923 || get_user_u32(addrlen
, vptr
+ 5 * n
))
1924 return -TARGET_EFAULT
;
1926 ret
= do_recvfrom(sockfd
, msg
, len
, flags
, addr
, addrlen
);
1929 case SOCKOP_shutdown
:
1933 if (get_user_s32(sockfd
, vptr
)
1934 || get_user_s32(how
, vptr
+ n
))
1935 return -TARGET_EFAULT
;
1937 ret
= get_errno(shutdown(sockfd
, how
));
1940 case SOCKOP_sendmsg
:
1941 case SOCKOP_recvmsg
:
1944 abi_ulong target_msg
;
1947 if (get_user_s32(fd
, vptr
)
1948 || get_user_ual(target_msg
, vptr
+ n
)
1949 || get_user_s32(flags
, vptr
+ 2 * n
))
1950 return -TARGET_EFAULT
;
1952 ret
= do_sendrecvmsg(fd
, target_msg
, flags
,
1953 (num
== SOCKOP_sendmsg
));
1956 case SOCKOP_setsockopt
:
1964 if (get_user_s32(sockfd
, vptr
)
1965 || get_user_s32(level
, vptr
+ n
)
1966 || get_user_s32(optname
, vptr
+ 2 * n
)
1967 || get_user_ual(optval
, vptr
+ 3 * n
)
1968 || get_user_u32(optlen
, vptr
+ 4 * n
))
1969 return -TARGET_EFAULT
;
1971 ret
= do_setsockopt(sockfd
, level
, optname
, optval
, optlen
);
1974 case SOCKOP_getsockopt
:
1982 if (get_user_s32(sockfd
, vptr
)
1983 || get_user_s32(level
, vptr
+ n
)
1984 || get_user_s32(optname
, vptr
+ 2 * n
)
1985 || get_user_ual(optval
, vptr
+ 3 * n
)
1986 || get_user_u32(optlen
, vptr
+ 4 * n
))
1987 return -TARGET_EFAULT
;
1989 ret
= do_getsockopt(sockfd
, level
, optname
, optval
, optlen
);
1993 gemu_log("Unsupported socketcall: %d\n", num
);
1994 ret
= -TARGET_ENOSYS
;
2001 #define N_SHM_REGIONS 32
2003 static struct shm_region
{
2006 } shm_regions
[N_SHM_REGIONS
];
2008 struct target_ipc_perm
2015 unsigned short int mode
;
2016 unsigned short int __pad1
;
2017 unsigned short int __seq
;
2018 unsigned short int __pad2
;
2019 abi_ulong __unused1
;
2020 abi_ulong __unused2
;
2023 struct target_semid_ds
2025 struct target_ipc_perm sem_perm
;
2026 abi_ulong sem_otime
;
2027 abi_ulong __unused1
;
2028 abi_ulong sem_ctime
;
2029 abi_ulong __unused2
;
2030 abi_ulong sem_nsems
;
2031 abi_ulong __unused3
;
2032 abi_ulong __unused4
;
2035 static inline abi_long
target_to_host_ipc_perm(struct ipc_perm
*host_ip
,
2036 abi_ulong target_addr
)
2038 struct target_ipc_perm
*target_ip
;
2039 struct target_semid_ds
*target_sd
;
2041 if (!lock_user_struct(VERIFY_READ
, target_sd
, target_addr
, 1))
2042 return -TARGET_EFAULT
;
2043 target_ip
=&(target_sd
->sem_perm
);
2044 host_ip
->__key
= tswapl(target_ip
->__key
);
2045 host_ip
->uid
= tswapl(target_ip
->uid
);
2046 host_ip
->gid
= tswapl(target_ip
->gid
);
2047 host_ip
->cuid
= tswapl(target_ip
->cuid
);
2048 host_ip
->cgid
= tswapl(target_ip
->cgid
);
2049 host_ip
->mode
= tswapl(target_ip
->mode
);
2050 unlock_user_struct(target_sd
, target_addr
, 0);
2054 static inline abi_long
host_to_target_ipc_perm(abi_ulong target_addr
,
2055 struct ipc_perm
*host_ip
)
2057 struct target_ipc_perm
*target_ip
;
2058 struct target_semid_ds
*target_sd
;
2060 if (!lock_user_struct(VERIFY_WRITE
, target_sd
, target_addr
, 0))
2061 return -TARGET_EFAULT
;
2062 target_ip
= &(target_sd
->sem_perm
);
2063 target_ip
->__key
= tswapl(host_ip
->__key
);
2064 target_ip
->uid
= tswapl(host_ip
->uid
);
2065 target_ip
->gid
= tswapl(host_ip
->gid
);
2066 target_ip
->cuid
= tswapl(host_ip
->cuid
);
2067 target_ip
->cgid
= tswapl(host_ip
->cgid
);
2068 target_ip
->mode
= tswapl(host_ip
->mode
);
2069 unlock_user_struct(target_sd
, target_addr
, 1);
2073 static inline abi_long
target_to_host_semid_ds(struct semid_ds
*host_sd
,
2074 abi_ulong target_addr
)
2076 struct target_semid_ds
*target_sd
;
2078 if (!lock_user_struct(VERIFY_READ
, target_sd
, target_addr
, 1))
2079 return -TARGET_EFAULT
;
2080 if (target_to_host_ipc_perm(&(host_sd
->sem_perm
),target_addr
))
2081 return -TARGET_EFAULT
;
2082 host_sd
->sem_nsems
= tswapl(target_sd
->sem_nsems
);
2083 host_sd
->sem_otime
= tswapl(target_sd
->sem_otime
);
2084 host_sd
->sem_ctime
= tswapl(target_sd
->sem_ctime
);
2085 unlock_user_struct(target_sd
, target_addr
, 0);
2089 static inline abi_long
host_to_target_semid_ds(abi_ulong target_addr
,
2090 struct semid_ds
*host_sd
)
2092 struct target_semid_ds
*target_sd
;
2094 if (!lock_user_struct(VERIFY_WRITE
, target_sd
, target_addr
, 0))
2095 return -TARGET_EFAULT
;
2096 if (host_to_target_ipc_perm(target_addr
,&(host_sd
->sem_perm
)))
2097 return -TARGET_EFAULT
;;
2098 target_sd
->sem_nsems
= tswapl(host_sd
->sem_nsems
);
2099 target_sd
->sem_otime
= tswapl(host_sd
->sem_otime
);
2100 target_sd
->sem_ctime
= tswapl(host_sd
->sem_ctime
);
2101 unlock_user_struct(target_sd
, target_addr
, 1);
2105 struct target_seminfo
{
2118 static inline abi_long
host_to_target_seminfo(abi_ulong target_addr
,
2119 struct seminfo
*host_seminfo
)
2121 struct target_seminfo
*target_seminfo
;
2122 if (!lock_user_struct(VERIFY_WRITE
, target_seminfo
, target_addr
, 0))
2123 return -TARGET_EFAULT
;
2124 __put_user(host_seminfo
->semmap
, &target_seminfo
->semmap
);
2125 __put_user(host_seminfo
->semmni
, &target_seminfo
->semmni
);
2126 __put_user(host_seminfo
->semmns
, &target_seminfo
->semmns
);
2127 __put_user(host_seminfo
->semmnu
, &target_seminfo
->semmnu
);
2128 __put_user(host_seminfo
->semmsl
, &target_seminfo
->semmsl
);
2129 __put_user(host_seminfo
->semopm
, &target_seminfo
->semopm
);
2130 __put_user(host_seminfo
->semume
, &target_seminfo
->semume
);
2131 __put_user(host_seminfo
->semusz
, &target_seminfo
->semusz
);
2132 __put_user(host_seminfo
->semvmx
, &target_seminfo
->semvmx
);
2133 __put_user(host_seminfo
->semaem
, &target_seminfo
->semaem
);
2134 unlock_user_struct(target_seminfo
, target_addr
, 1);
2140 struct semid_ds
*buf
;
2141 unsigned short *array
;
2142 struct seminfo
*__buf
;
2145 union target_semun
{
2152 static inline abi_long
target_to_host_semarray(int semid
, unsigned short **host_array
,
2153 abi_ulong target_addr
)
2156 unsigned short *array
;
2158 struct semid_ds semid_ds
;
2161 semun
.buf
= &semid_ds
;
2163 ret
= semctl(semid
, 0, IPC_STAT
, semun
);
2165 return get_errno(ret
);
2167 nsems
= semid_ds
.sem_nsems
;
2169 *host_array
= malloc(nsems
*sizeof(unsigned short));
2170 array
= lock_user(VERIFY_READ
, target_addr
,
2171 nsems
*sizeof(unsigned short), 1);
2173 return -TARGET_EFAULT
;
2175 for(i
=0; i
<nsems
; i
++) {
2176 __get_user((*host_array
)[i
], &array
[i
]);
2178 unlock_user(array
, target_addr
, 0);
2183 static inline abi_long
host_to_target_semarray(int semid
, abi_ulong target_addr
,
2184 unsigned short **host_array
)
2187 unsigned short *array
;
2189 struct semid_ds semid_ds
;
2192 semun
.buf
= &semid_ds
;
2194 ret
= semctl(semid
, 0, IPC_STAT
, semun
);
2196 return get_errno(ret
);
2198 nsems
= semid_ds
.sem_nsems
;
2200 array
= lock_user(VERIFY_WRITE
, target_addr
,
2201 nsems
*sizeof(unsigned short), 0);
2203 return -TARGET_EFAULT
;
2205 for(i
=0; i
<nsems
; i
++) {
2206 __put_user((*host_array
)[i
], &array
[i
]);
2209 unlock_user(array
, target_addr
, 1);
2214 static inline abi_long
do_semctl(int semid
, int semnum
, int cmd
,
2215 union target_semun target_su
)
2218 struct semid_ds dsarg
;
2219 unsigned short *array
;
2220 struct seminfo seminfo
;
2221 abi_long ret
= -TARGET_EINVAL
;
2228 arg
.val
= tswapl(target_su
.val
);
2229 ret
= get_errno(semctl(semid
, semnum
, cmd
, arg
));
2230 target_su
.val
= tswapl(arg
.val
);
2234 err
= target_to_host_semarray(semid
, &array
, target_su
.array
);
2238 ret
= get_errno(semctl(semid
, semnum
, cmd
, arg
));
2239 err
= host_to_target_semarray(semid
, target_su
.array
, &array
);
2246 err
= target_to_host_semid_ds(&dsarg
, target_su
.buf
);
2250 ret
= get_errno(semctl(semid
, semnum
, cmd
, arg
));
2251 err
= host_to_target_semid_ds(target_su
.buf
, &dsarg
);
2257 arg
.__buf
= &seminfo
;
2258 ret
= get_errno(semctl(semid
, semnum
, cmd
, arg
));
2259 err
= host_to_target_seminfo(target_su
.__buf
, &seminfo
);
2267 ret
= get_errno(semctl(semid
, semnum
, cmd
, NULL
));
2274 struct target_sembuf
{
2275 unsigned short sem_num
;
2280 static inline abi_long
target_to_host_sembuf(struct sembuf
*host_sembuf
,
2281 abi_ulong target_addr
,
2284 struct target_sembuf
*target_sembuf
;
2287 target_sembuf
= lock_user(VERIFY_READ
, target_addr
,
2288 nsops
*sizeof(struct target_sembuf
), 1);
2290 return -TARGET_EFAULT
;
2292 for(i
=0; i
<nsops
; i
++) {
2293 __get_user(host_sembuf
[i
].sem_num
, &target_sembuf
[i
].sem_num
);
2294 __get_user(host_sembuf
[i
].sem_op
, &target_sembuf
[i
].sem_op
);
2295 __get_user(host_sembuf
[i
].sem_flg
, &target_sembuf
[i
].sem_flg
);
2298 unlock_user(target_sembuf
, target_addr
, 0);
2303 static inline abi_long
do_semop(int semid
, abi_long ptr
, unsigned nsops
)
2305 struct sembuf sops
[nsops
];
2307 if (target_to_host_sembuf(sops
, ptr
, nsops
))
2308 return -TARGET_EFAULT
;
2310 return semop(semid
, sops
, nsops
);
2313 struct target_msqid_ds
2315 struct target_ipc_perm msg_perm
;
2316 abi_ulong msg_stime
;
2317 #if TARGET_ABI_BITS == 32
2318 abi_ulong __unused1
;
2320 abi_ulong msg_rtime
;
2321 #if TARGET_ABI_BITS == 32
2322 abi_ulong __unused2
;
2324 abi_ulong msg_ctime
;
2325 #if TARGET_ABI_BITS == 32
2326 abi_ulong __unused3
;
2328 abi_ulong __msg_cbytes
;
2330 abi_ulong msg_qbytes
;
2331 abi_ulong msg_lspid
;
2332 abi_ulong msg_lrpid
;
2333 abi_ulong __unused4
;
2334 abi_ulong __unused5
;
2337 static inline abi_long
target_to_host_msqid_ds(struct msqid_ds
*host_md
,
2338 abi_ulong target_addr
)
2340 struct target_msqid_ds
*target_md
;
2342 if (!lock_user_struct(VERIFY_READ
, target_md
, target_addr
, 1))
2343 return -TARGET_EFAULT
;
2344 if (target_to_host_ipc_perm(&(host_md
->msg_perm
),target_addr
))
2345 return -TARGET_EFAULT
;
2346 host_md
->msg_stime
= tswapl(target_md
->msg_stime
);
2347 host_md
->msg_rtime
= tswapl(target_md
->msg_rtime
);
2348 host_md
->msg_ctime
= tswapl(target_md
->msg_ctime
);
2349 host_md
->__msg_cbytes
= tswapl(target_md
->__msg_cbytes
);
2350 host_md
->msg_qnum
= tswapl(target_md
->msg_qnum
);
2351 host_md
->msg_qbytes
= tswapl(target_md
->msg_qbytes
);
2352 host_md
->msg_lspid
= tswapl(target_md
->msg_lspid
);
2353 host_md
->msg_lrpid
= tswapl(target_md
->msg_lrpid
);
2354 unlock_user_struct(target_md
, target_addr
, 0);
2358 static inline abi_long
host_to_target_msqid_ds(abi_ulong target_addr
,
2359 struct msqid_ds
*host_md
)
2361 struct target_msqid_ds
*target_md
;
2363 if (!lock_user_struct(VERIFY_WRITE
, target_md
, target_addr
, 0))
2364 return -TARGET_EFAULT
;
2365 if (host_to_target_ipc_perm(target_addr
,&(host_md
->msg_perm
)))
2366 return -TARGET_EFAULT
;
2367 target_md
->msg_stime
= tswapl(host_md
->msg_stime
);
2368 target_md
->msg_rtime
= tswapl(host_md
->msg_rtime
);
2369 target_md
->msg_ctime
= tswapl(host_md
->msg_ctime
);
2370 target_md
->__msg_cbytes
= tswapl(host_md
->__msg_cbytes
);
2371 target_md
->msg_qnum
= tswapl(host_md
->msg_qnum
);
2372 target_md
->msg_qbytes
= tswapl(host_md
->msg_qbytes
);
2373 target_md
->msg_lspid
= tswapl(host_md
->msg_lspid
);
2374 target_md
->msg_lrpid
= tswapl(host_md
->msg_lrpid
);
2375 unlock_user_struct(target_md
, target_addr
, 1);
2379 struct target_msginfo
{
2387 unsigned short int msgseg
;
2390 static inline abi_long
host_to_target_msginfo(abi_ulong target_addr
,
2391 struct msginfo
*host_msginfo
)
2393 struct target_msginfo
*target_msginfo
;
2394 if (!lock_user_struct(VERIFY_WRITE
, target_msginfo
, target_addr
, 0))
2395 return -TARGET_EFAULT
;
2396 __put_user(host_msginfo
->msgpool
, &target_msginfo
->msgpool
);
2397 __put_user(host_msginfo
->msgmap
, &target_msginfo
->msgmap
);
2398 __put_user(host_msginfo
->msgmax
, &target_msginfo
->msgmax
);
2399 __put_user(host_msginfo
->msgmnb
, &target_msginfo
->msgmnb
);
2400 __put_user(host_msginfo
->msgmni
, &target_msginfo
->msgmni
);
2401 __put_user(host_msginfo
->msgssz
, &target_msginfo
->msgssz
);
2402 __put_user(host_msginfo
->msgtql
, &target_msginfo
->msgtql
);
2403 __put_user(host_msginfo
->msgseg
, &target_msginfo
->msgseg
);
2404 unlock_user_struct(target_msginfo
, target_addr
, 1);
2408 static inline abi_long
do_msgctl(int msgid
, int cmd
, abi_long ptr
)
2410 struct msqid_ds dsarg
;
2411 struct msginfo msginfo
;
2412 abi_long ret
= -TARGET_EINVAL
;
2420 if (target_to_host_msqid_ds(&dsarg
,ptr
))
2421 return -TARGET_EFAULT
;
2422 ret
= get_errno(msgctl(msgid
, cmd
, &dsarg
));
2423 if (host_to_target_msqid_ds(ptr
,&dsarg
))
2424 return -TARGET_EFAULT
;
2427 ret
= get_errno(msgctl(msgid
, cmd
, NULL
));
2431 ret
= get_errno(msgctl(msgid
, cmd
, (struct msqid_ds
*)&msginfo
));
2432 if (host_to_target_msginfo(ptr
, &msginfo
))
2433 return -TARGET_EFAULT
;
2440 struct target_msgbuf
{
2445 static inline abi_long
do_msgsnd(int msqid
, abi_long msgp
,
2446 unsigned int msgsz
, int msgflg
)
2448 struct target_msgbuf
*target_mb
;
2449 struct msgbuf
*host_mb
;
2452 if (!lock_user_struct(VERIFY_READ
, target_mb
, msgp
, 0))
2453 return -TARGET_EFAULT
;
2454 host_mb
= malloc(msgsz
+sizeof(long));
2455 host_mb
->mtype
= (abi_long
) tswapl(target_mb
->mtype
);
2456 memcpy(host_mb
->mtext
, target_mb
->mtext
, msgsz
);
2457 ret
= get_errno(msgsnd(msqid
, host_mb
, msgsz
, msgflg
));
2459 unlock_user_struct(target_mb
, msgp
, 0);
2464 static inline abi_long
do_msgrcv(int msqid
, abi_long msgp
,
2465 unsigned int msgsz
, abi_long msgtyp
,
2468 struct target_msgbuf
*target_mb
;
2470 struct msgbuf
*host_mb
;
2473 if (!lock_user_struct(VERIFY_WRITE
, target_mb
, msgp
, 0))
2474 return -TARGET_EFAULT
;
2476 host_mb
= malloc(msgsz
+sizeof(long));
2477 ret
= get_errno(msgrcv(msqid
, host_mb
, msgsz
, tswapl(msgtyp
), msgflg
));
2480 abi_ulong target_mtext_addr
= msgp
+ sizeof(abi_ulong
);
2481 target_mtext
= lock_user(VERIFY_WRITE
, target_mtext_addr
, ret
, 0);
2482 if (!target_mtext
) {
2483 ret
= -TARGET_EFAULT
;
2486 memcpy(target_mb
->mtext
, host_mb
->mtext
, ret
);
2487 unlock_user(target_mtext
, target_mtext_addr
, ret
);
2490 target_mb
->mtype
= tswapl(host_mb
->mtype
);
2495 unlock_user_struct(target_mb
, msgp
, 1);
2499 struct target_shmid_ds
2501 struct target_ipc_perm shm_perm
;
2502 abi_ulong shm_segsz
;
2503 abi_ulong shm_atime
;
2504 #if TARGET_ABI_BITS == 32
2505 abi_ulong __unused1
;
2507 abi_ulong shm_dtime
;
2508 #if TARGET_ABI_BITS == 32
2509 abi_ulong __unused2
;
2511 abi_ulong shm_ctime
;
2512 #if TARGET_ABI_BITS == 32
2513 abi_ulong __unused3
;
2517 abi_ulong shm_nattch
;
2518 unsigned long int __unused4
;
2519 unsigned long int __unused5
;
2522 static inline abi_long
target_to_host_shmid_ds(struct shmid_ds
*host_sd
,
2523 abi_ulong target_addr
)
2525 struct target_shmid_ds
*target_sd
;
2527 if (!lock_user_struct(VERIFY_READ
, target_sd
, target_addr
, 1))
2528 return -TARGET_EFAULT
;
2529 if (target_to_host_ipc_perm(&(host_sd
->shm_perm
), target_addr
))
2530 return -TARGET_EFAULT
;
2531 __get_user(host_sd
->shm_segsz
, &target_sd
->shm_segsz
);
2532 __get_user(host_sd
->shm_atime
, &target_sd
->shm_atime
);
2533 __get_user(host_sd
->shm_dtime
, &target_sd
->shm_dtime
);
2534 __get_user(host_sd
->shm_ctime
, &target_sd
->shm_ctime
);
2535 __get_user(host_sd
->shm_cpid
, &target_sd
->shm_cpid
);
2536 __get_user(host_sd
->shm_lpid
, &target_sd
->shm_lpid
);
2537 __get_user(host_sd
->shm_nattch
, &target_sd
->shm_nattch
);
2538 unlock_user_struct(target_sd
, target_addr
, 0);
2542 static inline abi_long
host_to_target_shmid_ds(abi_ulong target_addr
,
2543 struct shmid_ds
*host_sd
)
2545 struct target_shmid_ds
*target_sd
;
2547 if (!lock_user_struct(VERIFY_WRITE
, target_sd
, target_addr
, 0))
2548 return -TARGET_EFAULT
;
2549 if (host_to_target_ipc_perm(target_addr
, &(host_sd
->shm_perm
)))
2550 return -TARGET_EFAULT
;
2551 __put_user(host_sd
->shm_segsz
, &target_sd
->shm_segsz
);
2552 __put_user(host_sd
->shm_atime
, &target_sd
->shm_atime
);
2553 __put_user(host_sd
->shm_dtime
, &target_sd
->shm_dtime
);
2554 __put_user(host_sd
->shm_ctime
, &target_sd
->shm_ctime
);
2555 __put_user(host_sd
->shm_cpid
, &target_sd
->shm_cpid
);
2556 __put_user(host_sd
->shm_lpid
, &target_sd
->shm_lpid
);
2557 __put_user(host_sd
->shm_nattch
, &target_sd
->shm_nattch
);
2558 unlock_user_struct(target_sd
, target_addr
, 1);
2562 struct target_shminfo
{
2570 static inline abi_long
host_to_target_shminfo(abi_ulong target_addr
,
2571 struct shminfo
*host_shminfo
)
2573 struct target_shminfo
*target_shminfo
;
2574 if (!lock_user_struct(VERIFY_WRITE
, target_shminfo
, target_addr
, 0))
2575 return -TARGET_EFAULT
;
2576 __put_user(host_shminfo
->shmmax
, &target_shminfo
->shmmax
);
2577 __put_user(host_shminfo
->shmmin
, &target_shminfo
->shmmin
);
2578 __put_user(host_shminfo
->shmmni
, &target_shminfo
->shmmni
);
2579 __put_user(host_shminfo
->shmseg
, &target_shminfo
->shmseg
);
2580 __put_user(host_shminfo
->shmall
, &target_shminfo
->shmall
);
2581 unlock_user_struct(target_shminfo
, target_addr
, 1);
2585 struct target_shm_info
{
2590 abi_ulong swap_attempts
;
2591 abi_ulong swap_successes
;
2594 static inline abi_long
host_to_target_shm_info(abi_ulong target_addr
,
2595 struct shm_info
*host_shm_info
)
2597 struct target_shm_info
*target_shm_info
;
2598 if (!lock_user_struct(VERIFY_WRITE
, target_shm_info
, target_addr
, 0))
2599 return -TARGET_EFAULT
;
2600 __put_user(host_shm_info
->used_ids
, &target_shm_info
->used_ids
);
2601 __put_user(host_shm_info
->shm_tot
, &target_shm_info
->shm_tot
);
2602 __put_user(host_shm_info
->shm_rss
, &target_shm_info
->shm_rss
);
2603 __put_user(host_shm_info
->shm_swp
, &target_shm_info
->shm_swp
);
2604 __put_user(host_shm_info
->swap_attempts
, &target_shm_info
->swap_attempts
);
2605 __put_user(host_shm_info
->swap_successes
, &target_shm_info
->swap_successes
);
2606 unlock_user_struct(target_shm_info
, target_addr
, 1);
2610 static inline abi_long
do_shmctl(int shmid
, int cmd
, abi_long buf
)
2612 struct shmid_ds dsarg
;
2613 struct shminfo shminfo
;
2614 struct shm_info shm_info
;
2615 abi_long ret
= -TARGET_EINVAL
;
2623 if (target_to_host_shmid_ds(&dsarg
, buf
))
2624 return -TARGET_EFAULT
;
2625 ret
= get_errno(shmctl(shmid
, cmd
, &dsarg
));
2626 if (host_to_target_shmid_ds(buf
, &dsarg
))
2627 return -TARGET_EFAULT
;
2630 ret
= get_errno(shmctl(shmid
, cmd
, (struct shmid_ds
*)&shminfo
));
2631 if (host_to_target_shminfo(buf
, &shminfo
))
2632 return -TARGET_EFAULT
;
2635 ret
= get_errno(shmctl(shmid
, cmd
, (struct shmid_ds
*)&shm_info
));
2636 if (host_to_target_shm_info(buf
, &shm_info
))
2637 return -TARGET_EFAULT
;
2642 ret
= get_errno(shmctl(shmid
, cmd
, NULL
));
2649 static inline abi_ulong
do_shmat(int shmid
, abi_ulong shmaddr
, int shmflg
)
2653 struct shmid_ds shm_info
;
2656 /* find out the length of the shared memory segment */
2657 ret
= get_errno(shmctl(shmid
, IPC_STAT
, &shm_info
));
2658 if (is_error(ret
)) {
2659 /* can't get length, bail out */
2666 host_raddr
= shmat(shmid
, (void *)g2h(shmaddr
), shmflg
);
2668 abi_ulong mmap_start
;
2670 mmap_start
= mmap_find_vma(0, shm_info
.shm_segsz
);
2672 if (mmap_start
== -1) {
2674 host_raddr
= (void *)-1;
2676 host_raddr
= shmat(shmid
, g2h(mmap_start
), shmflg
| SHM_REMAP
);
2679 if (host_raddr
== (void *)-1) {
2681 return get_errno((long)host_raddr
);
2683 raddr
=h2g((unsigned long)host_raddr
);
2685 page_set_flags(raddr
, raddr
+ shm_info
.shm_segsz
,
2686 PAGE_VALID
| PAGE_READ
|
2687 ((shmflg
& SHM_RDONLY
)? 0 : PAGE_WRITE
));
2689 for (i
= 0; i
< N_SHM_REGIONS
; i
++) {
2690 if (shm_regions
[i
].start
== 0) {
2691 shm_regions
[i
].start
= raddr
;
2692 shm_regions
[i
].size
= shm_info
.shm_segsz
;
2702 static inline abi_long
do_shmdt(abi_ulong shmaddr
)
2706 for (i
= 0; i
< N_SHM_REGIONS
; ++i
) {
2707 if (shm_regions
[i
].start
== shmaddr
) {
2708 shm_regions
[i
].start
= 0;
2709 page_set_flags(shmaddr
, shm_regions
[i
].size
, 0);
2714 return get_errno(shmdt(g2h(shmaddr
)));
2717 #ifdef TARGET_NR_ipc
2718 /* ??? This only works with linear mappings. */
2719 /* do_ipc() must return target values and target errnos. */
2720 static abi_long
do_ipc(unsigned int call
, int first
,
2721 int second
, int third
,
2722 abi_long ptr
, abi_long fifth
)
2727 version
= call
>> 16;
2732 ret
= do_semop(first
, ptr
, second
);
2736 ret
= get_errno(semget(first
, second
, third
));
2740 ret
= do_semctl(first
, second
, third
, (union target_semun
)(abi_ulong
) ptr
);
2744 ret
= get_errno(msgget(first
, second
));
2748 ret
= do_msgsnd(first
, ptr
, second
, third
);
2752 ret
= do_msgctl(first
, second
, ptr
);
2759 struct target_ipc_kludge
{
2764 if (!lock_user_struct(VERIFY_READ
, tmp
, ptr
, 1)) {
2765 ret
= -TARGET_EFAULT
;
2769 ret
= do_msgrcv(first
, tmp
->msgp
, second
, tmp
->msgtyp
, third
);
2771 unlock_user_struct(tmp
, ptr
, 0);
2775 ret
= do_msgrcv(first
, ptr
, second
, fifth
, third
);
2784 raddr
= do_shmat(first
, ptr
, second
);
2785 if (is_error(raddr
))
2786 return get_errno(raddr
);
2787 if (put_user_ual(raddr
, third
))
2788 return -TARGET_EFAULT
;
2792 ret
= -TARGET_EINVAL
;
2797 ret
= do_shmdt(ptr
);
2801 /* IPC_* flag values are the same on all linux platforms */
2802 ret
= get_errno(shmget(first
, second
, third
));
2805 /* IPC_* and SHM_* command values are the same on all linux platforms */
2807 ret
= do_shmctl(first
, second
, third
);
2810 gemu_log("Unsupported ipc call: %d (version %d)\n", call
, version
);
2811 ret
= -TARGET_ENOSYS
;
2818 /* kernel structure types definitions */
2821 #define STRUCT(name, ...) STRUCT_ ## name,
2822 #define STRUCT_SPECIAL(name) STRUCT_ ## name,
2824 #include "syscall_types.h"
2827 #undef STRUCT_SPECIAL
2829 #define STRUCT(name, ...) static const argtype struct_ ## name ## _def[] = { __VA_ARGS__, TYPE_NULL };
2830 #define STRUCT_SPECIAL(name)
2831 #include "syscall_types.h"
2833 #undef STRUCT_SPECIAL
2835 typedef struct IOCTLEntry
{
2836 unsigned int target_cmd
;
2837 unsigned int host_cmd
;
2840 const argtype arg_type
[5];
2843 #define IOC_R 0x0001
2844 #define IOC_W 0x0002
2845 #define IOC_RW (IOC_R | IOC_W)
2847 #define MAX_STRUCT_SIZE 4096
2849 static IOCTLEntry ioctl_entries
[] = {
2850 #define IOCTL(cmd, access, ...) \
2851 { TARGET_ ## cmd, cmd, #cmd, access, { __VA_ARGS__ } },
2856 /* ??? Implement proper locking for ioctls. */
2857 /* do_ioctl() Must return target values and target errnos. */
2858 static abi_long
do_ioctl(int fd
, abi_long cmd
, abi_long arg
)
2860 const IOCTLEntry
*ie
;
2861 const argtype
*arg_type
;
2863 uint8_t buf_temp
[MAX_STRUCT_SIZE
];
2869 if (ie
->target_cmd
== 0) {
2870 gemu_log("Unsupported ioctl: cmd=0x%04lx\n", (long)cmd
);
2871 return -TARGET_ENOSYS
;
2873 if (ie
->target_cmd
== cmd
)
2877 arg_type
= ie
->arg_type
;
2879 gemu_log("ioctl: cmd=0x%04lx (%s)\n", (long)cmd
, ie
->name
);
2881 switch(arg_type
[0]) {
2884 ret
= get_errno(ioctl(fd
, ie
->host_cmd
));
2889 ret
= get_errno(ioctl(fd
, ie
->host_cmd
, arg
));
2893 target_size
= thunk_type_size(arg_type
, 0);
2894 switch(ie
->access
) {
2896 ret
= get_errno(ioctl(fd
, ie
->host_cmd
, buf_temp
));
2897 if (!is_error(ret
)) {
2898 argptr
= lock_user(VERIFY_WRITE
, arg
, target_size
, 0);
2900 return -TARGET_EFAULT
;
2901 thunk_convert(argptr
, buf_temp
, arg_type
, THUNK_TARGET
);
2902 unlock_user(argptr
, arg
, target_size
);
2906 argptr
= lock_user(VERIFY_READ
, arg
, target_size
, 1);
2908 return -TARGET_EFAULT
;
2909 thunk_convert(buf_temp
, argptr
, arg_type
, THUNK_HOST
);
2910 unlock_user(argptr
, arg
, 0);
2911 ret
= get_errno(ioctl(fd
, ie
->host_cmd
, buf_temp
));
2915 argptr
= lock_user(VERIFY_READ
, arg
, target_size
, 1);
2917 return -TARGET_EFAULT
;
2918 thunk_convert(buf_temp
, argptr
, arg_type
, THUNK_HOST
);
2919 unlock_user(argptr
, arg
, 0);
2920 ret
= get_errno(ioctl(fd
, ie
->host_cmd
, buf_temp
));
2921 if (!is_error(ret
)) {
2922 argptr
= lock_user(VERIFY_WRITE
, arg
, target_size
, 0);
2924 return -TARGET_EFAULT
;
2925 thunk_convert(argptr
, buf_temp
, arg_type
, THUNK_TARGET
);
2926 unlock_user(argptr
, arg
, target_size
);
2932 gemu_log("Unsupported ioctl type: cmd=0x%04lx type=%d\n",
2933 (long)cmd
, arg_type
[0]);
2934 ret
= -TARGET_ENOSYS
;
2940 static const bitmask_transtbl iflag_tbl
[] = {
2941 { TARGET_IGNBRK
, TARGET_IGNBRK
, IGNBRK
, IGNBRK
},
2942 { TARGET_BRKINT
, TARGET_BRKINT
, BRKINT
, BRKINT
},
2943 { TARGET_IGNPAR
, TARGET_IGNPAR
, IGNPAR
, IGNPAR
},
2944 { TARGET_PARMRK
, TARGET_PARMRK
, PARMRK
, PARMRK
},
2945 { TARGET_INPCK
, TARGET_INPCK
, INPCK
, INPCK
},
2946 { TARGET_ISTRIP
, TARGET_ISTRIP
, ISTRIP
, ISTRIP
},
2947 { TARGET_INLCR
, TARGET_INLCR
, INLCR
, INLCR
},
2948 { TARGET_IGNCR
, TARGET_IGNCR
, IGNCR
, IGNCR
},
2949 { TARGET_ICRNL
, TARGET_ICRNL
, ICRNL
, ICRNL
},
2950 { TARGET_IUCLC
, TARGET_IUCLC
, IUCLC
, IUCLC
},
2951 { TARGET_IXON
, TARGET_IXON
, IXON
, IXON
},
2952 { TARGET_IXANY
, TARGET_IXANY
, IXANY
, IXANY
},
2953 { TARGET_IXOFF
, TARGET_IXOFF
, IXOFF
, IXOFF
},
2954 { TARGET_IMAXBEL
, TARGET_IMAXBEL
, IMAXBEL
, IMAXBEL
},
2958 static const bitmask_transtbl oflag_tbl
[] = {
2959 { TARGET_OPOST
, TARGET_OPOST
, OPOST
, OPOST
},
2960 { TARGET_OLCUC
, TARGET_OLCUC
, OLCUC
, OLCUC
},
2961 { TARGET_ONLCR
, TARGET_ONLCR
, ONLCR
, ONLCR
},
2962 { TARGET_OCRNL
, TARGET_OCRNL
, OCRNL
, OCRNL
},
2963 { TARGET_ONOCR
, TARGET_ONOCR
, ONOCR
, ONOCR
},
2964 { TARGET_ONLRET
, TARGET_ONLRET
, ONLRET
, ONLRET
},
2965 { TARGET_OFILL
, TARGET_OFILL
, OFILL
, OFILL
},
2966 { TARGET_OFDEL
, TARGET_OFDEL
, OFDEL
, OFDEL
},
2967 { TARGET_NLDLY
, TARGET_NL0
, NLDLY
, NL0
},
2968 { TARGET_NLDLY
, TARGET_NL1
, NLDLY
, NL1
},
2969 { TARGET_CRDLY
, TARGET_CR0
, CRDLY
, CR0
},
2970 { TARGET_CRDLY
, TARGET_CR1
, CRDLY
, CR1
},
2971 { TARGET_CRDLY
, TARGET_CR2
, CRDLY
, CR2
},
2972 { TARGET_CRDLY
, TARGET_CR3
, CRDLY
, CR3
},
2973 { TARGET_TABDLY
, TARGET_TAB0
, TABDLY
, TAB0
},
2974 { TARGET_TABDLY
, TARGET_TAB1
, TABDLY
, TAB1
},
2975 { TARGET_TABDLY
, TARGET_TAB2
, TABDLY
, TAB2
},
2976 { TARGET_TABDLY
, TARGET_TAB3
, TABDLY
, TAB3
},
2977 { TARGET_BSDLY
, TARGET_BS0
, BSDLY
, BS0
},
2978 { TARGET_BSDLY
, TARGET_BS1
, BSDLY
, BS1
},
2979 { TARGET_VTDLY
, TARGET_VT0
, VTDLY
, VT0
},
2980 { TARGET_VTDLY
, TARGET_VT1
, VTDLY
, VT1
},
2981 { TARGET_FFDLY
, TARGET_FF0
, FFDLY
, FF0
},
2982 { TARGET_FFDLY
, TARGET_FF1
, FFDLY
, FF1
},
2986 static const bitmask_transtbl cflag_tbl
[] = {
2987 { TARGET_CBAUD
, TARGET_B0
, CBAUD
, B0
},
2988 { TARGET_CBAUD
, TARGET_B50
, CBAUD
, B50
},
2989 { TARGET_CBAUD
, TARGET_B75
, CBAUD
, B75
},
2990 { TARGET_CBAUD
, TARGET_B110
, CBAUD
, B110
},
2991 { TARGET_CBAUD
, TARGET_B134
, CBAUD
, B134
},
2992 { TARGET_CBAUD
, TARGET_B150
, CBAUD
, B150
},
2993 { TARGET_CBAUD
, TARGET_B200
, CBAUD
, B200
},
2994 { TARGET_CBAUD
, TARGET_B300
, CBAUD
, B300
},
2995 { TARGET_CBAUD
, TARGET_B600
, CBAUD
, B600
},
2996 { TARGET_CBAUD
, TARGET_B1200
, CBAUD
, B1200
},
2997 { TARGET_CBAUD
, TARGET_B1800
, CBAUD
, B1800
},
2998 { TARGET_CBAUD
, TARGET_B2400
, CBAUD
, B2400
},
2999 { TARGET_CBAUD
, TARGET_B4800
, CBAUD
, B4800
},
3000 { TARGET_CBAUD
, TARGET_B9600
, CBAUD
, B9600
},
3001 { TARGET_CBAUD
, TARGET_B19200
, CBAUD
, B19200
},
3002 { TARGET_CBAUD
, TARGET_B38400
, CBAUD
, B38400
},
3003 { TARGET_CBAUD
, TARGET_B57600
, CBAUD
, B57600
},
3004 { TARGET_CBAUD
, TARGET_B115200
, CBAUD
, B115200
},
3005 { TARGET_CBAUD
, TARGET_B230400
, CBAUD
, B230400
},
3006 { TARGET_CBAUD
, TARGET_B460800
, CBAUD
, B460800
},
3007 { TARGET_CSIZE
, TARGET_CS5
, CSIZE
, CS5
},
3008 { TARGET_CSIZE
, TARGET_CS6
, CSIZE
, CS6
},
3009 { TARGET_CSIZE
, TARGET_CS7
, CSIZE
, CS7
},
3010 { TARGET_CSIZE
, TARGET_CS8
, CSIZE
, CS8
},
3011 { TARGET_CSTOPB
, TARGET_CSTOPB
, CSTOPB
, CSTOPB
},
3012 { TARGET_CREAD
, TARGET_CREAD
, CREAD
, CREAD
},
3013 { TARGET_PARENB
, TARGET_PARENB
, PARENB
, PARENB
},
3014 { TARGET_PARODD
, TARGET_PARODD
, PARODD
, PARODD
},
3015 { TARGET_HUPCL
, TARGET_HUPCL
, HUPCL
, HUPCL
},
3016 { TARGET_CLOCAL
, TARGET_CLOCAL
, CLOCAL
, CLOCAL
},
3017 { TARGET_CRTSCTS
, TARGET_CRTSCTS
, CRTSCTS
, CRTSCTS
},
3021 static const bitmask_transtbl lflag_tbl
[] = {
3022 { TARGET_ISIG
, TARGET_ISIG
, ISIG
, ISIG
},
3023 { TARGET_ICANON
, TARGET_ICANON
, ICANON
, ICANON
},
3024 { TARGET_XCASE
, TARGET_XCASE
, XCASE
, XCASE
},
3025 { TARGET_ECHO
, TARGET_ECHO
, ECHO
, ECHO
},
3026 { TARGET_ECHOE
, TARGET_ECHOE
, ECHOE
, ECHOE
},
3027 { TARGET_ECHOK
, TARGET_ECHOK
, ECHOK
, ECHOK
},
3028 { TARGET_ECHONL
, TARGET_ECHONL
, ECHONL
, ECHONL
},
3029 { TARGET_NOFLSH
, TARGET_NOFLSH
, NOFLSH
, NOFLSH
},
3030 { TARGET_TOSTOP
, TARGET_TOSTOP
, TOSTOP
, TOSTOP
},
3031 { TARGET_ECHOCTL
, TARGET_ECHOCTL
, ECHOCTL
, ECHOCTL
},
3032 { TARGET_ECHOPRT
, TARGET_ECHOPRT
, ECHOPRT
, ECHOPRT
},
3033 { TARGET_ECHOKE
, TARGET_ECHOKE
, ECHOKE
, ECHOKE
},
3034 { TARGET_FLUSHO
, TARGET_FLUSHO
, FLUSHO
, FLUSHO
},
3035 { TARGET_PENDIN
, TARGET_PENDIN
, PENDIN
, PENDIN
},
3036 { TARGET_IEXTEN
, TARGET_IEXTEN
, IEXTEN
, IEXTEN
},
3040 static void target_to_host_termios (void *dst
, const void *src
)
3042 struct host_termios
*host
= dst
;
3043 const struct target_termios
*target
= src
;
3046 target_to_host_bitmask(tswap32(target
->c_iflag
), iflag_tbl
);
3048 target_to_host_bitmask(tswap32(target
->c_oflag
), oflag_tbl
);
3050 target_to_host_bitmask(tswap32(target
->c_cflag
), cflag_tbl
);
3052 target_to_host_bitmask(tswap32(target
->c_lflag
), lflag_tbl
);
3053 host
->c_line
= target
->c_line
;
3055 memset(host
->c_cc
, 0, sizeof(host
->c_cc
));
3056 host
->c_cc
[VINTR
] = target
->c_cc
[TARGET_VINTR
];
3057 host
->c_cc
[VQUIT
] = target
->c_cc
[TARGET_VQUIT
];
3058 host
->c_cc
[VERASE
] = target
->c_cc
[TARGET_VERASE
];
3059 host
->c_cc
[VKILL
] = target
->c_cc
[TARGET_VKILL
];
3060 host
->c_cc
[VEOF
] = target
->c_cc
[TARGET_VEOF
];
3061 host
->c_cc
[VTIME
] = target
->c_cc
[TARGET_VTIME
];
3062 host
->c_cc
[VMIN
] = target
->c_cc
[TARGET_VMIN
];
3063 host
->c_cc
[VSWTC
] = target
->c_cc
[TARGET_VSWTC
];
3064 host
->c_cc
[VSTART
] = target
->c_cc
[TARGET_VSTART
];
3065 host
->c_cc
[VSTOP
] = target
->c_cc
[TARGET_VSTOP
];
3066 host
->c_cc
[VSUSP
] = target
->c_cc
[TARGET_VSUSP
];
3067 host
->c_cc
[VEOL
] = target
->c_cc
[TARGET_VEOL
];
3068 host
->c_cc
[VREPRINT
] = target
->c_cc
[TARGET_VREPRINT
];
3069 host
->c_cc
[VDISCARD
] = target
->c_cc
[TARGET_VDISCARD
];
3070 host
->c_cc
[VWERASE
] = target
->c_cc
[TARGET_VWERASE
];
3071 host
->c_cc
[VLNEXT
] = target
->c_cc
[TARGET_VLNEXT
];
3072 host
->c_cc
[VEOL2
] = target
->c_cc
[TARGET_VEOL2
];
3075 static void host_to_target_termios (void *dst
, const void *src
)
3077 struct target_termios
*target
= dst
;
3078 const struct host_termios
*host
= src
;
3081 tswap32(host_to_target_bitmask(host
->c_iflag
, iflag_tbl
));
3083 tswap32(host_to_target_bitmask(host
->c_oflag
, oflag_tbl
));
3085 tswap32(host_to_target_bitmask(host
->c_cflag
, cflag_tbl
));
3087 tswap32(host_to_target_bitmask(host
->c_lflag
, lflag_tbl
));
3088 target
->c_line
= host
->c_line
;
3090 memset(target
->c_cc
, 0, sizeof(target
->c_cc
));
3091 target
->c_cc
[TARGET_VINTR
] = host
->c_cc
[VINTR
];
3092 target
->c_cc
[TARGET_VQUIT
] = host
->c_cc
[VQUIT
];
3093 target
->c_cc
[TARGET_VERASE
] = host
->c_cc
[VERASE
];
3094 target
->c_cc
[TARGET_VKILL
] = host
->c_cc
[VKILL
];
3095 target
->c_cc
[TARGET_VEOF
] = host
->c_cc
[VEOF
];
3096 target
->c_cc
[TARGET_VTIME
] = host
->c_cc
[VTIME
];
3097 target
->c_cc
[TARGET_VMIN
] = host
->c_cc
[VMIN
];
3098 target
->c_cc
[TARGET_VSWTC
] = host
->c_cc
[VSWTC
];
3099 target
->c_cc
[TARGET_VSTART
] = host
->c_cc
[VSTART
];
3100 target
->c_cc
[TARGET_VSTOP
] = host
->c_cc
[VSTOP
];
3101 target
->c_cc
[TARGET_VSUSP
] = host
->c_cc
[VSUSP
];
3102 target
->c_cc
[TARGET_VEOL
] = host
->c_cc
[VEOL
];
3103 target
->c_cc
[TARGET_VREPRINT
] = host
->c_cc
[VREPRINT
];
3104 target
->c_cc
[TARGET_VDISCARD
] = host
->c_cc
[VDISCARD
];
3105 target
->c_cc
[TARGET_VWERASE
] = host
->c_cc
[VWERASE
];
3106 target
->c_cc
[TARGET_VLNEXT
] = host
->c_cc
[VLNEXT
];
3107 target
->c_cc
[TARGET_VEOL2
] = host
->c_cc
[VEOL2
];
3110 static const StructEntry struct_termios_def
= {
3111 .convert
= { host_to_target_termios
, target_to_host_termios
},
3112 .size
= { sizeof(struct target_termios
), sizeof(struct host_termios
) },
3113 .align
= { __alignof__(struct target_termios
), __alignof__(struct host_termios
) },
3116 static bitmask_transtbl mmap_flags_tbl
[] = {
3117 { TARGET_MAP_SHARED
, TARGET_MAP_SHARED
, MAP_SHARED
, MAP_SHARED
},
3118 { TARGET_MAP_PRIVATE
, TARGET_MAP_PRIVATE
, MAP_PRIVATE
, MAP_PRIVATE
},
3119 { TARGET_MAP_FIXED
, TARGET_MAP_FIXED
, MAP_FIXED
, MAP_FIXED
},
3120 { TARGET_MAP_ANONYMOUS
, TARGET_MAP_ANONYMOUS
, MAP_ANONYMOUS
, MAP_ANONYMOUS
},
3121 { TARGET_MAP_GROWSDOWN
, TARGET_MAP_GROWSDOWN
, MAP_GROWSDOWN
, MAP_GROWSDOWN
},
3122 { TARGET_MAP_DENYWRITE
, TARGET_MAP_DENYWRITE
, MAP_DENYWRITE
, MAP_DENYWRITE
},
3123 { TARGET_MAP_EXECUTABLE
, TARGET_MAP_EXECUTABLE
, MAP_EXECUTABLE
, MAP_EXECUTABLE
},
3124 { TARGET_MAP_LOCKED
, TARGET_MAP_LOCKED
, MAP_LOCKED
, MAP_LOCKED
},
3128 #if defined(TARGET_I386)
3130 /* NOTE: there is really one LDT for all the threads */
3131 static uint8_t *ldt_table
;
3133 static abi_long
read_ldt(abi_ulong ptr
, unsigned long bytecount
)
3140 size
= TARGET_LDT_ENTRIES
* TARGET_LDT_ENTRY_SIZE
;
3141 if (size
> bytecount
)
3143 p
= lock_user(VERIFY_WRITE
, ptr
, size
, 0);
3145 return -TARGET_EFAULT
;
3146 /* ??? Should this by byteswapped? */
3147 memcpy(p
, ldt_table
, size
);
3148 unlock_user(p
, ptr
, size
);
3152 /* XXX: add locking support */
3153 static abi_long
write_ldt(CPUX86State
*env
,
3154 abi_ulong ptr
, unsigned long bytecount
, int oldmode
)
3156 struct target_modify_ldt_ldt_s ldt_info
;
3157 struct target_modify_ldt_ldt_s
*target_ldt_info
;
3158 int seg_32bit
, contents
, read_exec_only
, limit_in_pages
;
3159 int seg_not_present
, useable
, lm
;
3160 uint32_t *lp
, entry_1
, entry_2
;
3162 if (bytecount
!= sizeof(ldt_info
))
3163 return -TARGET_EINVAL
;
3164 if (!lock_user_struct(VERIFY_READ
, target_ldt_info
, ptr
, 1))
3165 return -TARGET_EFAULT
;
3166 ldt_info
.entry_number
= tswap32(target_ldt_info
->entry_number
);
3167 ldt_info
.base_addr
= tswapl(target_ldt_info
->base_addr
);
3168 ldt_info
.limit
= tswap32(target_ldt_info
->limit
);
3169 ldt_info
.flags
= tswap32(target_ldt_info
->flags
);
3170 unlock_user_struct(target_ldt_info
, ptr
, 0);
3172 if (ldt_info
.entry_number
>= TARGET_LDT_ENTRIES
)
3173 return -TARGET_EINVAL
;
3174 seg_32bit
= ldt_info
.flags
& 1;
3175 contents
= (ldt_info
.flags
>> 1) & 3;
3176 read_exec_only
= (ldt_info
.flags
>> 3) & 1;
3177 limit_in_pages
= (ldt_info
.flags
>> 4) & 1;
3178 seg_not_present
= (ldt_info
.flags
>> 5) & 1;
3179 useable
= (ldt_info
.flags
>> 6) & 1;
3183 lm
= (ldt_info
.flags
>> 7) & 1;
3185 if (contents
== 3) {
3187 return -TARGET_EINVAL
;
3188 if (seg_not_present
== 0)
3189 return -TARGET_EINVAL
;
3191 /* allocate the LDT */
3193 env
->ldt
.base
= target_mmap(0,
3194 TARGET_LDT_ENTRIES
* TARGET_LDT_ENTRY_SIZE
,
3195 PROT_READ
|PROT_WRITE
,
3196 MAP_ANONYMOUS
|MAP_PRIVATE
, -1, 0);
3197 if (env
->ldt
.base
== -1)
3198 return -TARGET_ENOMEM
;
3199 memset(g2h(env
->ldt
.base
), 0,
3200 TARGET_LDT_ENTRIES
* TARGET_LDT_ENTRY_SIZE
);
3201 env
->ldt
.limit
= 0xffff;
3202 ldt_table
= g2h(env
->ldt
.base
);
3205 /* NOTE: same code as Linux kernel */
3206 /* Allow LDTs to be cleared by the user. */
3207 if (ldt_info
.base_addr
== 0 && ldt_info
.limit
== 0) {
3210 read_exec_only
== 1 &&
3212 limit_in_pages
== 0 &&
3213 seg_not_present
== 1 &&
3221 entry_1
= ((ldt_info
.base_addr
& 0x0000ffff) << 16) |
3222 (ldt_info
.limit
& 0x0ffff);
3223 entry_2
= (ldt_info
.base_addr
& 0xff000000) |
3224 ((ldt_info
.base_addr
& 0x00ff0000) >> 16) |
3225 (ldt_info
.limit
& 0xf0000) |
3226 ((read_exec_only
^ 1) << 9) |
3228 ((seg_not_present
^ 1) << 15) |
3230 (limit_in_pages
<< 23) |
3234 entry_2
|= (useable
<< 20);
3236 /* Install the new entry ... */
3238 lp
= (uint32_t *)(ldt_table
+ (ldt_info
.entry_number
<< 3));
3239 lp
[0] = tswap32(entry_1
);
3240 lp
[1] = tswap32(entry_2
);
3244 /* specific and weird i386 syscalls */
3245 static abi_long
do_modify_ldt(CPUX86State
*env
, int func
, abi_ulong ptr
,
3246 unsigned long bytecount
)
3252 ret
= read_ldt(ptr
, bytecount
);
3255 ret
= write_ldt(env
, ptr
, bytecount
, 1);
3258 ret
= write_ldt(env
, ptr
, bytecount
, 0);
3261 ret
= -TARGET_ENOSYS
;
3267 #if defined(TARGET_I386) && defined(TARGET_ABI32)
3268 static abi_long
do_set_thread_area(CPUX86State
*env
, abi_ulong ptr
)
3270 uint64_t *gdt_table
= g2h(env
->gdt
.base
);
3271 struct target_modify_ldt_ldt_s ldt_info
;
3272 struct target_modify_ldt_ldt_s
*target_ldt_info
;
3273 int seg_32bit
, contents
, read_exec_only
, limit_in_pages
;
3274 int seg_not_present
, useable
, lm
;
3275 uint32_t *lp
, entry_1
, entry_2
;
3278 lock_user_struct(VERIFY_WRITE
, target_ldt_info
, ptr
, 1);
3279 if (!target_ldt_info
)
3280 return -TARGET_EFAULT
;
3281 ldt_info
.entry_number
= tswap32(target_ldt_info
->entry_number
);
3282 ldt_info
.base_addr
= tswapl(target_ldt_info
->base_addr
);
3283 ldt_info
.limit
= tswap32(target_ldt_info
->limit
);
3284 ldt_info
.flags
= tswap32(target_ldt_info
->flags
);
3285 if (ldt_info
.entry_number
== -1) {
3286 for (i
=TARGET_GDT_ENTRY_TLS_MIN
; i
<=TARGET_GDT_ENTRY_TLS_MAX
; i
++) {
3287 if (gdt_table
[i
] == 0) {
3288 ldt_info
.entry_number
= i
;
3289 target_ldt_info
->entry_number
= tswap32(i
);
3294 unlock_user_struct(target_ldt_info
, ptr
, 1);
3296 if (ldt_info
.entry_number
< TARGET_GDT_ENTRY_TLS_MIN
||
3297 ldt_info
.entry_number
> TARGET_GDT_ENTRY_TLS_MAX
)
3298 return -TARGET_EINVAL
;
3299 seg_32bit
= ldt_info
.flags
& 1;
3300 contents
= (ldt_info
.flags
>> 1) & 3;
3301 read_exec_only
= (ldt_info
.flags
>> 3) & 1;
3302 limit_in_pages
= (ldt_info
.flags
>> 4) & 1;
3303 seg_not_present
= (ldt_info
.flags
>> 5) & 1;
3304 useable
= (ldt_info
.flags
>> 6) & 1;
3308 lm
= (ldt_info
.flags
>> 7) & 1;
3311 if (contents
== 3) {
3312 if (seg_not_present
== 0)
3313 return -TARGET_EINVAL
;
3316 /* NOTE: same code as Linux kernel */
3317 /* Allow LDTs to be cleared by the user. */
3318 if (ldt_info
.base_addr
== 0 && ldt_info
.limit
== 0) {
3319 if ((contents
== 0 &&
3320 read_exec_only
== 1 &&
3322 limit_in_pages
== 0 &&
3323 seg_not_present
== 1 &&
3331 entry_1
= ((ldt_info
.base_addr
& 0x0000ffff) << 16) |
3332 (ldt_info
.limit
& 0x0ffff);
3333 entry_2
= (ldt_info
.base_addr
& 0xff000000) |
3334 ((ldt_info
.base_addr
& 0x00ff0000) >> 16) |
3335 (ldt_info
.limit
& 0xf0000) |
3336 ((read_exec_only
^ 1) << 9) |
3338 ((seg_not_present
^ 1) << 15) |
3340 (limit_in_pages
<< 23) |
3345 /* Install the new entry ... */
3347 lp
= (uint32_t *)(gdt_table
+ ldt_info
.entry_number
);
3348 lp
[0] = tswap32(entry_1
);
3349 lp
[1] = tswap32(entry_2
);
3353 static abi_long
do_get_thread_area(CPUX86State
*env
, abi_ulong ptr
)
3355 struct target_modify_ldt_ldt_s
*target_ldt_info
;
3356 uint64_t *gdt_table
= g2h(env
->gdt
.base
);
3357 uint32_t base_addr
, limit
, flags
;
3358 int seg_32bit
, contents
, read_exec_only
, limit_in_pages
, idx
;
3359 int seg_not_present
, useable
, lm
;
3360 uint32_t *lp
, entry_1
, entry_2
;
3362 lock_user_struct(VERIFY_WRITE
, target_ldt_info
, ptr
, 1);
3363 if (!target_ldt_info
)
3364 return -TARGET_EFAULT
;
3365 idx
= tswap32(target_ldt_info
->entry_number
);
3366 if (idx
< TARGET_GDT_ENTRY_TLS_MIN
||
3367 idx
> TARGET_GDT_ENTRY_TLS_MAX
) {
3368 unlock_user_struct(target_ldt_info
, ptr
, 1);
3369 return -TARGET_EINVAL
;
3371 lp
= (uint32_t *)(gdt_table
+ idx
);
3372 entry_1
= tswap32(lp
[0]);
3373 entry_2
= tswap32(lp
[1]);
3375 read_exec_only
= ((entry_2
>> 9) & 1) ^ 1;
3376 contents
= (entry_2
>> 10) & 3;
3377 seg_not_present
= ((entry_2
>> 15) & 1) ^ 1;
3378 seg_32bit
= (entry_2
>> 22) & 1;
3379 limit_in_pages
= (entry_2
>> 23) & 1;
3380 useable
= (entry_2
>> 20) & 1;
3384 lm
= (entry_2
>> 21) & 1;
3386 flags
= (seg_32bit
<< 0) | (contents
<< 1) |
3387 (read_exec_only
<< 3) | (limit_in_pages
<< 4) |
3388 (seg_not_present
<< 5) | (useable
<< 6) | (lm
<< 7);
3389 limit
= (entry_1
& 0xffff) | (entry_2
& 0xf0000);
3390 base_addr
= (entry_1
>> 16) |
3391 (entry_2
& 0xff000000) |
3392 ((entry_2
& 0xff) << 16);
3393 target_ldt_info
->base_addr
= tswapl(base_addr
);
3394 target_ldt_info
->limit
= tswap32(limit
);
3395 target_ldt_info
->flags
= tswap32(flags
);
3396 unlock_user_struct(target_ldt_info
, ptr
, 1);
3399 #endif /* TARGET_I386 && TARGET_ABI32 */
3401 #ifndef TARGET_ABI32
3402 static abi_long
do_arch_prctl(CPUX86State
*env
, int code
, abi_ulong addr
)
3409 case TARGET_ARCH_SET_GS
:
3410 case TARGET_ARCH_SET_FS
:
3411 if (code
== TARGET_ARCH_SET_GS
)
3415 cpu_x86_load_seg(env
, idx
, 0);
3416 env
->segs
[idx
].base
= addr
;
3418 case TARGET_ARCH_GET_GS
:
3419 case TARGET_ARCH_GET_FS
:
3420 if (code
== TARGET_ARCH_GET_GS
)
3424 val
= env
->segs
[idx
].base
;
3425 if (put_user(val
, addr
, abi_ulong
))
3426 return -TARGET_EFAULT
;
3429 ret
= -TARGET_EINVAL
;
3436 #endif /* defined(TARGET_I386) */
3438 #if defined(USE_NPTL)
3440 #define NEW_STACK_SIZE PTHREAD_STACK_MIN
3442 static pthread_mutex_t clone_lock
= PTHREAD_MUTEX_INITIALIZER
;
3445 pthread_mutex_t mutex
;
3446 pthread_cond_t cond
;
3449 abi_ulong child_tidptr
;
3450 abi_ulong parent_tidptr
;
3454 static void *clone_func(void *arg
)
3456 new_thread_info
*info
= arg
;
3462 ts
= (TaskState
*)thread_env
->opaque
;
3463 info
->tid
= gettid();
3464 env
->host_tid
= info
->tid
;
3466 if (info
->child_tidptr
)
3467 put_user_u32(info
->tid
, info
->child_tidptr
);
3468 if (info
->parent_tidptr
)
3469 put_user_u32(info
->tid
, info
->parent_tidptr
);
3470 /* Enable signals. */
3471 sigprocmask(SIG_SETMASK
, &info
->sigmask
, NULL
);
3472 /* Signal to the parent that we're ready. */
3473 pthread_mutex_lock(&info
->mutex
);
3474 pthread_cond_broadcast(&info
->cond
);
3475 pthread_mutex_unlock(&info
->mutex
);
3476 /* Wait until the parent has finshed initializing the tls state. */
3477 pthread_mutex_lock(&clone_lock
);
3478 pthread_mutex_unlock(&clone_lock
);
3484 /* this stack is the equivalent of the kernel stack associated with a
3486 #define NEW_STACK_SIZE 8192
3488 static int clone_func(void *arg
)
3490 CPUState
*env
= arg
;
3497 /* do_fork() Must return host values and target errnos (unlike most
3498 do_*() functions). */
3499 static int do_fork(CPUState
*env
, unsigned int flags
, abi_ulong newsp
,
3500 abi_ulong parent_tidptr
, target_ulong newtls
,
3501 abi_ulong child_tidptr
)
3507 #if defined(USE_NPTL)
3508 unsigned int nptl_flags
;
3512 /* Emulate vfork() with fork() */
3513 if (flags
& CLONE_VFORK
)
3514 flags
&= ~(CLONE_VFORK
| CLONE_VM
);
3516 if (flags
& CLONE_VM
) {
3517 TaskState
*parent_ts
= (TaskState
*)env
->opaque
;
3518 #if defined(USE_NPTL)
3519 new_thread_info info
;
3520 pthread_attr_t attr
;
3522 ts
= qemu_mallocz(sizeof(TaskState
) + NEW_STACK_SIZE
);
3523 init_task_state(ts
);
3524 new_stack
= ts
->stack
;
3525 /* we create a new CPU instance. */
3526 new_env
= cpu_copy(env
);
3527 /* Init regs that differ from the parent. */
3528 cpu_clone_regs(new_env
, newsp
);
3529 new_env
->opaque
= ts
;
3530 ts
->bprm
= parent_ts
->bprm
;
3531 ts
->info
= parent_ts
->info
;
3532 #if defined(USE_NPTL)
3534 flags
&= ~CLONE_NPTL_FLAGS2
;
3536 if (nptl_flags
& CLONE_CHILD_CLEARTID
) {
3537 ts
->child_tidptr
= child_tidptr
;
3540 if (nptl_flags
& CLONE_SETTLS
)
3541 cpu_set_tls (new_env
, newtls
);
3543 /* Grab a mutex so that thread setup appears atomic. */
3544 pthread_mutex_lock(&clone_lock
);
3546 memset(&info
, 0, sizeof(info
));
3547 pthread_mutex_init(&info
.mutex
, NULL
);
3548 pthread_mutex_lock(&info
.mutex
);
3549 pthread_cond_init(&info
.cond
, NULL
);
3551 if (nptl_flags
& CLONE_CHILD_SETTID
)
3552 info
.child_tidptr
= child_tidptr
;
3553 if (nptl_flags
& CLONE_PARENT_SETTID
)
3554 info
.parent_tidptr
= parent_tidptr
;
3556 ret
= pthread_attr_init(&attr
);
3557 ret
= pthread_attr_setstack(&attr
, new_stack
, NEW_STACK_SIZE
);
3558 /* It is not safe to deliver signals until the child has finished
3559 initializing, so temporarily block all signals. */
3560 sigfillset(&sigmask
);
3561 sigprocmask(SIG_BLOCK
, &sigmask
, &info
.sigmask
);
3563 ret
= pthread_create(&info
.thread
, &attr
, clone_func
, &info
);
3564 /* TODO: Free new CPU state if thread creation failed. */
3566 sigprocmask(SIG_SETMASK
, &info
.sigmask
, NULL
);
3567 pthread_attr_destroy(&attr
);
3569 /* Wait for the child to initialize. */
3570 pthread_cond_wait(&info
.cond
, &info
.mutex
);
3572 if (flags
& CLONE_PARENT_SETTID
)
3573 put_user_u32(ret
, parent_tidptr
);
3577 pthread_mutex_unlock(&info
.mutex
);
3578 pthread_cond_destroy(&info
.cond
);
3579 pthread_mutex_destroy(&info
.mutex
);
3580 pthread_mutex_unlock(&clone_lock
);
3582 if (flags
& CLONE_NPTL_FLAGS2
)
3584 /* This is probably going to die very quickly, but do it anyway. */
3586 ret
= __clone2(clone_func
, new_stack
+ NEW_STACK_SIZE
, flags
, new_env
);
3588 ret
= clone(clone_func
, new_stack
+ NEW_STACK_SIZE
, flags
, new_env
);
3592 /* if no CLONE_VM, we consider it is a fork */
3593 if ((flags
& ~(CSIGNAL
| CLONE_NPTL_FLAGS2
)) != 0)
3598 /* Child Process. */
3599 cpu_clone_regs(env
, newsp
);
3601 #if defined(USE_NPTL)
3602 /* There is a race condition here. The parent process could
3603 theoretically read the TID in the child process before the child
3604 tid is set. This would require using either ptrace
3605 (not implemented) or having *_tidptr to point at a shared memory
3606 mapping. We can't repeat the spinlock hack used above because
3607 the child process gets its own copy of the lock. */
3608 if (flags
& CLONE_CHILD_SETTID
)
3609 put_user_u32(gettid(), child_tidptr
);
3610 if (flags
& CLONE_PARENT_SETTID
)
3611 put_user_u32(gettid(), parent_tidptr
);
3612 ts
= (TaskState
*)env
->opaque
;
3613 if (flags
& CLONE_SETTLS
)
3614 cpu_set_tls (env
, newtls
);
3615 if (flags
& CLONE_CHILD_CLEARTID
)
3616 ts
->child_tidptr
= child_tidptr
;
3625 static abi_long
do_fcntl(int fd
, int cmd
, abi_ulong arg
)
3628 struct target_flock
*target_fl
;
3629 struct flock64 fl64
;
3630 struct target_flock64
*target_fl64
;
3634 case TARGET_F_GETLK
:
3635 if (!lock_user_struct(VERIFY_READ
, target_fl
, arg
, 1))
3636 return -TARGET_EFAULT
;
3637 fl
.l_type
= tswap16(target_fl
->l_type
);
3638 fl
.l_whence
= tswap16(target_fl
->l_whence
);
3639 fl
.l_start
= tswapl(target_fl
->l_start
);
3640 fl
.l_len
= tswapl(target_fl
->l_len
);
3641 fl
.l_pid
= tswapl(target_fl
->l_pid
);
3642 unlock_user_struct(target_fl
, arg
, 0);
3643 ret
= get_errno(fcntl(fd
, cmd
, &fl
));
3645 if (!lock_user_struct(VERIFY_WRITE
, target_fl
, arg
, 0))
3646 return -TARGET_EFAULT
;
3647 target_fl
->l_type
= tswap16(fl
.l_type
);
3648 target_fl
->l_whence
= tswap16(fl
.l_whence
);
3649 target_fl
->l_start
= tswapl(fl
.l_start
);
3650 target_fl
->l_len
= tswapl(fl
.l_len
);
3651 target_fl
->l_pid
= tswapl(fl
.l_pid
);
3652 unlock_user_struct(target_fl
, arg
, 1);
3656 case TARGET_F_SETLK
:
3657 case TARGET_F_SETLKW
:
3658 if (!lock_user_struct(VERIFY_READ
, target_fl
, arg
, 1))
3659 return -TARGET_EFAULT
;
3660 fl
.l_type
= tswap16(target_fl
->l_type
);
3661 fl
.l_whence
= tswap16(target_fl
->l_whence
);
3662 fl
.l_start
= tswapl(target_fl
->l_start
);
3663 fl
.l_len
= tswapl(target_fl
->l_len
);
3664 fl
.l_pid
= tswapl(target_fl
->l_pid
);
3665 unlock_user_struct(target_fl
, arg
, 0);
3666 ret
= get_errno(fcntl(fd
, cmd
, &fl
));
3669 case TARGET_F_GETLK64
:
3670 if (!lock_user_struct(VERIFY_READ
, target_fl64
, arg
, 1))
3671 return -TARGET_EFAULT
;
3672 fl64
.l_type
= tswap16(target_fl64
->l_type
) >> 1;
3673 fl64
.l_whence
= tswap16(target_fl64
->l_whence
);
3674 fl64
.l_start
= tswapl(target_fl64
->l_start
);
3675 fl64
.l_len
= tswapl(target_fl64
->l_len
);
3676 fl64
.l_pid
= tswap16(target_fl64
->l_pid
);
3677 unlock_user_struct(target_fl64
, arg
, 0);
3678 ret
= get_errno(fcntl(fd
, cmd
>> 1, &fl64
));
3680 if (!lock_user_struct(VERIFY_WRITE
, target_fl64
, arg
, 0))
3681 return -TARGET_EFAULT
;
3682 target_fl64
->l_type
= tswap16(fl64
.l_type
) >> 1;
3683 target_fl64
->l_whence
= tswap16(fl64
.l_whence
);
3684 target_fl64
->l_start
= tswapl(fl64
.l_start
);
3685 target_fl64
->l_len
= tswapl(fl64
.l_len
);
3686 target_fl64
->l_pid
= tswapl(fl64
.l_pid
);
3687 unlock_user_struct(target_fl64
, arg
, 1);
3690 case TARGET_F_SETLK64
:
3691 case TARGET_F_SETLKW64
:
3692 if (!lock_user_struct(VERIFY_READ
, target_fl64
, arg
, 1))
3693 return -TARGET_EFAULT
;
3694 fl64
.l_type
= tswap16(target_fl64
->l_type
) >> 1;
3695 fl64
.l_whence
= tswap16(target_fl64
->l_whence
);
3696 fl64
.l_start
= tswapl(target_fl64
->l_start
);
3697 fl64
.l_len
= tswapl(target_fl64
->l_len
);
3698 fl64
.l_pid
= tswap16(target_fl64
->l_pid
);
3699 unlock_user_struct(target_fl64
, arg
, 0);
3700 ret
= get_errno(fcntl(fd
, cmd
>> 1, &fl64
));
3704 ret
= get_errno(fcntl(fd
, cmd
, arg
));
3706 ret
= host_to_target_bitmask(ret
, fcntl_flags_tbl
);
3711 ret
= get_errno(fcntl(fd
, cmd
, target_to_host_bitmask(arg
, fcntl_flags_tbl
)));
3715 ret
= get_errno(fcntl(fd
, cmd
, arg
));
3723 static inline int high2lowuid(int uid
)
3731 static inline int high2lowgid(int gid
)
3739 static inline int low2highuid(int uid
)
3741 if ((int16_t)uid
== -1)
3747 static inline int low2highgid(int gid
)
3749 if ((int16_t)gid
== -1)
3755 #endif /* USE_UID16 */
3757 void syscall_init(void)
3760 const argtype
*arg_type
;
3764 #define STRUCT(name, ...) thunk_register_struct(STRUCT_ ## name, #name, struct_ ## name ## _def);
3765 #define STRUCT_SPECIAL(name) thunk_register_struct_direct(STRUCT_ ## name, #name, &struct_ ## name ## _def);
3766 #include "syscall_types.h"
3768 #undef STRUCT_SPECIAL
3770 /* we patch the ioctl size if necessary. We rely on the fact that
3771 no ioctl has all the bits at '1' in the size field */
3773 while (ie
->target_cmd
!= 0) {
3774 if (((ie
->target_cmd
>> TARGET_IOC_SIZESHIFT
) & TARGET_IOC_SIZEMASK
) ==
3775 TARGET_IOC_SIZEMASK
) {
3776 arg_type
= ie
->arg_type
;
3777 if (arg_type
[0] != TYPE_PTR
) {
3778 fprintf(stderr
, "cannot patch size for ioctl 0x%x\n",
3783 size
= thunk_type_size(arg_type
, 0);
3784 ie
->target_cmd
= (ie
->target_cmd
&
3785 ~(TARGET_IOC_SIZEMASK
<< TARGET_IOC_SIZESHIFT
)) |
3786 (size
<< TARGET_IOC_SIZESHIFT
);
3789 /* Build target_to_host_errno_table[] table from
3790 * host_to_target_errno_table[]. */
3791 for (i
=0; i
< ERRNO_TABLE_SIZE
; i
++)
3792 target_to_host_errno_table
[host_to_target_errno_table
[i
]] = i
;
3794 /* automatic consistency check if same arch */
3795 #if (defined(__i386__) && defined(TARGET_I386) && defined(TARGET_ABI32)) || \
3796 (defined(__x86_64__) && defined(TARGET_X86_64))
3797 if (unlikely(ie
->target_cmd
!= ie
->host_cmd
)) {
3798 fprintf(stderr
, "ERROR: ioctl(%s): target=0x%x host=0x%x\n",
3799 ie
->name
, ie
->target_cmd
, ie
->host_cmd
);
3806 #if TARGET_ABI_BITS == 32
3807 static inline uint64_t target_offset64(uint32_t word0
, uint32_t word1
)
3809 #ifdef TARGET_WORDS_BIGENDIAN
3810 return ((uint64_t)word0
<< 32) | word1
;
3812 return ((uint64_t)word1
<< 32) | word0
;
3815 #else /* TARGET_ABI_BITS == 32 */
3816 static inline uint64_t target_offset64(uint64_t word0
, uint64_t word1
)
3820 #endif /* TARGET_ABI_BITS != 32 */
3822 #ifdef TARGET_NR_truncate64
3823 static inline abi_long
target_truncate64(void *cpu_env
, const char *arg1
,
3829 if (((CPUARMState
*)cpu_env
)->eabi
)
3835 return get_errno(truncate64(arg1
, target_offset64(arg2
, arg3
)));
3839 #ifdef TARGET_NR_ftruncate64
3840 static inline abi_long
target_ftruncate64(void *cpu_env
, abi_long arg1
,
3846 if (((CPUARMState
*)cpu_env
)->eabi
)
3852 return get_errno(ftruncate64(arg1
, target_offset64(arg2
, arg3
)));
3856 static inline abi_long
target_to_host_timespec(struct timespec
*host_ts
,
3857 abi_ulong target_addr
)
3859 struct target_timespec
*target_ts
;
3861 if (!lock_user_struct(VERIFY_READ
, target_ts
, target_addr
, 1))
3862 return -TARGET_EFAULT
;
3863 host_ts
->tv_sec
= tswapl(target_ts
->tv_sec
);
3864 host_ts
->tv_nsec
= tswapl(target_ts
->tv_nsec
);
3865 unlock_user_struct(target_ts
, target_addr
, 0);
3869 static inline abi_long
host_to_target_timespec(abi_ulong target_addr
,
3870 struct timespec
*host_ts
)
3872 struct target_timespec
*target_ts
;
3874 if (!lock_user_struct(VERIFY_WRITE
, target_ts
, target_addr
, 0))
3875 return -TARGET_EFAULT
;
3876 target_ts
->tv_sec
= tswapl(host_ts
->tv_sec
);
3877 target_ts
->tv_nsec
= tswapl(host_ts
->tv_nsec
);
3878 unlock_user_struct(target_ts
, target_addr
, 1);
3882 #if defined(TARGET_NR_stat64) || defined(TARGET_NR_newfstatat)
3883 static inline abi_long
host_to_target_stat64(void *cpu_env
,
3884 abi_ulong target_addr
,
3885 struct stat
*host_st
)
3888 if (((CPUARMState
*)cpu_env
)->eabi
) {
3889 struct target_eabi_stat64
*target_st
;
3891 if (!lock_user_struct(VERIFY_WRITE
, target_st
, target_addr
, 0))
3892 return -TARGET_EFAULT
;
3893 memset(target_st
, 0, sizeof(struct target_eabi_stat64
));
3894 __put_user(host_st
->st_dev
, &target_st
->st_dev
);
3895 __put_user(host_st
->st_ino
, &target_st
->st_ino
);
3896 #ifdef TARGET_STAT64_HAS_BROKEN_ST_INO
3897 __put_user(host_st
->st_ino
, &target_st
->__st_ino
);
3899 __put_user(host_st
->st_mode
, &target_st
->st_mode
);
3900 __put_user(host_st
->st_nlink
, &target_st
->st_nlink
);
3901 __put_user(host_st
->st_uid
, &target_st
->st_uid
);
3902 __put_user(host_st
->st_gid
, &target_st
->st_gid
);
3903 __put_user(host_st
->st_rdev
, &target_st
->st_rdev
);
3904 __put_user(host_st
->st_size
, &target_st
->st_size
);
3905 __put_user(host_st
->st_blksize
, &target_st
->st_blksize
);
3906 __put_user(host_st
->st_blocks
, &target_st
->st_blocks
);
3907 __put_user(host_st
->st_atime
, &target_st
->target_st_atime
);
3908 __put_user(host_st
->st_mtime
, &target_st
->target_st_mtime
);
3909 __put_user(host_st
->st_ctime
, &target_st
->target_st_ctime
);
3910 unlock_user_struct(target_st
, target_addr
, 1);
3914 #if TARGET_LONG_BITS == 64
3915 struct target_stat
*target_st
;
3917 struct target_stat64
*target_st
;
3920 if (!lock_user_struct(VERIFY_WRITE
, target_st
, target_addr
, 0))
3921 return -TARGET_EFAULT
;
3922 memset(target_st
, 0, sizeof(*target_st
));
3923 __put_user(host_st
->st_dev
, &target_st
->st_dev
);
3924 __put_user(host_st
->st_ino
, &target_st
->st_ino
);
3925 #ifdef TARGET_STAT64_HAS_BROKEN_ST_INO
3926 __put_user(host_st
->st_ino
, &target_st
->__st_ino
);
3928 __put_user(host_st
->st_mode
, &target_st
->st_mode
);
3929 __put_user(host_st
->st_nlink
, &target_st
->st_nlink
);
3930 __put_user(host_st
->st_uid
, &target_st
->st_uid
);
3931 __put_user(host_st
->st_gid
, &target_st
->st_gid
);
3932 __put_user(host_st
->st_rdev
, &target_st
->st_rdev
);
3933 /* XXX: better use of kernel struct */
3934 __put_user(host_st
->st_size
, &target_st
->st_size
);
3935 __put_user(host_st
->st_blksize
, &target_st
->st_blksize
);
3936 __put_user(host_st
->st_blocks
, &target_st
->st_blocks
);
3937 __put_user(host_st
->st_atime
, &target_st
->target_st_atime
);
3938 __put_user(host_st
->st_mtime
, &target_st
->target_st_mtime
);
3939 __put_user(host_st
->st_ctime
, &target_st
->target_st_ctime
);
3940 unlock_user_struct(target_st
, target_addr
, 1);
3947 #if defined(USE_NPTL)
3948 /* ??? Using host futex calls even when target atomic operations
3949 are not really atomic probably breaks things. However implementing
3950 futexes locally would make futexes shared between multiple processes
3951 tricky. However they're probably useless because guest atomic
3952 operations won't work either. */
3953 static int do_futex(target_ulong uaddr
, int op
, int val
, target_ulong timeout
,
3954 target_ulong uaddr2
, int val3
)
3956 struct timespec ts
, *pts
;
3958 /* ??? We assume FUTEX_* constants are the same on both host
3960 #ifdef FUTEX_CMD_MASK
3961 switch ((op
&FUTEX_CMD_MASK
)) {
3968 target_to_host_timespec(pts
, timeout
);
3972 return get_errno(sys_futex(g2h(uaddr
), op
, tswap32(val
),
3975 return get_errno(sys_futex(g2h(uaddr
), op
, val
, NULL
, NULL
, 0));
3977 return get_errno(sys_futex(g2h(uaddr
), op
, val
, NULL
, g2h(uaddr2
), val3
));
3979 return get_errno(sys_futex(g2h(uaddr
), op
, val
, NULL
, NULL
, 0));
3981 return get_errno(sys_futex(g2h(uaddr
), op
, val
,
3982 NULL
, g2h(uaddr2
), 0));
3983 case FUTEX_CMP_REQUEUE
:
3984 return get_errno(sys_futex(g2h(uaddr
), op
, val
,
3985 NULL
, g2h(uaddr2
), tswap32(val3
)));
3987 return -TARGET_ENOSYS
;
3992 /* Map host to target signal numbers for the wait family of syscalls.
3993 Assume all other status bits are the same. */
3994 static int host_to_target_waitstatus(int status
)
3996 if (WIFSIGNALED(status
)) {
3997 return host_to_target_signal(WTERMSIG(status
)) | (status
& ~0x7f);
3999 if (WIFSTOPPED(status
)) {
4000 return (host_to_target_signal(WSTOPSIG(status
)) << 8)
4006 int get_osversion(void)
4008 static int osversion
;
4009 struct new_utsname buf
;
4014 if (qemu_uname_release
&& *qemu_uname_release
) {
4015 s
= qemu_uname_release
;
4017 if (sys_uname(&buf
))
4022 for (i
= 0; i
< 3; i
++) {
4024 while (*s
>= '0' && *s
<= '9') {
4029 tmp
= (tmp
<< 8) + n
;
4037 /* do_syscall() should always have a single exit point at the end so
4038 that actions, such as logging of syscall results, can be performed.
4039 All errnos that do_syscall() returns must be -TARGET_<errcode>. */
4040 abi_long
do_syscall(void *cpu_env
, int num
, abi_long arg1
,
4041 abi_long arg2
, abi_long arg3
, abi_long arg4
,
4042 abi_long arg5
, abi_long arg6
)
4050 gemu_log("syscall %d", num
);
4053 print_syscall(num
, arg1
, arg2
, arg3
, arg4
, arg5
, arg6
);
4056 case TARGET_NR_exit
:
4058 /* In old applications this may be used to implement _exit(2).
4059 However in threaded applictions it is used for thread termination,
4060 and _exit_group is used for application termination.
4061 Do thread termination if we have more then one thread. */
4062 /* FIXME: This probably breaks if a signal arrives. We should probably
4063 be disabling signals. */
4064 if (first_cpu
->next_cpu
) {
4072 while (p
&& p
!= (CPUState
*)cpu_env
) {
4073 lastp
= &p
->next_cpu
;
4076 /* If we didn't find the CPU for this thread then something is
4080 /* Remove the CPU from the list. */
4081 *lastp
= p
->next_cpu
;
4083 ts
= ((CPUState
*)cpu_env
)->opaque
;
4084 if (ts
->child_tidptr
) {
4085 put_user_u32(0, ts
->child_tidptr
);
4086 sys_futex(g2h(ts
->child_tidptr
), FUTEX_WAKE
, INT_MAX
,
4089 /* TODO: Free CPU state. */
4096 gdb_exit(cpu_env
, arg1
);
4098 ret
= 0; /* avoid warning */
4100 case TARGET_NR_read
:
4104 if (!(p
= lock_user(VERIFY_WRITE
, arg2
, arg3
, 0)))
4106 ret
= get_errno(read(arg1
, p
, arg3
));
4107 unlock_user(p
, arg2
, ret
);
4110 case TARGET_NR_write
:
4111 if (!(p
= lock_user(VERIFY_READ
, arg2
, arg3
, 1)))
4113 ret
= get_errno(write(arg1
, p
, arg3
));
4114 unlock_user(p
, arg2
, 0);
4116 case TARGET_NR_open
:
4117 if (!(p
= lock_user_string(arg1
)))
4119 ret
= get_errno(open(path(p
),
4120 target_to_host_bitmask(arg2
, fcntl_flags_tbl
),
4122 unlock_user(p
, arg1
, 0);
4124 #if defined(TARGET_NR_openat) && defined(__NR_openat)
4125 case TARGET_NR_openat
:
4126 if (!(p
= lock_user_string(arg2
)))
4128 ret
= get_errno(sys_openat(arg1
,
4130 target_to_host_bitmask(arg3
, fcntl_flags_tbl
),
4132 unlock_user(p
, arg2
, 0);
4135 case TARGET_NR_close
:
4136 ret
= get_errno(close(arg1
));
4141 case TARGET_NR_fork
:
4142 ret
= get_errno(do_fork(cpu_env
, SIGCHLD
, 0, 0, 0, 0));
4144 #ifdef TARGET_NR_waitpid
4145 case TARGET_NR_waitpid
:
4148 ret
= get_errno(waitpid(arg1
, &status
, arg3
));
4149 if (!is_error(ret
) && arg2
4150 && put_user_s32(host_to_target_waitstatus(status
), arg2
))
4155 #ifdef TARGET_NR_waitid
4156 case TARGET_NR_waitid
:
4160 ret
= get_errno(waitid(arg1
, arg2
, &info
, arg4
));
4161 if (!is_error(ret
) && arg3
&& info
.si_pid
!= 0) {
4162 if (!(p
= lock_user(VERIFY_WRITE
, arg3
, sizeof(target_siginfo_t
), 0)))
4164 host_to_target_siginfo(p
, &info
);
4165 unlock_user(p
, arg3
, sizeof(target_siginfo_t
));
4170 #ifdef TARGET_NR_creat /* not on alpha */
4171 case TARGET_NR_creat
:
4172 if (!(p
= lock_user_string(arg1
)))
4174 ret
= get_errno(creat(p
, arg2
));
4175 unlock_user(p
, arg1
, 0);
4178 case TARGET_NR_link
:
4181 p
= lock_user_string(arg1
);
4182 p2
= lock_user_string(arg2
);
4184 ret
= -TARGET_EFAULT
;
4186 ret
= get_errno(link(p
, p2
));
4187 unlock_user(p2
, arg2
, 0);
4188 unlock_user(p
, arg1
, 0);
4191 #if defined(TARGET_NR_linkat) && defined(__NR_linkat)
4192 case TARGET_NR_linkat
:
4197 p
= lock_user_string(arg2
);
4198 p2
= lock_user_string(arg4
);
4200 ret
= -TARGET_EFAULT
;
4202 ret
= get_errno(sys_linkat(arg1
, p
, arg3
, p2
, arg5
));
4203 unlock_user(p
, arg2
, 0);
4204 unlock_user(p2
, arg4
, 0);
4208 case TARGET_NR_unlink
:
4209 if (!(p
= lock_user_string(arg1
)))
4211 ret
= get_errno(unlink(p
));
4212 unlock_user(p
, arg1
, 0);
4214 #if defined(TARGET_NR_unlinkat) && defined(__NR_unlinkat)
4215 case TARGET_NR_unlinkat
:
4216 if (!(p
= lock_user_string(arg2
)))
4218 ret
= get_errno(sys_unlinkat(arg1
, p
, arg3
));
4219 unlock_user(p
, arg2
, 0);
4222 case TARGET_NR_execve
:
4224 char **argp
, **envp
;
4227 abi_ulong guest_argp
;
4228 abi_ulong guest_envp
;
4234 for (gp
= guest_argp
; gp
; gp
+= sizeof(abi_ulong
)) {
4235 if (get_user_ual(addr
, gp
))
4243 for (gp
= guest_envp
; gp
; gp
+= sizeof(abi_ulong
)) {
4244 if (get_user_ual(addr
, gp
))
4251 argp
= alloca((argc
+ 1) * sizeof(void *));
4252 envp
= alloca((envc
+ 1) * sizeof(void *));
4254 for (gp
= guest_argp
, q
= argp
; gp
;
4255 gp
+= sizeof(abi_ulong
), q
++) {
4256 if (get_user_ual(addr
, gp
))
4260 if (!(*q
= lock_user_string(addr
)))
4265 for (gp
= guest_envp
, q
= envp
; gp
;
4266 gp
+= sizeof(abi_ulong
), q
++) {
4267 if (get_user_ual(addr
, gp
))
4271 if (!(*q
= lock_user_string(addr
)))
4276 if (!(p
= lock_user_string(arg1
)))
4278 ret
= get_errno(execve(p
, argp
, envp
));
4279 unlock_user(p
, arg1
, 0);
4284 ret
= -TARGET_EFAULT
;
4287 for (gp
= guest_argp
, q
= argp
; *q
;
4288 gp
+= sizeof(abi_ulong
), q
++) {
4289 if (get_user_ual(addr
, gp
)
4292 unlock_user(*q
, addr
, 0);
4294 for (gp
= guest_envp
, q
= envp
; *q
;
4295 gp
+= sizeof(abi_ulong
), q
++) {
4296 if (get_user_ual(addr
, gp
)
4299 unlock_user(*q
, addr
, 0);
4303 case TARGET_NR_chdir
:
4304 if (!(p
= lock_user_string(arg1
)))
4306 ret
= get_errno(chdir(p
));
4307 unlock_user(p
, arg1
, 0);
4309 #ifdef TARGET_NR_time
4310 case TARGET_NR_time
:
4313 ret
= get_errno(time(&host_time
));
4316 && put_user_sal(host_time
, arg1
))
4321 case TARGET_NR_mknod
:
4322 if (!(p
= lock_user_string(arg1
)))
4324 ret
= get_errno(mknod(p
, arg2
, arg3
));
4325 unlock_user(p
, arg1
, 0);
4327 #if defined(TARGET_NR_mknodat) && defined(__NR_mknodat)
4328 case TARGET_NR_mknodat
:
4329 if (!(p
= lock_user_string(arg2
)))
4331 ret
= get_errno(sys_mknodat(arg1
, p
, arg3
, arg4
));
4332 unlock_user(p
, arg2
, 0);
4335 case TARGET_NR_chmod
:
4336 if (!(p
= lock_user_string(arg1
)))
4338 ret
= get_errno(chmod(p
, arg2
));
4339 unlock_user(p
, arg1
, 0);
4341 #ifdef TARGET_NR_break
4342 case TARGET_NR_break
:
4345 #ifdef TARGET_NR_oldstat
4346 case TARGET_NR_oldstat
:
4349 case TARGET_NR_lseek
:
4350 ret
= get_errno(lseek(arg1
, arg2
, arg3
));
4352 #ifdef TARGET_NR_getxpid
4353 case TARGET_NR_getxpid
:
4355 case TARGET_NR_getpid
:
4357 ret
= get_errno(getpid());
4359 case TARGET_NR_mount
:
4361 /* need to look at the data field */
4363 p
= lock_user_string(arg1
);
4364 p2
= lock_user_string(arg2
);
4365 p3
= lock_user_string(arg3
);
4366 if (!p
|| !p2
|| !p3
)
4367 ret
= -TARGET_EFAULT
;
4369 /* FIXME - arg5 should be locked, but it isn't clear how to
4370 * do that since it's not guaranteed to be a NULL-terminated
4373 ret
= get_errno(mount(p
, p2
, p3
, (unsigned long)arg4
, g2h(arg5
)));
4374 unlock_user(p
, arg1
, 0);
4375 unlock_user(p2
, arg2
, 0);
4376 unlock_user(p3
, arg3
, 0);
4379 #ifdef TARGET_NR_umount
4380 case TARGET_NR_umount
:
4381 if (!(p
= lock_user_string(arg1
)))
4383 ret
= get_errno(umount(p
));
4384 unlock_user(p
, arg1
, 0);
4387 #ifdef TARGET_NR_stime /* not on alpha */
4388 case TARGET_NR_stime
:
4391 if (get_user_sal(host_time
, arg1
))
4393 ret
= get_errno(stime(&host_time
));
4397 case TARGET_NR_ptrace
:
4399 #ifdef TARGET_NR_alarm /* not on alpha */
4400 case TARGET_NR_alarm
:
4404 #ifdef TARGET_NR_oldfstat
4405 case TARGET_NR_oldfstat
:
4408 #ifdef TARGET_NR_pause /* not on alpha */
4409 case TARGET_NR_pause
:
4410 ret
= get_errno(pause());
4413 #ifdef TARGET_NR_utime
4414 case TARGET_NR_utime
:
4416 struct utimbuf tbuf
, *host_tbuf
;
4417 struct target_utimbuf
*target_tbuf
;
4419 if (!lock_user_struct(VERIFY_READ
, target_tbuf
, arg2
, 1))
4421 tbuf
.actime
= tswapl(target_tbuf
->actime
);
4422 tbuf
.modtime
= tswapl(target_tbuf
->modtime
);
4423 unlock_user_struct(target_tbuf
, arg2
, 0);
4428 if (!(p
= lock_user_string(arg1
)))
4430 ret
= get_errno(utime(p
, host_tbuf
));
4431 unlock_user(p
, arg1
, 0);
4435 case TARGET_NR_utimes
:
4437 struct timeval
*tvp
, tv
[2];
4439 if (copy_from_user_timeval(&tv
[0], arg2
)
4440 || copy_from_user_timeval(&tv
[1],
4441 arg2
+ sizeof(struct target_timeval
)))
4447 if (!(p
= lock_user_string(arg1
)))
4449 ret
= get_errno(utimes(p
, tvp
));
4450 unlock_user(p
, arg1
, 0);
4453 #if defined(TARGET_NR_futimesat) && defined(__NR_futimesat)
4454 case TARGET_NR_futimesat
:
4456 struct timeval
*tvp
, tv
[2];
4458 if (copy_from_user_timeval(&tv
[0], arg3
)
4459 || copy_from_user_timeval(&tv
[1],
4460 arg3
+ sizeof(struct target_timeval
)))
4466 if (!(p
= lock_user_string(arg2
)))
4468 ret
= get_errno(sys_futimesat(arg1
, path(p
), tvp
));
4469 unlock_user(p
, arg2
, 0);
4473 #ifdef TARGET_NR_stty
4474 case TARGET_NR_stty
:
4477 #ifdef TARGET_NR_gtty
4478 case TARGET_NR_gtty
:
4481 case TARGET_NR_access
:
4482 if (!(p
= lock_user_string(arg1
)))
4484 ret
= get_errno(access(p
, arg2
));
4485 unlock_user(p
, arg1
, 0);
4487 #if defined(TARGET_NR_faccessat) && defined(__NR_faccessat)
4488 case TARGET_NR_faccessat
:
4489 if (!(p
= lock_user_string(arg2
)))
4491 ret
= get_errno(sys_faccessat(arg1
, p
, arg3
));
4492 unlock_user(p
, arg2
, 0);
4495 #ifdef TARGET_NR_nice /* not on alpha */
4496 case TARGET_NR_nice
:
4497 ret
= get_errno(nice(arg1
));
4500 #ifdef TARGET_NR_ftime
4501 case TARGET_NR_ftime
:
4504 case TARGET_NR_sync
:
4508 case TARGET_NR_kill
:
4509 ret
= get_errno(kill(arg1
, target_to_host_signal(arg2
)));
4511 case TARGET_NR_rename
:
4514 p
= lock_user_string(arg1
);
4515 p2
= lock_user_string(arg2
);
4517 ret
= -TARGET_EFAULT
;
4519 ret
= get_errno(rename(p
, p2
));
4520 unlock_user(p2
, arg2
, 0);
4521 unlock_user(p
, arg1
, 0);
4524 #if defined(TARGET_NR_renameat) && defined(__NR_renameat)
4525 case TARGET_NR_renameat
:
4528 p
= lock_user_string(arg2
);
4529 p2
= lock_user_string(arg4
);
4531 ret
= -TARGET_EFAULT
;
4533 ret
= get_errno(sys_renameat(arg1
, p
, arg3
, p2
));
4534 unlock_user(p2
, arg4
, 0);
4535 unlock_user(p
, arg2
, 0);
4539 case TARGET_NR_mkdir
:
4540 if (!(p
= lock_user_string(arg1
)))
4542 ret
= get_errno(mkdir(p
, arg2
));
4543 unlock_user(p
, arg1
, 0);
4545 #if defined(TARGET_NR_mkdirat) && defined(__NR_mkdirat)
4546 case TARGET_NR_mkdirat
:
4547 if (!(p
= lock_user_string(arg2
)))
4549 ret
= get_errno(sys_mkdirat(arg1
, p
, arg3
));
4550 unlock_user(p
, arg2
, 0);
4553 case TARGET_NR_rmdir
:
4554 if (!(p
= lock_user_string(arg1
)))
4556 ret
= get_errno(rmdir(p
));
4557 unlock_user(p
, arg1
, 0);
4560 ret
= get_errno(dup(arg1
));
4562 case TARGET_NR_pipe
:
4563 ret
= do_pipe(cpu_env
, arg1
, 0);
4565 #ifdef TARGET_NR_pipe2
4566 case TARGET_NR_pipe2
:
4567 ret
= do_pipe(cpu_env
, arg1
, arg2
);
4570 case TARGET_NR_times
:
4572 struct target_tms
*tmsp
;
4574 ret
= get_errno(times(&tms
));
4576 tmsp
= lock_user(VERIFY_WRITE
, arg1
, sizeof(struct target_tms
), 0);
4579 tmsp
->tms_utime
= tswapl(host_to_target_clock_t(tms
.tms_utime
));
4580 tmsp
->tms_stime
= tswapl(host_to_target_clock_t(tms
.tms_stime
));
4581 tmsp
->tms_cutime
= tswapl(host_to_target_clock_t(tms
.tms_cutime
));
4582 tmsp
->tms_cstime
= tswapl(host_to_target_clock_t(tms
.tms_cstime
));
4585 ret
= host_to_target_clock_t(ret
);
4588 #ifdef TARGET_NR_prof
4589 case TARGET_NR_prof
:
4592 #ifdef TARGET_NR_signal
4593 case TARGET_NR_signal
:
4596 case TARGET_NR_acct
:
4598 ret
= get_errno(acct(NULL
));
4600 if (!(p
= lock_user_string(arg1
)))
4602 ret
= get_errno(acct(path(p
)));
4603 unlock_user(p
, arg1
, 0);
4606 #ifdef TARGET_NR_umount2 /* not on alpha */
4607 case TARGET_NR_umount2
:
4608 if (!(p
= lock_user_string(arg1
)))
4610 ret
= get_errno(umount2(p
, arg2
));
4611 unlock_user(p
, arg1
, 0);
4614 #ifdef TARGET_NR_lock
4615 case TARGET_NR_lock
:
4618 case TARGET_NR_ioctl
:
4619 ret
= do_ioctl(arg1
, arg2
, arg3
);
4621 case TARGET_NR_fcntl
:
4622 ret
= do_fcntl(arg1
, arg2
, arg3
);
4624 #ifdef TARGET_NR_mpx
4628 case TARGET_NR_setpgid
:
4629 ret
= get_errno(setpgid(arg1
, arg2
));
4631 #ifdef TARGET_NR_ulimit
4632 case TARGET_NR_ulimit
:
4635 #ifdef TARGET_NR_oldolduname
4636 case TARGET_NR_oldolduname
:
4639 case TARGET_NR_umask
:
4640 ret
= get_errno(umask(arg1
));
4642 case TARGET_NR_chroot
:
4643 if (!(p
= lock_user_string(arg1
)))
4645 ret
= get_errno(chroot(p
));
4646 unlock_user(p
, arg1
, 0);
4648 case TARGET_NR_ustat
:
4650 case TARGET_NR_dup2
:
4651 ret
= get_errno(dup2(arg1
, arg2
));
4653 #ifdef TARGET_NR_getppid /* not on alpha */
4654 case TARGET_NR_getppid
:
4655 ret
= get_errno(getppid());
4658 case TARGET_NR_getpgrp
:
4659 ret
= get_errno(getpgrp());
4661 case TARGET_NR_setsid
:
4662 ret
= get_errno(setsid());
4664 #ifdef TARGET_NR_sigaction
4665 case TARGET_NR_sigaction
:
4667 #if !defined(TARGET_MIPS)
4668 struct target_old_sigaction
*old_act
;
4669 struct target_sigaction act
, oact
, *pact
;
4671 if (!lock_user_struct(VERIFY_READ
, old_act
, arg2
, 1))
4673 act
._sa_handler
= old_act
->_sa_handler
;
4674 target_siginitset(&act
.sa_mask
, old_act
->sa_mask
);
4675 act
.sa_flags
= old_act
->sa_flags
;
4676 act
.sa_restorer
= old_act
->sa_restorer
;
4677 unlock_user_struct(old_act
, arg2
, 0);
4682 ret
= get_errno(do_sigaction(arg1
, pact
, &oact
));
4683 if (!is_error(ret
) && arg3
) {
4684 if (!lock_user_struct(VERIFY_WRITE
, old_act
, arg3
, 0))
4686 old_act
->_sa_handler
= oact
._sa_handler
;
4687 old_act
->sa_mask
= oact
.sa_mask
.sig
[0];
4688 old_act
->sa_flags
= oact
.sa_flags
;
4689 old_act
->sa_restorer
= oact
.sa_restorer
;
4690 unlock_user_struct(old_act
, arg3
, 1);
4693 struct target_sigaction act
, oact
, *pact
, *old_act
;
4696 if (!lock_user_struct(VERIFY_READ
, old_act
, arg2
, 1))
4698 act
._sa_handler
= old_act
->_sa_handler
;
4699 target_siginitset(&act
.sa_mask
, old_act
->sa_mask
.sig
[0]);
4700 act
.sa_flags
= old_act
->sa_flags
;
4701 unlock_user_struct(old_act
, arg2
, 0);
4707 ret
= get_errno(do_sigaction(arg1
, pact
, &oact
));
4709 if (!is_error(ret
) && arg3
) {
4710 if (!lock_user_struct(VERIFY_WRITE
, old_act
, arg3
, 0))
4712 old_act
->_sa_handler
= oact
._sa_handler
;
4713 old_act
->sa_flags
= oact
.sa_flags
;
4714 old_act
->sa_mask
.sig
[0] = oact
.sa_mask
.sig
[0];
4715 old_act
->sa_mask
.sig
[1] = 0;
4716 old_act
->sa_mask
.sig
[2] = 0;
4717 old_act
->sa_mask
.sig
[3] = 0;
4718 unlock_user_struct(old_act
, arg3
, 1);
4724 case TARGET_NR_rt_sigaction
:
4726 struct target_sigaction
*act
;
4727 struct target_sigaction
*oact
;
4730 if (!lock_user_struct(VERIFY_READ
, act
, arg2
, 1))
4735 if (!lock_user_struct(VERIFY_WRITE
, oact
, arg3
, 0)) {
4736 ret
= -TARGET_EFAULT
;
4737 goto rt_sigaction_fail
;
4741 ret
= get_errno(do_sigaction(arg1
, act
, oact
));
4744 unlock_user_struct(act
, arg2
, 0);
4746 unlock_user_struct(oact
, arg3
, 1);
4749 #ifdef TARGET_NR_sgetmask /* not on alpha */
4750 case TARGET_NR_sgetmask
:
4753 abi_ulong target_set
;
4754 sigprocmask(0, NULL
, &cur_set
);
4755 host_to_target_old_sigset(&target_set
, &cur_set
);
4760 #ifdef TARGET_NR_ssetmask /* not on alpha */
4761 case TARGET_NR_ssetmask
:
4763 sigset_t set
, oset
, cur_set
;
4764 abi_ulong target_set
= arg1
;
4765 sigprocmask(0, NULL
, &cur_set
);
4766 target_to_host_old_sigset(&set
, &target_set
);
4767 sigorset(&set
, &set
, &cur_set
);
4768 sigprocmask(SIG_SETMASK
, &set
, &oset
);
4769 host_to_target_old_sigset(&target_set
, &oset
);
4774 #ifdef TARGET_NR_sigprocmask
4775 case TARGET_NR_sigprocmask
:
4778 sigset_t set
, oldset
, *set_ptr
;
4782 case TARGET_SIG_BLOCK
:
4785 case TARGET_SIG_UNBLOCK
:
4788 case TARGET_SIG_SETMASK
:
4792 ret
= -TARGET_EINVAL
;
4795 if (!(p
= lock_user(VERIFY_READ
, arg2
, sizeof(target_sigset_t
), 1)))
4797 target_to_host_old_sigset(&set
, p
);
4798 unlock_user(p
, arg2
, 0);
4804 ret
= get_errno(sigprocmask(arg1
, set_ptr
, &oldset
));
4805 if (!is_error(ret
) && arg3
) {
4806 if (!(p
= lock_user(VERIFY_WRITE
, arg3
, sizeof(target_sigset_t
), 0)))
4808 host_to_target_old_sigset(p
, &oldset
);
4809 unlock_user(p
, arg3
, sizeof(target_sigset_t
));
4814 case TARGET_NR_rt_sigprocmask
:
4817 sigset_t set
, oldset
, *set_ptr
;
4821 case TARGET_SIG_BLOCK
:
4824 case TARGET_SIG_UNBLOCK
:
4827 case TARGET_SIG_SETMASK
:
4831 ret
= -TARGET_EINVAL
;
4834 if (!(p
= lock_user(VERIFY_READ
, arg2
, sizeof(target_sigset_t
), 1)))
4836 target_to_host_sigset(&set
, p
);
4837 unlock_user(p
, arg2
, 0);
4843 ret
= get_errno(sigprocmask(how
, set_ptr
, &oldset
));
4844 if (!is_error(ret
) && arg3
) {
4845 if (!(p
= lock_user(VERIFY_WRITE
, arg3
, sizeof(target_sigset_t
), 0)))
4847 host_to_target_sigset(p
, &oldset
);
4848 unlock_user(p
, arg3
, sizeof(target_sigset_t
));
4852 #ifdef TARGET_NR_sigpending
4853 case TARGET_NR_sigpending
:
4856 ret
= get_errno(sigpending(&set
));
4857 if (!is_error(ret
)) {
4858 if (!(p
= lock_user(VERIFY_WRITE
, arg1
, sizeof(target_sigset_t
), 0)))
4860 host_to_target_old_sigset(p
, &set
);
4861 unlock_user(p
, arg1
, sizeof(target_sigset_t
));
4866 case TARGET_NR_rt_sigpending
:
4869 ret
= get_errno(sigpending(&set
));
4870 if (!is_error(ret
)) {
4871 if (!(p
= lock_user(VERIFY_WRITE
, arg1
, sizeof(target_sigset_t
), 0)))
4873 host_to_target_sigset(p
, &set
);
4874 unlock_user(p
, arg1
, sizeof(target_sigset_t
));
4878 #ifdef TARGET_NR_sigsuspend
4879 case TARGET_NR_sigsuspend
:
4882 if (!(p
= lock_user(VERIFY_READ
, arg1
, sizeof(target_sigset_t
), 1)))
4884 target_to_host_old_sigset(&set
, p
);
4885 unlock_user(p
, arg1
, 0);
4886 ret
= get_errno(sigsuspend(&set
));
4890 case TARGET_NR_rt_sigsuspend
:
4893 if (!(p
= lock_user(VERIFY_READ
, arg1
, sizeof(target_sigset_t
), 1)))
4895 target_to_host_sigset(&set
, p
);
4896 unlock_user(p
, arg1
, 0);
4897 ret
= get_errno(sigsuspend(&set
));
4900 case TARGET_NR_rt_sigtimedwait
:
4903 struct timespec uts
, *puts
;
4906 if (!(p
= lock_user(VERIFY_READ
, arg1
, sizeof(target_sigset_t
), 1)))
4908 target_to_host_sigset(&set
, p
);
4909 unlock_user(p
, arg1
, 0);
4912 target_to_host_timespec(puts
, arg3
);
4916 ret
= get_errno(sigtimedwait(&set
, &uinfo
, puts
));
4917 if (!is_error(ret
) && arg2
) {
4918 if (!(p
= lock_user(VERIFY_WRITE
, arg2
, sizeof(target_siginfo_t
), 0)))
4920 host_to_target_siginfo(p
, &uinfo
);
4921 unlock_user(p
, arg2
, sizeof(target_siginfo_t
));
4925 case TARGET_NR_rt_sigqueueinfo
:
4928 if (!(p
= lock_user(VERIFY_READ
, arg3
, sizeof(target_sigset_t
), 1)))
4930 target_to_host_siginfo(&uinfo
, p
);
4931 unlock_user(p
, arg1
, 0);
4932 ret
= get_errno(sys_rt_sigqueueinfo(arg1
, arg2
, &uinfo
));
4935 #ifdef TARGET_NR_sigreturn
4936 case TARGET_NR_sigreturn
:
4937 /* NOTE: ret is eax, so not transcoding must be done */
4938 ret
= do_sigreturn(cpu_env
);
4941 case TARGET_NR_rt_sigreturn
:
4942 /* NOTE: ret is eax, so not transcoding must be done */
4943 ret
= do_rt_sigreturn(cpu_env
);
4945 case TARGET_NR_sethostname
:
4946 if (!(p
= lock_user_string(arg1
)))
4948 ret
= get_errno(sethostname(p
, arg2
));
4949 unlock_user(p
, arg1
, 0);
4951 case TARGET_NR_setrlimit
:
4953 /* XXX: convert resource ? */
4954 int resource
= arg1
;
4955 struct target_rlimit
*target_rlim
;
4957 if (!lock_user_struct(VERIFY_READ
, target_rlim
, arg2
, 1))
4959 rlim
.rlim_cur
= tswapl(target_rlim
->rlim_cur
);
4960 rlim
.rlim_max
= tswapl(target_rlim
->rlim_max
);
4961 unlock_user_struct(target_rlim
, arg2
, 0);
4962 ret
= get_errno(setrlimit(resource
, &rlim
));
4965 case TARGET_NR_getrlimit
:
4967 /* XXX: convert resource ? */
4968 int resource
= arg1
;
4969 struct target_rlimit
*target_rlim
;
4972 ret
= get_errno(getrlimit(resource
, &rlim
));
4973 if (!is_error(ret
)) {
4974 if (!lock_user_struct(VERIFY_WRITE
, target_rlim
, arg2
, 0))
4976 rlim
.rlim_cur
= tswapl(target_rlim
->rlim_cur
);
4977 rlim
.rlim_max
= tswapl(target_rlim
->rlim_max
);
4978 unlock_user_struct(target_rlim
, arg2
, 1);
4982 case TARGET_NR_getrusage
:
4984 struct rusage rusage
;
4985 ret
= get_errno(getrusage(arg1
, &rusage
));
4986 if (!is_error(ret
)) {
4987 host_to_target_rusage(arg2
, &rusage
);
4991 case TARGET_NR_gettimeofday
:
4994 ret
= get_errno(gettimeofday(&tv
, NULL
));
4995 if (!is_error(ret
)) {
4996 if (copy_to_user_timeval(arg1
, &tv
))
5001 case TARGET_NR_settimeofday
:
5004 if (copy_from_user_timeval(&tv
, arg1
))
5006 ret
= get_errno(settimeofday(&tv
, NULL
));
5009 #ifdef TARGET_NR_select
5010 case TARGET_NR_select
:
5012 struct target_sel_arg_struct
*sel
;
5013 abi_ulong inp
, outp
, exp
, tvp
;
5016 if (!lock_user_struct(VERIFY_READ
, sel
, arg1
, 1))
5018 nsel
= tswapl(sel
->n
);
5019 inp
= tswapl(sel
->inp
);
5020 outp
= tswapl(sel
->outp
);
5021 exp
= tswapl(sel
->exp
);
5022 tvp
= tswapl(sel
->tvp
);
5023 unlock_user_struct(sel
, arg1
, 0);
5024 ret
= do_select(nsel
, inp
, outp
, exp
, tvp
);
5028 case TARGET_NR_symlink
:
5031 p
= lock_user_string(arg1
);
5032 p2
= lock_user_string(arg2
);
5034 ret
= -TARGET_EFAULT
;
5036 ret
= get_errno(symlink(p
, p2
));
5037 unlock_user(p2
, arg2
, 0);
5038 unlock_user(p
, arg1
, 0);
5041 #if defined(TARGET_NR_symlinkat) && defined(__NR_symlinkat)
5042 case TARGET_NR_symlinkat
:
5045 p
= lock_user_string(arg1
);
5046 p2
= lock_user_string(arg3
);
5048 ret
= -TARGET_EFAULT
;
5050 ret
= get_errno(sys_symlinkat(p
, arg2
, p2
));
5051 unlock_user(p2
, arg3
, 0);
5052 unlock_user(p
, arg1
, 0);
5056 #ifdef TARGET_NR_oldlstat
5057 case TARGET_NR_oldlstat
:
5060 case TARGET_NR_readlink
:
5063 p
= lock_user_string(arg1
);
5064 p2
= lock_user(VERIFY_WRITE
, arg2
, arg3
, 0);
5066 ret
= -TARGET_EFAULT
;
5068 if (strncmp((const char *)p
, "/proc/self/exe", 14) == 0) {
5069 char real
[PATH_MAX
];
5070 temp
= realpath(exec_path
,real
);
5071 ret
= (temp
==NULL
) ? get_errno(-1) : strlen(real
) ;
5072 snprintf((char *)p2
, arg3
, "%s", real
);
5075 ret
= get_errno(readlink(path(p
), p2
, arg3
));
5077 unlock_user(p2
, arg2
, ret
);
5078 unlock_user(p
, arg1
, 0);
5081 #if defined(TARGET_NR_readlinkat) && defined(__NR_readlinkat)
5082 case TARGET_NR_readlinkat
:
5085 p
= lock_user_string(arg2
);
5086 p2
= lock_user(VERIFY_WRITE
, arg3
, arg4
, 0);
5088 ret
= -TARGET_EFAULT
;
5090 ret
= get_errno(sys_readlinkat(arg1
, path(p
), p2
, arg4
));
5091 unlock_user(p2
, arg3
, ret
);
5092 unlock_user(p
, arg2
, 0);
5096 #ifdef TARGET_NR_uselib
5097 case TARGET_NR_uselib
:
5100 #ifdef TARGET_NR_swapon
5101 case TARGET_NR_swapon
:
5102 if (!(p
= lock_user_string(arg1
)))
5104 ret
= get_errno(swapon(p
, arg2
));
5105 unlock_user(p
, arg1
, 0);
5108 case TARGET_NR_reboot
:
5110 #ifdef TARGET_NR_readdir
5111 case TARGET_NR_readdir
:
5114 #ifdef TARGET_NR_mmap
5115 case TARGET_NR_mmap
:
5116 #if (defined(TARGET_I386) && defined(TARGET_ABI32)) || defined(TARGET_ARM) || defined(TARGET_M68K) || defined(TARGET_CRIS) || defined(TARGET_MICROBLAZE)
5119 abi_ulong v1
, v2
, v3
, v4
, v5
, v6
;
5120 if (!(v
= lock_user(VERIFY_READ
, arg1
, 6 * sizeof(abi_ulong
), 1)))
5128 unlock_user(v
, arg1
, 0);
5129 ret
= get_errno(target_mmap(v1
, v2
, v3
,
5130 target_to_host_bitmask(v4
, mmap_flags_tbl
),
5134 ret
= get_errno(target_mmap(arg1
, arg2
, arg3
,
5135 target_to_host_bitmask(arg4
, mmap_flags_tbl
),
5141 #ifdef TARGET_NR_mmap2
5142 case TARGET_NR_mmap2
:
5144 #define MMAP_SHIFT 12
5146 ret
= get_errno(target_mmap(arg1
, arg2
, arg3
,
5147 target_to_host_bitmask(arg4
, mmap_flags_tbl
),
5149 arg6
<< MMAP_SHIFT
));
5152 case TARGET_NR_munmap
:
5153 ret
= get_errno(target_munmap(arg1
, arg2
));
5155 case TARGET_NR_mprotect
:
5156 ret
= get_errno(target_mprotect(arg1
, arg2
, arg3
));
5158 #ifdef TARGET_NR_mremap
5159 case TARGET_NR_mremap
:
5160 ret
= get_errno(target_mremap(arg1
, arg2
, arg3
, arg4
, arg5
));
5163 /* ??? msync/mlock/munlock are broken for softmmu. */
5164 #ifdef TARGET_NR_msync
5165 case TARGET_NR_msync
:
5166 ret
= get_errno(msync(g2h(arg1
), arg2
, arg3
));
5169 #ifdef TARGET_NR_mlock
5170 case TARGET_NR_mlock
:
5171 ret
= get_errno(mlock(g2h(arg1
), arg2
));
5174 #ifdef TARGET_NR_munlock
5175 case TARGET_NR_munlock
:
5176 ret
= get_errno(munlock(g2h(arg1
), arg2
));
5179 #ifdef TARGET_NR_mlockall
5180 case TARGET_NR_mlockall
:
5181 ret
= get_errno(mlockall(arg1
));
5184 #ifdef TARGET_NR_munlockall
5185 case TARGET_NR_munlockall
:
5186 ret
= get_errno(munlockall());
5189 case TARGET_NR_truncate
:
5190 if (!(p
= lock_user_string(arg1
)))
5192 ret
= get_errno(truncate(p
, arg2
));
5193 unlock_user(p
, arg1
, 0);
5195 case TARGET_NR_ftruncate
:
5196 ret
= get_errno(ftruncate(arg1
, arg2
));
5198 case TARGET_NR_fchmod
:
5199 ret
= get_errno(fchmod(arg1
, arg2
));
5201 #if defined(TARGET_NR_fchmodat) && defined(__NR_fchmodat)
5202 case TARGET_NR_fchmodat
:
5203 if (!(p
= lock_user_string(arg2
)))
5205 ret
= get_errno(sys_fchmodat(arg1
, p
, arg3
));
5206 unlock_user(p
, arg2
, 0);
5209 case TARGET_NR_getpriority
:
5210 /* libc does special remapping of the return value of
5211 * sys_getpriority() so it's just easiest to call
5212 * sys_getpriority() directly rather than through libc. */
5213 ret
= sys_getpriority(arg1
, arg2
);
5215 case TARGET_NR_setpriority
:
5216 ret
= get_errno(setpriority(arg1
, arg2
, arg3
));
5218 #ifdef TARGET_NR_profil
5219 case TARGET_NR_profil
:
5222 case TARGET_NR_statfs
:
5223 if (!(p
= lock_user_string(arg1
)))
5225 ret
= get_errno(statfs(path(p
), &stfs
));
5226 unlock_user(p
, arg1
, 0);
5228 if (!is_error(ret
)) {
5229 struct target_statfs
*target_stfs
;
5231 if (!lock_user_struct(VERIFY_WRITE
, target_stfs
, arg2
, 0))
5233 __put_user(stfs
.f_type
, &target_stfs
->f_type
);
5234 __put_user(stfs
.f_bsize
, &target_stfs
->f_bsize
);
5235 __put_user(stfs
.f_blocks
, &target_stfs
->f_blocks
);
5236 __put_user(stfs
.f_bfree
, &target_stfs
->f_bfree
);
5237 __put_user(stfs
.f_bavail
, &target_stfs
->f_bavail
);
5238 __put_user(stfs
.f_files
, &target_stfs
->f_files
);
5239 __put_user(stfs
.f_ffree
, &target_stfs
->f_ffree
);
5240 __put_user(stfs
.f_fsid
.__val
[0], &target_stfs
->f_fsid
.val
[0]);
5241 __put_user(stfs
.f_fsid
.__val
[1], &target_stfs
->f_fsid
.val
[1]);
5242 __put_user(stfs
.f_namelen
, &target_stfs
->f_namelen
);
5243 unlock_user_struct(target_stfs
, arg2
, 1);
5246 case TARGET_NR_fstatfs
:
5247 ret
= get_errno(fstatfs(arg1
, &stfs
));
5248 goto convert_statfs
;
5249 #ifdef TARGET_NR_statfs64
5250 case TARGET_NR_statfs64
:
5251 if (!(p
= lock_user_string(arg1
)))
5253 ret
= get_errno(statfs(path(p
), &stfs
));
5254 unlock_user(p
, arg1
, 0);
5256 if (!is_error(ret
)) {
5257 struct target_statfs64
*target_stfs
;
5259 if (!lock_user_struct(VERIFY_WRITE
, target_stfs
, arg3
, 0))
5261 __put_user(stfs
.f_type
, &target_stfs
->f_type
);
5262 __put_user(stfs
.f_bsize
, &target_stfs
->f_bsize
);
5263 __put_user(stfs
.f_blocks
, &target_stfs
->f_blocks
);
5264 __put_user(stfs
.f_bfree
, &target_stfs
->f_bfree
);
5265 __put_user(stfs
.f_bavail
, &target_stfs
->f_bavail
);
5266 __put_user(stfs
.f_files
, &target_stfs
->f_files
);
5267 __put_user(stfs
.f_ffree
, &target_stfs
->f_ffree
);
5268 __put_user(stfs
.f_fsid
.__val
[0], &target_stfs
->f_fsid
.val
[0]);
5269 __put_user(stfs
.f_fsid
.__val
[1], &target_stfs
->f_fsid
.val
[1]);
5270 __put_user(stfs
.f_namelen
, &target_stfs
->f_namelen
);
5271 unlock_user_struct(target_stfs
, arg3
, 1);
5274 case TARGET_NR_fstatfs64
:
5275 ret
= get_errno(fstatfs(arg1
, &stfs
));
5276 goto convert_statfs64
;
5278 #ifdef TARGET_NR_ioperm
5279 case TARGET_NR_ioperm
:
5282 #ifdef TARGET_NR_socketcall
5283 case TARGET_NR_socketcall
:
5284 ret
= do_socketcall(arg1
, arg2
);
5287 #ifdef TARGET_NR_accept
5288 case TARGET_NR_accept
:
5289 ret
= do_accept(arg1
, arg2
, arg3
);
5292 #ifdef TARGET_NR_bind
5293 case TARGET_NR_bind
:
5294 ret
= do_bind(arg1
, arg2
, arg3
);
5297 #ifdef TARGET_NR_connect
5298 case TARGET_NR_connect
:
5299 ret
= do_connect(arg1
, arg2
, arg3
);
5302 #ifdef TARGET_NR_getpeername
5303 case TARGET_NR_getpeername
:
5304 ret
= do_getpeername(arg1
, arg2
, arg3
);
5307 #ifdef TARGET_NR_getsockname
5308 case TARGET_NR_getsockname
:
5309 ret
= do_getsockname(arg1
, arg2
, arg3
);
5312 #ifdef TARGET_NR_getsockopt
5313 case TARGET_NR_getsockopt
:
5314 ret
= do_getsockopt(arg1
, arg2
, arg3
, arg4
, arg5
);
5317 #ifdef TARGET_NR_listen
5318 case TARGET_NR_listen
:
5319 ret
= get_errno(listen(arg1
, arg2
));
5322 #ifdef TARGET_NR_recv
5323 case TARGET_NR_recv
:
5324 ret
= do_recvfrom(arg1
, arg2
, arg3
, arg4
, 0, 0);
5327 #ifdef TARGET_NR_recvfrom
5328 case TARGET_NR_recvfrom
:
5329 ret
= do_recvfrom(arg1
, arg2
, arg3
, arg4
, arg5
, arg6
);
5332 #ifdef TARGET_NR_recvmsg
5333 case TARGET_NR_recvmsg
:
5334 ret
= do_sendrecvmsg(arg1
, arg2
, arg3
, 0);
5337 #ifdef TARGET_NR_send
5338 case TARGET_NR_send
:
5339 ret
= do_sendto(arg1
, arg2
, arg3
, arg4
, 0, 0);
5342 #ifdef TARGET_NR_sendmsg
5343 case TARGET_NR_sendmsg
:
5344 ret
= do_sendrecvmsg(arg1
, arg2
, arg3
, 1);
5347 #ifdef TARGET_NR_sendto
5348 case TARGET_NR_sendto
:
5349 ret
= do_sendto(arg1
, arg2
, arg3
, arg4
, arg5
, arg6
);
5352 #ifdef TARGET_NR_shutdown
5353 case TARGET_NR_shutdown
:
5354 ret
= get_errno(shutdown(arg1
, arg2
));
5357 #ifdef TARGET_NR_socket
5358 case TARGET_NR_socket
:
5359 ret
= do_socket(arg1
, arg2
, arg3
);
5362 #ifdef TARGET_NR_socketpair
5363 case TARGET_NR_socketpair
:
5364 ret
= do_socketpair(arg1
, arg2
, arg3
, arg4
);
5367 #ifdef TARGET_NR_setsockopt
5368 case TARGET_NR_setsockopt
:
5369 ret
= do_setsockopt(arg1
, arg2
, arg3
, arg4
, (socklen_t
) arg5
);
5373 case TARGET_NR_syslog
:
5374 if (!(p
= lock_user_string(arg2
)))
5376 ret
= get_errno(sys_syslog((int)arg1
, p
, (int)arg3
));
5377 unlock_user(p
, arg2
, 0);
5380 case TARGET_NR_setitimer
:
5382 struct itimerval value
, ovalue
, *pvalue
;
5386 if (copy_from_user_timeval(&pvalue
->it_interval
, arg2
)
5387 || copy_from_user_timeval(&pvalue
->it_value
,
5388 arg2
+ sizeof(struct target_timeval
)))
5393 ret
= get_errno(setitimer(arg1
, pvalue
, &ovalue
));
5394 if (!is_error(ret
) && arg3
) {
5395 if (copy_to_user_timeval(arg3
,
5396 &ovalue
.it_interval
)
5397 || copy_to_user_timeval(arg3
+ sizeof(struct target_timeval
),
5403 case TARGET_NR_getitimer
:
5405 struct itimerval value
;
5407 ret
= get_errno(getitimer(arg1
, &value
));
5408 if (!is_error(ret
) && arg2
) {
5409 if (copy_to_user_timeval(arg2
,
5411 || copy_to_user_timeval(arg2
+ sizeof(struct target_timeval
),
5417 case TARGET_NR_stat
:
5418 if (!(p
= lock_user_string(arg1
)))
5420 ret
= get_errno(stat(path(p
), &st
));
5421 unlock_user(p
, arg1
, 0);
5423 case TARGET_NR_lstat
:
5424 if (!(p
= lock_user_string(arg1
)))
5426 ret
= get_errno(lstat(path(p
), &st
));
5427 unlock_user(p
, arg1
, 0);
5429 case TARGET_NR_fstat
:
5431 ret
= get_errno(fstat(arg1
, &st
));
5433 if (!is_error(ret
)) {
5434 struct target_stat
*target_st
;
5436 if (!lock_user_struct(VERIFY_WRITE
, target_st
, arg2
, 0))
5438 __put_user(st
.st_dev
, &target_st
->st_dev
);
5439 __put_user(st
.st_ino
, &target_st
->st_ino
);
5440 __put_user(st
.st_mode
, &target_st
->st_mode
);
5441 __put_user(st
.st_uid
, &target_st
->st_uid
);
5442 __put_user(st
.st_gid
, &target_st
->st_gid
);
5443 __put_user(st
.st_nlink
, &target_st
->st_nlink
);
5444 __put_user(st
.st_rdev
, &target_st
->st_rdev
);
5445 __put_user(st
.st_size
, &target_st
->st_size
);
5446 __put_user(st
.st_blksize
, &target_st
->st_blksize
);
5447 __put_user(st
.st_blocks
, &target_st
->st_blocks
);
5448 __put_user(st
.st_atime
, &target_st
->target_st_atime
);
5449 __put_user(st
.st_mtime
, &target_st
->target_st_mtime
);
5450 __put_user(st
.st_ctime
, &target_st
->target_st_ctime
);
5451 unlock_user_struct(target_st
, arg2
, 1);
5455 #ifdef TARGET_NR_olduname
5456 case TARGET_NR_olduname
:
5459 #ifdef TARGET_NR_iopl
5460 case TARGET_NR_iopl
:
5463 case TARGET_NR_vhangup
:
5464 ret
= get_errno(vhangup());
5466 #ifdef TARGET_NR_idle
5467 case TARGET_NR_idle
:
5470 #ifdef TARGET_NR_syscall
5471 case TARGET_NR_syscall
:
5472 ret
= do_syscall(cpu_env
,arg1
& 0xffff,arg2
,arg3
,arg4
,arg5
,arg6
,0);
5475 case TARGET_NR_wait4
:
5478 abi_long status_ptr
= arg2
;
5479 struct rusage rusage
, *rusage_ptr
;
5480 abi_ulong target_rusage
= arg4
;
5482 rusage_ptr
= &rusage
;
5485 ret
= get_errno(wait4(arg1
, &status
, arg3
, rusage_ptr
));
5486 if (!is_error(ret
)) {
5488 status
= host_to_target_waitstatus(status
);
5489 if (put_user_s32(status
, status_ptr
))
5493 host_to_target_rusage(target_rusage
, &rusage
);
5497 #ifdef TARGET_NR_swapoff
5498 case TARGET_NR_swapoff
:
5499 if (!(p
= lock_user_string(arg1
)))
5501 ret
= get_errno(swapoff(p
));
5502 unlock_user(p
, arg1
, 0);
5505 case TARGET_NR_sysinfo
:
5507 struct target_sysinfo
*target_value
;
5508 struct sysinfo value
;
5509 ret
= get_errno(sysinfo(&value
));
5510 if (!is_error(ret
) && arg1
)
5512 if (!lock_user_struct(VERIFY_WRITE
, target_value
, arg1
, 0))
5514 __put_user(value
.uptime
, &target_value
->uptime
);
5515 __put_user(value
.loads
[0], &target_value
->loads
[0]);
5516 __put_user(value
.loads
[1], &target_value
->loads
[1]);
5517 __put_user(value
.loads
[2], &target_value
->loads
[2]);
5518 __put_user(value
.totalram
, &target_value
->totalram
);
5519 __put_user(value
.freeram
, &target_value
->freeram
);
5520 __put_user(value
.sharedram
, &target_value
->sharedram
);
5521 __put_user(value
.bufferram
, &target_value
->bufferram
);
5522 __put_user(value
.totalswap
, &target_value
->totalswap
);
5523 __put_user(value
.freeswap
, &target_value
->freeswap
);
5524 __put_user(value
.procs
, &target_value
->procs
);
5525 __put_user(value
.totalhigh
, &target_value
->totalhigh
);
5526 __put_user(value
.freehigh
, &target_value
->freehigh
);
5527 __put_user(value
.mem_unit
, &target_value
->mem_unit
);
5528 unlock_user_struct(target_value
, arg1
, 1);
5532 #ifdef TARGET_NR_ipc
5534 ret
= do_ipc(arg1
, arg2
, arg3
, arg4
, arg5
, arg6
);
5537 #ifdef TARGET_NR_semget
5538 case TARGET_NR_semget
:
5539 ret
= get_errno(semget(arg1
, arg2
, arg3
));
5542 #ifdef TARGET_NR_semop
5543 case TARGET_NR_semop
:
5544 ret
= get_errno(do_semop(arg1
, arg2
, arg3
));
5547 #ifdef TARGET_NR_semctl
5548 case TARGET_NR_semctl
:
5549 ret
= do_semctl(arg1
, arg2
, arg3
, (union target_semun
)(abi_ulong
)arg4
);
5552 #ifdef TARGET_NR_msgctl
5553 case TARGET_NR_msgctl
:
5554 ret
= do_msgctl(arg1
, arg2
, arg3
);
5557 #ifdef TARGET_NR_msgget
5558 case TARGET_NR_msgget
:
5559 ret
= get_errno(msgget(arg1
, arg2
));
5562 #ifdef TARGET_NR_msgrcv
5563 case TARGET_NR_msgrcv
:
5564 ret
= do_msgrcv(arg1
, arg2
, arg3
, arg4
, arg5
);
5567 #ifdef TARGET_NR_msgsnd
5568 case TARGET_NR_msgsnd
:
5569 ret
= do_msgsnd(arg1
, arg2
, arg3
, arg4
);
5572 #ifdef TARGET_NR_shmget
5573 case TARGET_NR_shmget
:
5574 ret
= get_errno(shmget(arg1
, arg2
, arg3
));
5577 #ifdef TARGET_NR_shmctl
5578 case TARGET_NR_shmctl
:
5579 ret
= do_shmctl(arg1
, arg2
, arg3
);
5582 #ifdef TARGET_NR_shmat
5583 case TARGET_NR_shmat
:
5584 ret
= do_shmat(arg1
, arg2
, arg3
);
5587 #ifdef TARGET_NR_shmdt
5588 case TARGET_NR_shmdt
:
5589 ret
= do_shmdt(arg1
);
5592 case TARGET_NR_fsync
:
5593 ret
= get_errno(fsync(arg1
));
5595 case TARGET_NR_clone
:
5596 #if defined(TARGET_SH4)
5597 ret
= get_errno(do_fork(cpu_env
, arg1
, arg2
, arg3
, arg5
, arg4
));
5598 #elif defined(TARGET_CRIS)
5599 ret
= get_errno(do_fork(cpu_env
, arg2
, arg1
, arg3
, arg4
, arg5
));
5601 ret
= get_errno(do_fork(cpu_env
, arg1
, arg2
, arg3
, arg4
, arg5
));
5604 #ifdef __NR_exit_group
5605 /* new thread calls */
5606 case TARGET_NR_exit_group
:
5610 gdb_exit(cpu_env
, arg1
);
5611 ret
= get_errno(exit_group(arg1
));
5614 case TARGET_NR_setdomainname
:
5615 if (!(p
= lock_user_string(arg1
)))
5617 ret
= get_errno(setdomainname(p
, arg2
));
5618 unlock_user(p
, arg1
, 0);
5620 case TARGET_NR_uname
:
5621 /* no need to transcode because we use the linux syscall */
5623 struct new_utsname
* buf
;
5625 if (!lock_user_struct(VERIFY_WRITE
, buf
, arg1
, 0))
5627 ret
= get_errno(sys_uname(buf
));
5628 if (!is_error(ret
)) {
5629 /* Overrite the native machine name with whatever is being
5631 strcpy (buf
->machine
, UNAME_MACHINE
);
5632 /* Allow the user to override the reported release. */
5633 if (qemu_uname_release
&& *qemu_uname_release
)
5634 strcpy (buf
->release
, qemu_uname_release
);
5636 unlock_user_struct(buf
, arg1
, 1);
5640 case TARGET_NR_modify_ldt
:
5641 ret
= do_modify_ldt(cpu_env
, arg1
, arg2
, arg3
);
5643 #if !defined(TARGET_X86_64)
5644 case TARGET_NR_vm86old
:
5646 case TARGET_NR_vm86
:
5647 ret
= do_vm86(cpu_env
, arg1
, arg2
);
5651 case TARGET_NR_adjtimex
:
5653 #ifdef TARGET_NR_create_module
5654 case TARGET_NR_create_module
:
5656 case TARGET_NR_init_module
:
5657 case TARGET_NR_delete_module
:
5658 #ifdef TARGET_NR_get_kernel_syms
5659 case TARGET_NR_get_kernel_syms
:
5662 case TARGET_NR_quotactl
:
5664 case TARGET_NR_getpgid
:
5665 ret
= get_errno(getpgid(arg1
));
5667 case TARGET_NR_fchdir
:
5668 ret
= get_errno(fchdir(arg1
));
5670 #ifdef TARGET_NR_bdflush /* not on x86_64 */
5671 case TARGET_NR_bdflush
:
5674 #ifdef TARGET_NR_sysfs
5675 case TARGET_NR_sysfs
:
5678 case TARGET_NR_personality
:
5679 ret
= get_errno(personality(arg1
));
5681 #ifdef TARGET_NR_afs_syscall
5682 case TARGET_NR_afs_syscall
:
5685 #ifdef TARGET_NR__llseek /* Not on alpha */
5686 case TARGET_NR__llseek
:
5688 #if defined (__x86_64__)
5689 ret
= get_errno(lseek(arg1
, ((uint64_t )arg2
<< 32) | arg3
, arg5
));
5690 if (put_user_s64(ret
, arg4
))
5694 ret
= get_errno(_llseek(arg1
, arg2
, arg3
, &res
, arg5
));
5695 if (put_user_s64(res
, arg4
))
5701 case TARGET_NR_getdents
:
5702 #if TARGET_ABI_BITS != 32
5704 #elif TARGET_ABI_BITS == 32 && HOST_LONG_BITS == 64
5706 struct target_dirent
*target_dirp
;
5707 struct linux_dirent
*dirp
;
5708 abi_long count
= arg3
;
5710 dirp
= malloc(count
);
5712 ret
= -TARGET_ENOMEM
;
5716 ret
= get_errno(sys_getdents(arg1
, dirp
, count
));
5717 if (!is_error(ret
)) {
5718 struct linux_dirent
*de
;
5719 struct target_dirent
*tde
;
5721 int reclen
, treclen
;
5722 int count1
, tnamelen
;
5726 if (!(target_dirp
= lock_user(VERIFY_WRITE
, arg2
, count
, 0)))
5730 reclen
= de
->d_reclen
;
5731 treclen
= reclen
- (2 * (sizeof(long) - sizeof(abi_long
)));
5732 tde
->d_reclen
= tswap16(treclen
);
5733 tde
->d_ino
= tswapl(de
->d_ino
);
5734 tde
->d_off
= tswapl(de
->d_off
);
5735 tnamelen
= treclen
- (2 * sizeof(abi_long
) + 2);
5738 /* XXX: may not be correct */
5739 pstrcpy(tde
->d_name
, tnamelen
, de
->d_name
);
5740 de
= (struct linux_dirent
*)((char *)de
+ reclen
);
5742 tde
= (struct target_dirent
*)((char *)tde
+ treclen
);
5746 unlock_user(target_dirp
, arg2
, ret
);
5752 struct linux_dirent
*dirp
;
5753 abi_long count
= arg3
;
5755 if (!(dirp
= lock_user(VERIFY_WRITE
, arg2
, count
, 0)))
5757 ret
= get_errno(sys_getdents(arg1
, dirp
, count
));
5758 if (!is_error(ret
)) {
5759 struct linux_dirent
*de
;
5764 reclen
= de
->d_reclen
;
5767 de
->d_reclen
= tswap16(reclen
);
5768 tswapls(&de
->d_ino
);
5769 tswapls(&de
->d_off
);
5770 de
= (struct linux_dirent
*)((char *)de
+ reclen
);
5774 unlock_user(dirp
, arg2
, ret
);
5778 #if defined(TARGET_NR_getdents64) && defined(__NR_getdents64)
5779 case TARGET_NR_getdents64
:
5781 struct linux_dirent64
*dirp
;
5782 abi_long count
= arg3
;
5783 if (!(dirp
= lock_user(VERIFY_WRITE
, arg2
, count
, 0)))
5785 ret
= get_errno(sys_getdents64(arg1
, dirp
, count
));
5786 if (!is_error(ret
)) {
5787 struct linux_dirent64
*de
;
5792 reclen
= de
->d_reclen
;
5795 de
->d_reclen
= tswap16(reclen
);
5796 tswap64s((uint64_t *)&de
->d_ino
);
5797 tswap64s((uint64_t *)&de
->d_off
);
5798 de
= (struct linux_dirent64
*)((char *)de
+ reclen
);
5802 unlock_user(dirp
, arg2
, ret
);
5805 #endif /* TARGET_NR_getdents64 */
5806 #ifdef TARGET_NR__newselect
5807 case TARGET_NR__newselect
:
5808 ret
= do_select(arg1
, arg2
, arg3
, arg4
, arg5
);
5811 #ifdef TARGET_NR_poll
5812 case TARGET_NR_poll
:
5814 struct target_pollfd
*target_pfd
;
5815 unsigned int nfds
= arg2
;
5820 target_pfd
= lock_user(VERIFY_WRITE
, arg1
, sizeof(struct target_pollfd
) * nfds
, 1);
5823 pfd
= alloca(sizeof(struct pollfd
) * nfds
);
5824 for(i
= 0; i
< nfds
; i
++) {
5825 pfd
[i
].fd
= tswap32(target_pfd
[i
].fd
);
5826 pfd
[i
].events
= tswap16(target_pfd
[i
].events
);
5828 ret
= get_errno(poll(pfd
, nfds
, timeout
));
5829 if (!is_error(ret
)) {
5830 for(i
= 0; i
< nfds
; i
++) {
5831 target_pfd
[i
].revents
= tswap16(pfd
[i
].revents
);
5833 ret
+= nfds
* (sizeof(struct target_pollfd
)
5834 - sizeof(struct pollfd
));
5836 unlock_user(target_pfd
, arg1
, ret
);
5840 case TARGET_NR_flock
:
5841 /* NOTE: the flock constant seems to be the same for every
5843 ret
= get_errno(flock(arg1
, arg2
));
5845 case TARGET_NR_readv
:
5850 vec
= alloca(count
* sizeof(struct iovec
));
5851 if (lock_iovec(VERIFY_WRITE
, vec
, arg2
, count
, 0) < 0)
5853 ret
= get_errno(readv(arg1
, vec
, count
));
5854 unlock_iovec(vec
, arg2
, count
, 1);
5857 case TARGET_NR_writev
:
5862 vec
= alloca(count
* sizeof(struct iovec
));
5863 if (lock_iovec(VERIFY_READ
, vec
, arg2
, count
, 1) < 0)
5865 ret
= get_errno(writev(arg1
, vec
, count
));
5866 unlock_iovec(vec
, arg2
, count
, 0);
5869 case TARGET_NR_getsid
:
5870 ret
= get_errno(getsid(arg1
));
5872 #if defined(TARGET_NR_fdatasync) /* Not on alpha (osf_datasync ?) */
5873 case TARGET_NR_fdatasync
:
5874 ret
= get_errno(fdatasync(arg1
));
5877 case TARGET_NR__sysctl
:
5878 /* We don't implement this, but ENOTDIR is always a safe
5880 ret
= -TARGET_ENOTDIR
;
5882 case TARGET_NR_sched_setparam
:
5884 struct sched_param
*target_schp
;
5885 struct sched_param schp
;
5887 if (!lock_user_struct(VERIFY_READ
, target_schp
, arg2
, 1))
5889 schp
.sched_priority
= tswap32(target_schp
->sched_priority
);
5890 unlock_user_struct(target_schp
, arg2
, 0);
5891 ret
= get_errno(sched_setparam(arg1
, &schp
));
5894 case TARGET_NR_sched_getparam
:
5896 struct sched_param
*target_schp
;
5897 struct sched_param schp
;
5898 ret
= get_errno(sched_getparam(arg1
, &schp
));
5899 if (!is_error(ret
)) {
5900 if (!lock_user_struct(VERIFY_WRITE
, target_schp
, arg2
, 0))
5902 target_schp
->sched_priority
= tswap32(schp
.sched_priority
);
5903 unlock_user_struct(target_schp
, arg2
, 1);
5907 case TARGET_NR_sched_setscheduler
:
5909 struct sched_param
*target_schp
;
5910 struct sched_param schp
;
5911 if (!lock_user_struct(VERIFY_READ
, target_schp
, arg3
, 1))
5913 schp
.sched_priority
= tswap32(target_schp
->sched_priority
);
5914 unlock_user_struct(target_schp
, arg3
, 0);
5915 ret
= get_errno(sched_setscheduler(arg1
, arg2
, &schp
));
5918 case TARGET_NR_sched_getscheduler
:
5919 ret
= get_errno(sched_getscheduler(arg1
));
5921 case TARGET_NR_sched_yield
:
5922 ret
= get_errno(sched_yield());
5924 case TARGET_NR_sched_get_priority_max
:
5925 ret
= get_errno(sched_get_priority_max(arg1
));
5927 case TARGET_NR_sched_get_priority_min
:
5928 ret
= get_errno(sched_get_priority_min(arg1
));
5930 case TARGET_NR_sched_rr_get_interval
:
5933 ret
= get_errno(sched_rr_get_interval(arg1
, &ts
));
5934 if (!is_error(ret
)) {
5935 host_to_target_timespec(arg2
, &ts
);
5939 case TARGET_NR_nanosleep
:
5941 struct timespec req
, rem
;
5942 target_to_host_timespec(&req
, arg1
);
5943 ret
= get_errno(nanosleep(&req
, &rem
));
5944 if (is_error(ret
) && arg2
) {
5945 host_to_target_timespec(arg2
, &rem
);
5949 #ifdef TARGET_NR_query_module
5950 case TARGET_NR_query_module
:
5953 #ifdef TARGET_NR_nfsservctl
5954 case TARGET_NR_nfsservctl
:
5957 case TARGET_NR_prctl
:
5960 case PR_GET_PDEATHSIG
:
5963 ret
= get_errno(prctl(arg1
, &deathsig
, arg3
, arg4
, arg5
));
5964 if (!is_error(ret
) && arg2
5965 && put_user_ual(deathsig
, arg2
))
5970 ret
= get_errno(prctl(arg1
, arg2
, arg3
, arg4
, arg5
));
5974 #ifdef TARGET_NR_arch_prctl
5975 case TARGET_NR_arch_prctl
:
5976 #if defined(TARGET_I386) && !defined(TARGET_ABI32)
5977 ret
= do_arch_prctl(cpu_env
, arg1
, arg2
);
5983 #ifdef TARGET_NR_pread
5984 case TARGET_NR_pread
:
5986 if (((CPUARMState
*)cpu_env
)->eabi
)
5989 if (!(p
= lock_user(VERIFY_WRITE
, arg2
, arg3
, 0)))
5991 ret
= get_errno(pread(arg1
, p
, arg3
, arg4
));
5992 unlock_user(p
, arg2
, ret
);
5994 case TARGET_NR_pwrite
:
5996 if (((CPUARMState
*)cpu_env
)->eabi
)
5999 if (!(p
= lock_user(VERIFY_READ
, arg2
, arg3
, 1)))
6001 ret
= get_errno(pwrite(arg1
, p
, arg3
, arg4
));
6002 unlock_user(p
, arg2
, 0);
6005 #ifdef TARGET_NR_pread64
6006 case TARGET_NR_pread64
:
6007 if (!(p
= lock_user(VERIFY_WRITE
, arg2
, arg3
, 0)))
6009 ret
= get_errno(pread64(arg1
, p
, arg3
, target_offset64(arg4
, arg5
)));
6010 unlock_user(p
, arg2
, ret
);
6012 case TARGET_NR_pwrite64
:
6013 if (!(p
= lock_user(VERIFY_READ
, arg2
, arg3
, 1)))
6015 ret
= get_errno(pwrite64(arg1
, p
, arg3
, target_offset64(arg4
, arg5
)));
6016 unlock_user(p
, arg2
, 0);
6019 case TARGET_NR_getcwd
:
6020 if (!(p
= lock_user(VERIFY_WRITE
, arg1
, arg2
, 0)))
6022 ret
= get_errno(sys_getcwd1(p
, arg2
));
6023 unlock_user(p
, arg1
, ret
);
6025 case TARGET_NR_capget
:
6027 case TARGET_NR_capset
:
6029 case TARGET_NR_sigaltstack
:
6030 #if defined(TARGET_I386) || defined(TARGET_ARM) || defined(TARGET_MIPS) || \
6031 defined(TARGET_SPARC) || defined(TARGET_PPC) || defined(TARGET_ALPHA)
6032 ret
= do_sigaltstack(arg1
, arg2
, get_sp_from_cpustate((CPUState
*)cpu_env
));
6037 case TARGET_NR_sendfile
:
6039 #ifdef TARGET_NR_getpmsg
6040 case TARGET_NR_getpmsg
:
6043 #ifdef TARGET_NR_putpmsg
6044 case TARGET_NR_putpmsg
:
6047 #ifdef TARGET_NR_vfork
6048 case TARGET_NR_vfork
:
6049 ret
= get_errno(do_fork(cpu_env
, CLONE_VFORK
| CLONE_VM
| SIGCHLD
,
6053 #ifdef TARGET_NR_ugetrlimit
6054 case TARGET_NR_ugetrlimit
:
6057 ret
= get_errno(getrlimit(arg1
, &rlim
));
6058 if (!is_error(ret
)) {
6059 struct target_rlimit
*target_rlim
;
6060 if (!lock_user_struct(VERIFY_WRITE
, target_rlim
, arg2
, 0))
6062 target_rlim
->rlim_cur
= tswapl(rlim
.rlim_cur
);
6063 target_rlim
->rlim_max
= tswapl(rlim
.rlim_max
);
6064 unlock_user_struct(target_rlim
, arg2
, 1);
6069 #ifdef TARGET_NR_truncate64
6070 case TARGET_NR_truncate64
:
6071 if (!(p
= lock_user_string(arg1
)))
6073 ret
= target_truncate64(cpu_env
, p
, arg2
, arg3
, arg4
);
6074 unlock_user(p
, arg1
, 0);
6077 #ifdef TARGET_NR_ftruncate64
6078 case TARGET_NR_ftruncate64
:
6079 ret
= target_ftruncate64(cpu_env
, arg1
, arg2
, arg3
, arg4
);
6082 #ifdef TARGET_NR_stat64
6083 case TARGET_NR_stat64
:
6084 if (!(p
= lock_user_string(arg1
)))
6086 ret
= get_errno(stat(path(p
), &st
));
6087 unlock_user(p
, arg1
, 0);
6089 ret
= host_to_target_stat64(cpu_env
, arg2
, &st
);
6092 #ifdef TARGET_NR_lstat64
6093 case TARGET_NR_lstat64
:
6094 if (!(p
= lock_user_string(arg1
)))
6096 ret
= get_errno(lstat(path(p
), &st
));
6097 unlock_user(p
, arg1
, 0);
6099 ret
= host_to_target_stat64(cpu_env
, arg2
, &st
);
6102 #ifdef TARGET_NR_fstat64
6103 case TARGET_NR_fstat64
:
6104 ret
= get_errno(fstat(arg1
, &st
));
6106 ret
= host_to_target_stat64(cpu_env
, arg2
, &st
);
6109 #if (defined(TARGET_NR_fstatat64) || defined(TARGET_NR_newfstatat)) && \
6110 (defined(__NR_fstatat64) || defined(__NR_newfstatat))
6111 #ifdef TARGET_NR_fstatat64
6112 case TARGET_NR_fstatat64
:
6114 #ifdef TARGET_NR_newfstatat
6115 case TARGET_NR_newfstatat
:
6117 if (!(p
= lock_user_string(arg2
)))
6119 #ifdef __NR_fstatat64
6120 ret
= get_errno(sys_fstatat64(arg1
, path(p
), &st
, arg4
));
6122 ret
= get_errno(sys_newfstatat(arg1
, path(p
), &st
, arg4
));
6125 ret
= host_to_target_stat64(cpu_env
, arg3
, &st
);
6129 case TARGET_NR_lchown
:
6130 if (!(p
= lock_user_string(arg1
)))
6132 ret
= get_errno(lchown(p
, low2highuid(arg2
), low2highgid(arg3
)));
6133 unlock_user(p
, arg1
, 0);
6135 case TARGET_NR_getuid
:
6136 ret
= get_errno(high2lowuid(getuid()));
6138 case TARGET_NR_getgid
:
6139 ret
= get_errno(high2lowgid(getgid()));
6141 case TARGET_NR_geteuid
:
6142 ret
= get_errno(high2lowuid(geteuid()));
6144 case TARGET_NR_getegid
:
6145 ret
= get_errno(high2lowgid(getegid()));
6147 case TARGET_NR_setreuid
:
6148 ret
= get_errno(setreuid(low2highuid(arg1
), low2highuid(arg2
)));
6150 case TARGET_NR_setregid
:
6151 ret
= get_errno(setregid(low2highgid(arg1
), low2highgid(arg2
)));
6153 case TARGET_NR_getgroups
:
6155 int gidsetsize
= arg1
;
6156 uint16_t *target_grouplist
;
6160 grouplist
= alloca(gidsetsize
* sizeof(gid_t
));
6161 ret
= get_errno(getgroups(gidsetsize
, grouplist
));
6162 if (gidsetsize
== 0)
6164 if (!is_error(ret
)) {
6165 target_grouplist
= lock_user(VERIFY_WRITE
, arg2
, gidsetsize
* 2, 0);
6166 if (!target_grouplist
)
6168 for(i
= 0;i
< ret
; i
++)
6169 target_grouplist
[i
] = tswap16(grouplist
[i
]);
6170 unlock_user(target_grouplist
, arg2
, gidsetsize
* 2);
6174 case TARGET_NR_setgroups
:
6176 int gidsetsize
= arg1
;
6177 uint16_t *target_grouplist
;
6181 grouplist
= alloca(gidsetsize
* sizeof(gid_t
));
6182 target_grouplist
= lock_user(VERIFY_READ
, arg2
, gidsetsize
* 2, 1);
6183 if (!target_grouplist
) {
6184 ret
= -TARGET_EFAULT
;
6187 for(i
= 0;i
< gidsetsize
; i
++)
6188 grouplist
[i
] = tswap16(target_grouplist
[i
]);
6189 unlock_user(target_grouplist
, arg2
, 0);
6190 ret
= get_errno(setgroups(gidsetsize
, grouplist
));
6193 case TARGET_NR_fchown
:
6194 ret
= get_errno(fchown(arg1
, low2highuid(arg2
), low2highgid(arg3
)));
6196 #if defined(TARGET_NR_fchownat) && defined(__NR_fchownat)
6197 case TARGET_NR_fchownat
:
6198 if (!(p
= lock_user_string(arg2
)))
6200 ret
= get_errno(sys_fchownat(arg1
, p
, low2highuid(arg3
), low2highgid(arg4
), arg5
));
6201 unlock_user(p
, arg2
, 0);
6204 #ifdef TARGET_NR_setresuid
6205 case TARGET_NR_setresuid
:
6206 ret
= get_errno(setresuid(low2highuid(arg1
),
6208 low2highuid(arg3
)));
6211 #ifdef TARGET_NR_getresuid
6212 case TARGET_NR_getresuid
:
6214 uid_t ruid
, euid
, suid
;
6215 ret
= get_errno(getresuid(&ruid
, &euid
, &suid
));
6216 if (!is_error(ret
)) {
6217 if (put_user_u16(high2lowuid(ruid
), arg1
)
6218 || put_user_u16(high2lowuid(euid
), arg2
)
6219 || put_user_u16(high2lowuid(suid
), arg3
))
6225 #ifdef TARGET_NR_getresgid
6226 case TARGET_NR_setresgid
:
6227 ret
= get_errno(setresgid(low2highgid(arg1
),
6229 low2highgid(arg3
)));
6232 #ifdef TARGET_NR_getresgid
6233 case TARGET_NR_getresgid
:
6235 gid_t rgid
, egid
, sgid
;
6236 ret
= get_errno(getresgid(&rgid
, &egid
, &sgid
));
6237 if (!is_error(ret
)) {
6238 if (put_user_u16(high2lowgid(rgid
), arg1
)
6239 || put_user_u16(high2lowgid(egid
), arg2
)
6240 || put_user_u16(high2lowgid(sgid
), arg3
))
6246 case TARGET_NR_chown
:
6247 if (!(p
= lock_user_string(arg1
)))
6249 ret
= get_errno(chown(p
, low2highuid(arg2
), low2highgid(arg3
)));
6250 unlock_user(p
, arg1
, 0);
6252 case TARGET_NR_setuid
:
6253 ret
= get_errno(setuid(low2highuid(arg1
)));
6255 case TARGET_NR_setgid
:
6256 ret
= get_errno(setgid(low2highgid(arg1
)));
6258 case TARGET_NR_setfsuid
:
6259 ret
= get_errno(setfsuid(arg1
));
6261 case TARGET_NR_setfsgid
:
6262 ret
= get_errno(setfsgid(arg1
));
6264 #endif /* USE_UID16 */
6266 #ifdef TARGET_NR_lchown32
6267 case TARGET_NR_lchown32
:
6268 if (!(p
= lock_user_string(arg1
)))
6270 ret
= get_errno(lchown(p
, arg2
, arg3
));
6271 unlock_user(p
, arg1
, 0);
6274 #ifdef TARGET_NR_getuid32
6275 case TARGET_NR_getuid32
:
6276 ret
= get_errno(getuid());
6280 #if defined(TARGET_NR_getxuid) && defined(TARGET_ALPHA)
6281 /* Alpha specific */
6282 case TARGET_NR_getxuid
:
6286 ((CPUAlphaState
*)cpu_env
)->ir
[IR_A4
]=euid
;
6288 ret
= get_errno(getuid());
6291 #if defined(TARGET_NR_getxgid) && defined(TARGET_ALPHA)
6292 /* Alpha specific */
6293 case TARGET_NR_getxgid
:
6297 ((CPUAlphaState
*)cpu_env
)->ir
[IR_A4
]=egid
;
6299 ret
= get_errno(getgid());
6303 #ifdef TARGET_NR_getgid32
6304 case TARGET_NR_getgid32
:
6305 ret
= get_errno(getgid());
6308 #ifdef TARGET_NR_geteuid32
6309 case TARGET_NR_geteuid32
:
6310 ret
= get_errno(geteuid());
6313 #ifdef TARGET_NR_getegid32
6314 case TARGET_NR_getegid32
:
6315 ret
= get_errno(getegid());
6318 #ifdef TARGET_NR_setreuid32
6319 case TARGET_NR_setreuid32
:
6320 ret
= get_errno(setreuid(arg1
, arg2
));
6323 #ifdef TARGET_NR_setregid32
6324 case TARGET_NR_setregid32
:
6325 ret
= get_errno(setregid(arg1
, arg2
));
6328 #ifdef TARGET_NR_getgroups32
6329 case TARGET_NR_getgroups32
:
6331 int gidsetsize
= arg1
;
6332 uint32_t *target_grouplist
;
6336 grouplist
= alloca(gidsetsize
* sizeof(gid_t
));
6337 ret
= get_errno(getgroups(gidsetsize
, grouplist
));
6338 if (gidsetsize
== 0)
6340 if (!is_error(ret
)) {
6341 target_grouplist
= lock_user(VERIFY_WRITE
, arg2
, gidsetsize
* 4, 0);
6342 if (!target_grouplist
) {
6343 ret
= -TARGET_EFAULT
;
6346 for(i
= 0;i
< ret
; i
++)
6347 target_grouplist
[i
] = tswap32(grouplist
[i
]);
6348 unlock_user(target_grouplist
, arg2
, gidsetsize
* 4);
6353 #ifdef TARGET_NR_setgroups32
6354 case TARGET_NR_setgroups32
:
6356 int gidsetsize
= arg1
;
6357 uint32_t *target_grouplist
;
6361 grouplist
= alloca(gidsetsize
* sizeof(gid_t
));
6362 target_grouplist
= lock_user(VERIFY_READ
, arg2
, gidsetsize
* 4, 1);
6363 if (!target_grouplist
) {
6364 ret
= -TARGET_EFAULT
;
6367 for(i
= 0;i
< gidsetsize
; i
++)
6368 grouplist
[i
] = tswap32(target_grouplist
[i
]);
6369 unlock_user(target_grouplist
, arg2
, 0);
6370 ret
= get_errno(setgroups(gidsetsize
, grouplist
));
6374 #ifdef TARGET_NR_fchown32
6375 case TARGET_NR_fchown32
:
6376 ret
= get_errno(fchown(arg1
, arg2
, arg3
));
6379 #ifdef TARGET_NR_setresuid32
6380 case TARGET_NR_setresuid32
:
6381 ret
= get_errno(setresuid(arg1
, arg2
, arg3
));
6384 #ifdef TARGET_NR_getresuid32
6385 case TARGET_NR_getresuid32
:
6387 uid_t ruid
, euid
, suid
;
6388 ret
= get_errno(getresuid(&ruid
, &euid
, &suid
));
6389 if (!is_error(ret
)) {
6390 if (put_user_u32(ruid
, arg1
)
6391 || put_user_u32(euid
, arg2
)
6392 || put_user_u32(suid
, arg3
))
6398 #ifdef TARGET_NR_setresgid32
6399 case TARGET_NR_setresgid32
:
6400 ret
= get_errno(setresgid(arg1
, arg2
, arg3
));
6403 #ifdef TARGET_NR_getresgid32
6404 case TARGET_NR_getresgid32
:
6406 gid_t rgid
, egid
, sgid
;
6407 ret
= get_errno(getresgid(&rgid
, &egid
, &sgid
));
6408 if (!is_error(ret
)) {
6409 if (put_user_u32(rgid
, arg1
)
6410 || put_user_u32(egid
, arg2
)
6411 || put_user_u32(sgid
, arg3
))
6417 #ifdef TARGET_NR_chown32
6418 case TARGET_NR_chown32
:
6419 if (!(p
= lock_user_string(arg1
)))
6421 ret
= get_errno(chown(p
, arg2
, arg3
));
6422 unlock_user(p
, arg1
, 0);
6425 #ifdef TARGET_NR_setuid32
6426 case TARGET_NR_setuid32
:
6427 ret
= get_errno(setuid(arg1
));
6430 #ifdef TARGET_NR_setgid32
6431 case TARGET_NR_setgid32
:
6432 ret
= get_errno(setgid(arg1
));
6435 #ifdef TARGET_NR_setfsuid32
6436 case TARGET_NR_setfsuid32
:
6437 ret
= get_errno(setfsuid(arg1
));
6440 #ifdef TARGET_NR_setfsgid32
6441 case TARGET_NR_setfsgid32
:
6442 ret
= get_errno(setfsgid(arg1
));
6446 case TARGET_NR_pivot_root
:
6448 #ifdef TARGET_NR_mincore
6449 case TARGET_NR_mincore
:
6452 ret
= -TARGET_EFAULT
;
6453 if (!(a
= lock_user(VERIFY_READ
, arg1
,arg2
, 0)))
6455 if (!(p
= lock_user_string(arg3
)))
6457 ret
= get_errno(mincore(a
, arg2
, p
));
6458 unlock_user(p
, arg3
, ret
);
6460 unlock_user(a
, arg1
, 0);
6464 #ifdef TARGET_NR_arm_fadvise64_64
6465 case TARGET_NR_arm_fadvise64_64
:
6468 * arm_fadvise64_64 looks like fadvise64_64 but
6469 * with different argument order
6477 #if defined(TARGET_NR_fadvise64_64) || defined(TARGET_NR_arm_fadvise64_64)
6478 #ifdef TARGET_NR_fadvise64_64
6479 case TARGET_NR_fadvise64_64
:
6481 /* This is a hint, so ignoring and returning success is ok. */
6485 #ifdef TARGET_NR_madvise
6486 case TARGET_NR_madvise
:
6487 /* A straight passthrough may not be safe because qemu sometimes
6488 turns private flie-backed mappings into anonymous mappings.
6489 This will break MADV_DONTNEED.
6490 This is a hint, so ignoring and returning success is ok. */
6494 #if TARGET_ABI_BITS == 32
6495 case TARGET_NR_fcntl64
:
6499 struct target_flock64
*target_fl
;
6501 struct target_eabi_flock64
*target_efl
;
6505 case TARGET_F_GETLK64
:
6508 case TARGET_F_SETLK64
:
6511 case TARGET_F_SETLKW64
:
6520 case TARGET_F_GETLK64
:
6522 if (((CPUARMState
*)cpu_env
)->eabi
) {
6523 if (!lock_user_struct(VERIFY_READ
, target_efl
, arg3
, 1))
6525 fl
.l_type
= tswap16(target_efl
->l_type
);
6526 fl
.l_whence
= tswap16(target_efl
->l_whence
);
6527 fl
.l_start
= tswap64(target_efl
->l_start
);
6528 fl
.l_len
= tswap64(target_efl
->l_len
);
6529 fl
.l_pid
= tswapl(target_efl
->l_pid
);
6530 unlock_user_struct(target_efl
, arg3
, 0);
6534 if (!lock_user_struct(VERIFY_READ
, target_fl
, arg3
, 1))
6536 fl
.l_type
= tswap16(target_fl
->l_type
);
6537 fl
.l_whence
= tswap16(target_fl
->l_whence
);
6538 fl
.l_start
= tswap64(target_fl
->l_start
);
6539 fl
.l_len
= tswap64(target_fl
->l_len
);
6540 fl
.l_pid
= tswapl(target_fl
->l_pid
);
6541 unlock_user_struct(target_fl
, arg3
, 0);
6543 ret
= get_errno(fcntl(arg1
, cmd
, &fl
));
6546 if (((CPUARMState
*)cpu_env
)->eabi
) {
6547 if (!lock_user_struct(VERIFY_WRITE
, target_efl
, arg3
, 0))
6549 target_efl
->l_type
= tswap16(fl
.l_type
);
6550 target_efl
->l_whence
= tswap16(fl
.l_whence
);
6551 target_efl
->l_start
= tswap64(fl
.l_start
);
6552 target_efl
->l_len
= tswap64(fl
.l_len
);
6553 target_efl
->l_pid
= tswapl(fl
.l_pid
);
6554 unlock_user_struct(target_efl
, arg3
, 1);
6558 if (!lock_user_struct(VERIFY_WRITE
, target_fl
, arg3
, 0))
6560 target_fl
->l_type
= tswap16(fl
.l_type
);
6561 target_fl
->l_whence
= tswap16(fl
.l_whence
);
6562 target_fl
->l_start
= tswap64(fl
.l_start
);
6563 target_fl
->l_len
= tswap64(fl
.l_len
);
6564 target_fl
->l_pid
= tswapl(fl
.l_pid
);
6565 unlock_user_struct(target_fl
, arg3
, 1);
6570 case TARGET_F_SETLK64
:
6571 case TARGET_F_SETLKW64
:
6573 if (((CPUARMState
*)cpu_env
)->eabi
) {
6574 if (!lock_user_struct(VERIFY_READ
, target_efl
, arg3
, 1))
6576 fl
.l_type
= tswap16(target_efl
->l_type
);
6577 fl
.l_whence
= tswap16(target_efl
->l_whence
);
6578 fl
.l_start
= tswap64(target_efl
->l_start
);
6579 fl
.l_len
= tswap64(target_efl
->l_len
);
6580 fl
.l_pid
= tswapl(target_efl
->l_pid
);
6581 unlock_user_struct(target_efl
, arg3
, 0);
6585 if (!lock_user_struct(VERIFY_READ
, target_fl
, arg3
, 1))
6587 fl
.l_type
= tswap16(target_fl
->l_type
);
6588 fl
.l_whence
= tswap16(target_fl
->l_whence
);
6589 fl
.l_start
= tswap64(target_fl
->l_start
);
6590 fl
.l_len
= tswap64(target_fl
->l_len
);
6591 fl
.l_pid
= tswapl(target_fl
->l_pid
);
6592 unlock_user_struct(target_fl
, arg3
, 0);
6594 ret
= get_errno(fcntl(arg1
, cmd
, &fl
));
6597 ret
= do_fcntl(arg1
, cmd
, arg3
);
6603 #ifdef TARGET_NR_cacheflush
6604 case TARGET_NR_cacheflush
:
6605 /* self-modifying code is handled automatically, so nothing needed */
6609 #ifdef TARGET_NR_security
6610 case TARGET_NR_security
:
6613 #ifdef TARGET_NR_getpagesize
6614 case TARGET_NR_getpagesize
:
6615 ret
= TARGET_PAGE_SIZE
;
6618 case TARGET_NR_gettid
:
6619 ret
= get_errno(gettid());
6621 #ifdef TARGET_NR_readahead
6622 case TARGET_NR_readahead
:
6623 #if TARGET_ABI_BITS == 32
6625 if (((CPUARMState
*)cpu_env
)->eabi
)
6632 ret
= get_errno(readahead(arg1
, ((off64_t
)arg3
<< 32) | arg2
, arg4
));
6634 ret
= get_errno(readahead(arg1
, arg2
, arg3
));
6638 #ifdef TARGET_NR_setxattr
6639 case TARGET_NR_setxattr
:
6640 case TARGET_NR_lsetxattr
:
6641 case TARGET_NR_fsetxattr
:
6642 case TARGET_NR_getxattr
:
6643 case TARGET_NR_lgetxattr
:
6644 case TARGET_NR_fgetxattr
:
6645 case TARGET_NR_listxattr
:
6646 case TARGET_NR_llistxattr
:
6647 case TARGET_NR_flistxattr
:
6648 case TARGET_NR_removexattr
:
6649 case TARGET_NR_lremovexattr
:
6650 case TARGET_NR_fremovexattr
:
6651 ret
= -TARGET_EOPNOTSUPP
;
6654 #ifdef TARGET_NR_set_thread_area
6655 case TARGET_NR_set_thread_area
:
6656 #if defined(TARGET_MIPS)
6657 ((CPUMIPSState
*) cpu_env
)->tls_value
= arg1
;
6660 #elif defined(TARGET_CRIS)
6662 ret
= -TARGET_EINVAL
;
6664 ((CPUCRISState
*) cpu_env
)->pregs
[PR_PID
] = arg1
;
6668 #elif defined(TARGET_I386) && defined(TARGET_ABI32)
6669 ret
= do_set_thread_area(cpu_env
, arg1
);
6672 goto unimplemented_nowarn
;
6675 #ifdef TARGET_NR_get_thread_area
6676 case TARGET_NR_get_thread_area
:
6677 #if defined(TARGET_I386) && defined(TARGET_ABI32)
6678 ret
= do_get_thread_area(cpu_env
, arg1
);
6680 goto unimplemented_nowarn
;
6683 #ifdef TARGET_NR_getdomainname
6684 case TARGET_NR_getdomainname
:
6685 goto unimplemented_nowarn
;
6688 #ifdef TARGET_NR_clock_gettime
6689 case TARGET_NR_clock_gettime
:
6692 ret
= get_errno(clock_gettime(arg1
, &ts
));
6693 if (!is_error(ret
)) {
6694 host_to_target_timespec(arg2
, &ts
);
6699 #ifdef TARGET_NR_clock_getres
6700 case TARGET_NR_clock_getres
:
6703 ret
= get_errno(clock_getres(arg1
, &ts
));
6704 if (!is_error(ret
)) {
6705 host_to_target_timespec(arg2
, &ts
);
6710 #ifdef TARGET_NR_clock_nanosleep
6711 case TARGET_NR_clock_nanosleep
:
6714 target_to_host_timespec(&ts
, arg3
);
6715 ret
= get_errno(clock_nanosleep(arg1
, arg2
, &ts
, arg4
? &ts
: NULL
));
6717 host_to_target_timespec(arg4
, &ts
);
6722 #if defined(TARGET_NR_set_tid_address) && defined(__NR_set_tid_address)
6723 case TARGET_NR_set_tid_address
:
6724 ret
= get_errno(set_tid_address((int *)g2h(arg1
)));
6728 #if defined(TARGET_NR_tkill) && defined(__NR_tkill)
6729 case TARGET_NR_tkill
:
6730 ret
= get_errno(sys_tkill((int)arg1
, target_to_host_signal(arg2
)));
6734 #if defined(TARGET_NR_tgkill) && defined(__NR_tgkill)
6735 case TARGET_NR_tgkill
:
6736 ret
= get_errno(sys_tgkill((int)arg1
, (int)arg2
,
6737 target_to_host_signal(arg3
)));
6741 #ifdef TARGET_NR_set_robust_list
6742 case TARGET_NR_set_robust_list
:
6743 goto unimplemented_nowarn
;
6746 #if defined(TARGET_NR_utimensat) && defined(__NR_utimensat)
6747 case TARGET_NR_utimensat
:
6749 struct timespec
*tsp
, ts
[2];
6753 target_to_host_timespec(ts
, arg3
);
6754 target_to_host_timespec(ts
+1, arg3
+sizeof(struct target_timespec
));
6758 ret
= get_errno(sys_utimensat(arg1
, NULL
, tsp
, arg4
));
6760 if (!(p
= lock_user_string(arg2
))) {
6761 ret
= -TARGET_EFAULT
;
6764 ret
= get_errno(sys_utimensat(arg1
, path(p
), tsp
, arg4
));
6765 unlock_user(p
, arg2
, 0);
6770 #if defined(USE_NPTL)
6771 case TARGET_NR_futex
:
6772 ret
= do_futex(arg1
, arg2
, arg3
, arg4
, arg5
, arg6
);
6775 #if defined(TARGET_NR_inotify_init) && defined(__NR_inotify_init)
6776 case TARGET_NR_inotify_init
:
6777 ret
= get_errno(sys_inotify_init());
6780 #if defined(TARGET_NR_inotify_add_watch) && defined(__NR_inotify_add_watch)
6781 case TARGET_NR_inotify_add_watch
:
6782 p
= lock_user_string(arg2
);
6783 ret
= get_errno(sys_inotify_add_watch(arg1
, path(p
), arg3
));
6784 unlock_user(p
, arg2
, 0);
6787 #if defined(TARGET_NR_inotify_rm_watch) && defined(__NR_inotify_rm_watch)
6788 case TARGET_NR_inotify_rm_watch
:
6789 ret
= get_errno(sys_inotify_rm_watch(arg1
, arg2
));
6793 #ifdef TARGET_NR_mq_open
6794 case TARGET_NR_mq_open
:
6796 struct mq_attr posix_mq_attr
;
6798 p
= lock_user_string(arg1
- 1);
6800 copy_from_user_mq_attr (&posix_mq_attr
, arg4
);
6801 ret
= get_errno(mq_open(p
, arg2
, arg3
, &posix_mq_attr
));
6802 unlock_user (p
, arg1
, 0);
6806 case TARGET_NR_mq_unlink
:
6807 p
= lock_user_string(arg1
- 1);
6808 ret
= get_errno(mq_unlink(p
));
6809 unlock_user (p
, arg1
, 0);
6812 case TARGET_NR_mq_timedsend
:
6816 p
= lock_user (VERIFY_READ
, arg2
, arg3
, 1);
6818 target_to_host_timespec(&ts
, arg5
);
6819 ret
= get_errno(mq_timedsend(arg1
, p
, arg3
, arg4
, &ts
));
6820 host_to_target_timespec(arg5
, &ts
);
6823 ret
= get_errno(mq_send(arg1
, p
, arg3
, arg4
));
6824 unlock_user (p
, arg2
, arg3
);
6828 case TARGET_NR_mq_timedreceive
:
6833 p
= lock_user (VERIFY_READ
, arg2
, arg3
, 1);
6835 target_to_host_timespec(&ts
, arg5
);
6836 ret
= get_errno(mq_timedreceive(arg1
, p
, arg3
, &prio
, &ts
));
6837 host_to_target_timespec(arg5
, &ts
);
6840 ret
= get_errno(mq_receive(arg1
, p
, arg3
, &prio
));
6841 unlock_user (p
, arg2
, arg3
);
6843 put_user_u32(prio
, arg4
);
6847 /* Not implemented for now... */
6848 /* case TARGET_NR_mq_notify: */
6851 case TARGET_NR_mq_getsetattr
:
6853 struct mq_attr posix_mq_attr_in
, posix_mq_attr_out
;
6856 ret
= mq_getattr(arg1
, &posix_mq_attr_out
);
6857 copy_to_user_mq_attr(arg3
, &posix_mq_attr_out
);
6860 copy_from_user_mq_attr(&posix_mq_attr_in
, arg2
);
6861 ret
|= mq_setattr(arg1
, &posix_mq_attr_in
, &posix_mq_attr_out
);
6870 gemu_log("qemu: Unsupported syscall: %d\n", num
);
6871 #if defined(TARGET_NR_setxattr) || defined(TARGET_NR_get_thread_area) || defined(TARGET_NR_getdomainname) || defined(TARGET_NR_set_robust_list)
6872 unimplemented_nowarn
:
6874 ret
= -TARGET_ENOSYS
;
6879 gemu_log(" = %ld\n", ret
);
6882 print_syscall_ret(num
, ret
);
6885 ret
= -TARGET_EFAULT
;