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>
80 #include "linux_loop.h"
83 #include "qemu-common.h"
86 #include <linux/futex.h>
87 #define CLONE_NPTL_FLAGS2 (CLONE_SETTLS | \
88 CLONE_PARENT_SETTID | CLONE_CHILD_SETTID | CLONE_CHILD_CLEARTID)
90 /* XXX: Hardcode the above values. */
91 #define CLONE_NPTL_FLAGS2 0
96 //#include <linux/msdos_fs.h>
97 #define VFAT_IOCTL_READDIR_BOTH _IOR('r', 1, struct linux_dirent [2])
98 #define VFAT_IOCTL_READDIR_SHORT _IOR('r', 2, struct linux_dirent [2])
109 #define _syscall0(type,name) \
110 static type name (void) \
112 return syscall(__NR_##name); \
115 #define _syscall1(type,name,type1,arg1) \
116 static type name (type1 arg1) \
118 return syscall(__NR_##name, arg1); \
121 #define _syscall2(type,name,type1,arg1,type2,arg2) \
122 static type name (type1 arg1,type2 arg2) \
124 return syscall(__NR_##name, arg1, arg2); \
127 #define _syscall3(type,name,type1,arg1,type2,arg2,type3,arg3) \
128 static type name (type1 arg1,type2 arg2,type3 arg3) \
130 return syscall(__NR_##name, arg1, arg2, arg3); \
133 #define _syscall4(type,name,type1,arg1,type2,arg2,type3,arg3,type4,arg4) \
134 static type name (type1 arg1,type2 arg2,type3 arg3,type4 arg4) \
136 return syscall(__NR_##name, arg1, arg2, arg3, arg4); \
139 #define _syscall5(type,name,type1,arg1,type2,arg2,type3,arg3,type4,arg4, \
141 static type name (type1 arg1,type2 arg2,type3 arg3,type4 arg4,type5 arg5) \
143 return syscall(__NR_##name, arg1, arg2, arg3, arg4, arg5); \
147 #define _syscall6(type,name,type1,arg1,type2,arg2,type3,arg3,type4,arg4, \
148 type5,arg5,type6,arg6) \
149 static type name (type1 arg1,type2 arg2,type3 arg3,type4 arg4,type5 arg5, \
152 return syscall(__NR_##name, arg1, arg2, arg3, arg4, arg5, arg6); \
156 #define __NR_sys_uname __NR_uname
157 #define __NR_sys_faccessat __NR_faccessat
158 #define __NR_sys_fchmodat __NR_fchmodat
159 #define __NR_sys_fchownat __NR_fchownat
160 #define __NR_sys_fstatat64 __NR_fstatat64
161 #define __NR_sys_futimesat __NR_futimesat
162 #define __NR_sys_getcwd1 __NR_getcwd
163 #define __NR_sys_getdents __NR_getdents
164 #define __NR_sys_getdents64 __NR_getdents64
165 #define __NR_sys_getpriority __NR_getpriority
166 #define __NR_sys_linkat __NR_linkat
167 #define __NR_sys_mkdirat __NR_mkdirat
168 #define __NR_sys_mknodat __NR_mknodat
169 #define __NR_sys_newfstatat __NR_newfstatat
170 #define __NR_sys_openat __NR_openat
171 #define __NR_sys_readlinkat __NR_readlinkat
172 #define __NR_sys_renameat __NR_renameat
173 #define __NR_sys_rt_sigqueueinfo __NR_rt_sigqueueinfo
174 #define __NR_sys_symlinkat __NR_symlinkat
175 #define __NR_sys_syslog __NR_syslog
176 #define __NR_sys_tgkill __NR_tgkill
177 #define __NR_sys_tkill __NR_tkill
178 #define __NR_sys_unlinkat __NR_unlinkat
179 #define __NR_sys_utimensat __NR_utimensat
180 #define __NR_sys_futex __NR_futex
181 #define __NR_sys_inotify_init __NR_inotify_init
182 #define __NR_sys_inotify_add_watch __NR_inotify_add_watch
183 #define __NR_sys_inotify_rm_watch __NR_inotify_rm_watch
185 #if defined(__alpha__) || defined (__ia64__) || defined(__x86_64__)
186 #define __NR__llseek __NR_lseek
190 _syscall0(int, gettid
)
192 /* This is a replacement for the host gettid() and must return a host
194 static int gettid(void) {
198 #if TARGET_ABI_BITS == 32
199 _syscall3(int, sys_getdents
, uint
, fd
, struct linux_dirent
*, dirp
, uint
, count
);
201 #if defined(TARGET_NR_getdents64) && defined(__NR_getdents64)
202 _syscall3(int, sys_getdents64
, uint
, fd
, struct linux_dirent64
*, dirp
, uint
, count
);
204 _syscall2(int, sys_getpriority
, int, which
, int, who
);
205 #if defined(TARGET_NR__llseek) && !defined (__x86_64__)
206 _syscall5(int, _llseek
, uint
, fd
, ulong
, hi
, ulong
, lo
,
207 loff_t
*, res
, uint
, wh
);
209 _syscall3(int,sys_rt_sigqueueinfo
,int,pid
,int,sig
,siginfo_t
*,uinfo
)
210 _syscall3(int,sys_syslog
,int,type
,char*,bufp
,int,len
)
211 #if defined(TARGET_NR_tgkill) && defined(__NR_tgkill)
212 _syscall3(int,sys_tgkill
,int,tgid
,int,pid
,int,sig
)
214 #if defined(TARGET_NR_tkill) && defined(__NR_tkill)
215 _syscall2(int,sys_tkill
,int,tid
,int,sig
)
217 #ifdef __NR_exit_group
218 _syscall1(int,exit_group
,int,error_code
)
220 #if defined(TARGET_NR_set_tid_address) && defined(__NR_set_tid_address)
221 _syscall1(int,set_tid_address
,int *,tidptr
)
223 #if defined(USE_NPTL)
224 #if defined(TARGET_NR_futex) && defined(__NR_futex)
225 _syscall6(int,sys_futex
,int *,uaddr
,int,op
,int,val
,
226 const struct timespec
*,timeout
,int *,uaddr2
,int,val3
)
230 static bitmask_transtbl fcntl_flags_tbl
[] = {
231 { TARGET_O_ACCMODE
, TARGET_O_WRONLY
, O_ACCMODE
, O_WRONLY
, },
232 { TARGET_O_ACCMODE
, TARGET_O_RDWR
, O_ACCMODE
, O_RDWR
, },
233 { TARGET_O_CREAT
, TARGET_O_CREAT
, O_CREAT
, O_CREAT
, },
234 { TARGET_O_EXCL
, TARGET_O_EXCL
, O_EXCL
, O_EXCL
, },
235 { TARGET_O_NOCTTY
, TARGET_O_NOCTTY
, O_NOCTTY
, O_NOCTTY
, },
236 { TARGET_O_TRUNC
, TARGET_O_TRUNC
, O_TRUNC
, O_TRUNC
, },
237 { TARGET_O_APPEND
, TARGET_O_APPEND
, O_APPEND
, O_APPEND
, },
238 { TARGET_O_NONBLOCK
, TARGET_O_NONBLOCK
, O_NONBLOCK
, O_NONBLOCK
, },
239 { TARGET_O_SYNC
, TARGET_O_SYNC
, O_SYNC
, O_SYNC
, },
240 { TARGET_FASYNC
, TARGET_FASYNC
, FASYNC
, FASYNC
, },
241 { TARGET_O_DIRECTORY
, TARGET_O_DIRECTORY
, O_DIRECTORY
, O_DIRECTORY
, },
242 { TARGET_O_NOFOLLOW
, TARGET_O_NOFOLLOW
, O_NOFOLLOW
, O_NOFOLLOW
, },
243 { TARGET_O_LARGEFILE
, TARGET_O_LARGEFILE
, O_LARGEFILE
, O_LARGEFILE
, },
244 #if defined(O_DIRECT)
245 { TARGET_O_DIRECT
, TARGET_O_DIRECT
, O_DIRECT
, O_DIRECT
, },
250 #define COPY_UTSNAME_FIELD(dest, src) \
252 /* __NEW_UTS_LEN doesn't include terminating null */ \
253 (void) strncpy((dest), (src), __NEW_UTS_LEN); \
254 (dest)[__NEW_UTS_LEN] = '\0'; \
257 static int sys_uname(struct new_utsname
*buf
)
259 struct utsname uts_buf
;
261 if (uname(&uts_buf
) < 0)
265 * Just in case these have some differences, we
266 * translate utsname to new_utsname (which is the
267 * struct linux kernel uses).
270 bzero(buf
, sizeof (*buf
));
271 COPY_UTSNAME_FIELD(buf
->sysname
, uts_buf
.sysname
);
272 COPY_UTSNAME_FIELD(buf
->nodename
, uts_buf
.nodename
);
273 COPY_UTSNAME_FIELD(buf
->release
, uts_buf
.release
);
274 COPY_UTSNAME_FIELD(buf
->version
, uts_buf
.version
);
275 COPY_UTSNAME_FIELD(buf
->machine
, uts_buf
.machine
);
277 COPY_UTSNAME_FIELD(buf
->domainname
, uts_buf
.domainname
);
281 #undef COPY_UTSNAME_FIELD
284 static int sys_getcwd1(char *buf
, size_t size
)
286 if (getcwd(buf
, size
) == NULL
) {
287 /* getcwd() sets errno */
290 return strlen(buf
)+1;
295 * Host system seems to have atfile syscall stubs available. We
296 * now enable them one by one as specified by target syscall_nr.h.
299 #ifdef TARGET_NR_faccessat
300 static int sys_faccessat(int dirfd
, const char *pathname
, int mode
)
302 return (faccessat(dirfd
, pathname
, mode
, 0));
305 #ifdef TARGET_NR_fchmodat
306 static int sys_fchmodat(int dirfd
, const char *pathname
, mode_t mode
)
308 return (fchmodat(dirfd
, pathname
, mode
, 0));
311 #if defined(TARGET_NR_fchownat) && defined(USE_UID16)
312 static int sys_fchownat(int dirfd
, const char *pathname
, uid_t owner
,
313 gid_t group
, int flags
)
315 return (fchownat(dirfd
, pathname
, owner
, group
, flags
));
318 #ifdef __NR_fstatat64
319 static int sys_fstatat64(int dirfd
, const char *pathname
, struct stat
*buf
,
322 return (fstatat(dirfd
, pathname
, buf
, flags
));
325 #ifdef __NR_newfstatat
326 static int sys_newfstatat(int dirfd
, const char *pathname
, struct stat
*buf
,
329 return (fstatat(dirfd
, pathname
, buf
, flags
));
332 #ifdef TARGET_NR_futimesat
333 static int sys_futimesat(int dirfd
, const char *pathname
,
334 const struct timeval times
[2])
336 return (futimesat(dirfd
, pathname
, times
));
339 #ifdef TARGET_NR_linkat
340 static int sys_linkat(int olddirfd
, const char *oldpath
,
341 int newdirfd
, const char *newpath
, int flags
)
343 return (linkat(olddirfd
, oldpath
, newdirfd
, newpath
, flags
));
346 #ifdef TARGET_NR_mkdirat
347 static int sys_mkdirat(int dirfd
, const char *pathname
, mode_t mode
)
349 return (mkdirat(dirfd
, pathname
, mode
));
352 #ifdef TARGET_NR_mknodat
353 static int sys_mknodat(int dirfd
, const char *pathname
, mode_t mode
,
356 return (mknodat(dirfd
, pathname
, mode
, dev
));
359 #ifdef TARGET_NR_openat
360 static int sys_openat(int dirfd
, const char *pathname
, int flags
, ...)
363 * open(2) has extra parameter 'mode' when called with
366 if ((flags
& O_CREAT
) != 0) {
371 * Get the 'mode' parameter and translate it to
375 mode
= va_arg(ap
, mode_t
);
376 mode
= target_to_host_bitmask(mode
, fcntl_flags_tbl
);
379 return (openat(dirfd
, pathname
, flags
, mode
));
381 return (openat(dirfd
, pathname
, flags
));
384 #ifdef TARGET_NR_readlinkat
385 static int sys_readlinkat(int dirfd
, const char *pathname
, char *buf
, size_t bufsiz
)
387 return (readlinkat(dirfd
, pathname
, buf
, bufsiz
));
390 #ifdef TARGET_NR_renameat
391 static int sys_renameat(int olddirfd
, const char *oldpath
,
392 int newdirfd
, const char *newpath
)
394 return (renameat(olddirfd
, oldpath
, newdirfd
, newpath
));
397 #ifdef TARGET_NR_symlinkat
398 static int sys_symlinkat(const char *oldpath
, int newdirfd
, const char *newpath
)
400 return (symlinkat(oldpath
, newdirfd
, newpath
));
403 #ifdef TARGET_NR_unlinkat
404 static int sys_unlinkat(int dirfd
, const char *pathname
, int flags
)
406 return (unlinkat(dirfd
, pathname
, flags
));
409 #else /* !CONFIG_ATFILE */
412 * Try direct syscalls instead
414 #if defined(TARGET_NR_faccessat) && defined(__NR_faccessat)
415 _syscall3(int,sys_faccessat
,int,dirfd
,const char *,pathname
,int,mode
)
417 #if defined(TARGET_NR_fchmodat) && defined(__NR_fchmodat)
418 _syscall3(int,sys_fchmodat
,int,dirfd
,const char *,pathname
, mode_t
,mode
)
420 #if defined(TARGET_NR_fchownat) && defined(__NR_fchownat) && defined(USE_UID16)
421 _syscall5(int,sys_fchownat
,int,dirfd
,const char *,pathname
,
422 uid_t
,owner
,gid_t
,group
,int,flags
)
424 #if (defined(TARGET_NR_fstatat64) || defined(TARGET_NR_newfstatat)) && \
425 defined(__NR_fstatat64)
426 _syscall4(int,sys_fstatat64
,int,dirfd
,const char *,pathname
,
427 struct stat
*,buf
,int,flags
)
429 #if defined(TARGET_NR_futimesat) && defined(__NR_futimesat)
430 _syscall3(int,sys_futimesat
,int,dirfd
,const char *,pathname
,
431 const struct timeval
*,times
)
433 #if (defined(TARGET_NR_newfstatat) || defined(TARGET_NR_fstatat64) ) && \
434 defined(__NR_newfstatat)
435 _syscall4(int,sys_newfstatat
,int,dirfd
,const char *,pathname
,
436 struct stat
*,buf
,int,flags
)
438 #if defined(TARGET_NR_linkat) && defined(__NR_linkat)
439 _syscall5(int,sys_linkat
,int,olddirfd
,const char *,oldpath
,
440 int,newdirfd
,const char *,newpath
,int,flags
)
442 #if defined(TARGET_NR_mkdirat) && defined(__NR_mkdirat)
443 _syscall3(int,sys_mkdirat
,int,dirfd
,const char *,pathname
,mode_t
,mode
)
445 #if defined(TARGET_NR_mknodat) && defined(__NR_mknodat)
446 _syscall4(int,sys_mknodat
,int,dirfd
,const char *,pathname
,
447 mode_t
,mode
,dev_t
,dev
)
449 #if defined(TARGET_NR_openat) && defined(__NR_openat)
450 _syscall4(int,sys_openat
,int,dirfd
,const char *,pathname
,int,flags
,mode_t
,mode
)
452 #if defined(TARGET_NR_readlinkat) && defined(__NR_readlinkat)
453 _syscall4(int,sys_readlinkat
,int,dirfd
,const char *,pathname
,
454 char *,buf
,size_t,bufsize
)
456 #if defined(TARGET_NR_renameat) && defined(__NR_renameat)
457 _syscall4(int,sys_renameat
,int,olddirfd
,const char *,oldpath
,
458 int,newdirfd
,const char *,newpath
)
460 #if defined(TARGET_NR_symlinkat) && defined(__NR_symlinkat)
461 _syscall3(int,sys_symlinkat
,const char *,oldpath
,
462 int,newdirfd
,const char *,newpath
)
464 #if defined(TARGET_NR_unlinkat) && defined(__NR_unlinkat)
465 _syscall3(int,sys_unlinkat
,int,dirfd
,const char *,pathname
,int,flags
)
468 #endif /* CONFIG_ATFILE */
470 #ifdef CONFIG_UTIMENSAT
471 static int sys_utimensat(int dirfd
, const char *pathname
,
472 const struct timespec times
[2], int flags
)
474 if (pathname
== NULL
)
475 return futimens(dirfd
, times
);
477 return utimensat(dirfd
, pathname
, times
, flags
);
480 #if defined(TARGET_NR_utimensat) && defined(__NR_utimensat)
481 _syscall4(int,sys_utimensat
,int,dirfd
,const char *,pathname
,
482 const struct timespec
*,tsp
,int,flags
)
484 #endif /* CONFIG_UTIMENSAT */
486 #ifdef CONFIG_INOTIFY
487 #include <sys/inotify.h>
489 #if defined(TARGET_NR_inotify_init) && defined(__NR_inotify_init)
490 static int sys_inotify_init(void)
492 return (inotify_init());
495 #if defined(TARGET_NR_inotify_add_watch) && defined(__NR_inotify_add_watch)
496 static int sys_inotify_add_watch(int fd
,const char *pathname
, int32_t mask
)
498 return (inotify_add_watch(fd
, pathname
, mask
));
501 #if defined(TARGET_NR_inotify_rm_watch) && defined(__NR_inotify_rm_watch)
502 static int sys_inotify_rm_watch(int fd
, int32_t wd
)
504 return (inotify_rm_watch(fd
, wd
));
508 /* Userspace can usually survive runtime without inotify */
509 #undef TARGET_NR_inotify_init
510 #undef TARGET_NR_inotify_add_watch
511 #undef TARGET_NR_inotify_rm_watch
512 #endif /* CONFIG_INOTIFY */
515 extern int personality(int);
516 extern int flock(int, int);
517 extern int setfsuid(int);
518 extern int setfsgid(int);
519 extern int setgroups(int, gid_t
*);
521 #define ERRNO_TABLE_SIZE 1200
523 /* target_to_host_errno_table[] is initialized from
524 * host_to_target_errno_table[] in syscall_init(). */
525 static uint16_t target_to_host_errno_table
[ERRNO_TABLE_SIZE
] = {
529 * This list is the union of errno values overridden in asm-<arch>/errno.h
530 * minus the errnos that are not actually generic to all archs.
532 static uint16_t host_to_target_errno_table
[ERRNO_TABLE_SIZE
] = {
533 [EIDRM
] = TARGET_EIDRM
,
534 [ECHRNG
] = TARGET_ECHRNG
,
535 [EL2NSYNC
] = TARGET_EL2NSYNC
,
536 [EL3HLT
] = TARGET_EL3HLT
,
537 [EL3RST
] = TARGET_EL3RST
,
538 [ELNRNG
] = TARGET_ELNRNG
,
539 [EUNATCH
] = TARGET_EUNATCH
,
540 [ENOCSI
] = TARGET_ENOCSI
,
541 [EL2HLT
] = TARGET_EL2HLT
,
542 [EDEADLK
] = TARGET_EDEADLK
,
543 [ENOLCK
] = TARGET_ENOLCK
,
544 [EBADE
] = TARGET_EBADE
,
545 [EBADR
] = TARGET_EBADR
,
546 [EXFULL
] = TARGET_EXFULL
,
547 [ENOANO
] = TARGET_ENOANO
,
548 [EBADRQC
] = TARGET_EBADRQC
,
549 [EBADSLT
] = TARGET_EBADSLT
,
550 [EBFONT
] = TARGET_EBFONT
,
551 [ENOSTR
] = TARGET_ENOSTR
,
552 [ENODATA
] = TARGET_ENODATA
,
553 [ETIME
] = TARGET_ETIME
,
554 [ENOSR
] = TARGET_ENOSR
,
555 [ENONET
] = TARGET_ENONET
,
556 [ENOPKG
] = TARGET_ENOPKG
,
557 [EREMOTE
] = TARGET_EREMOTE
,
558 [ENOLINK
] = TARGET_ENOLINK
,
559 [EADV
] = TARGET_EADV
,
560 [ESRMNT
] = TARGET_ESRMNT
,
561 [ECOMM
] = TARGET_ECOMM
,
562 [EPROTO
] = TARGET_EPROTO
,
563 [EDOTDOT
] = TARGET_EDOTDOT
,
564 [EMULTIHOP
] = TARGET_EMULTIHOP
,
565 [EBADMSG
] = TARGET_EBADMSG
,
566 [ENAMETOOLONG
] = TARGET_ENAMETOOLONG
,
567 [EOVERFLOW
] = TARGET_EOVERFLOW
,
568 [ENOTUNIQ
] = TARGET_ENOTUNIQ
,
569 [EBADFD
] = TARGET_EBADFD
,
570 [EREMCHG
] = TARGET_EREMCHG
,
571 [ELIBACC
] = TARGET_ELIBACC
,
572 [ELIBBAD
] = TARGET_ELIBBAD
,
573 [ELIBSCN
] = TARGET_ELIBSCN
,
574 [ELIBMAX
] = TARGET_ELIBMAX
,
575 [ELIBEXEC
] = TARGET_ELIBEXEC
,
576 [EILSEQ
] = TARGET_EILSEQ
,
577 [ENOSYS
] = TARGET_ENOSYS
,
578 [ELOOP
] = TARGET_ELOOP
,
579 [ERESTART
] = TARGET_ERESTART
,
580 [ESTRPIPE
] = TARGET_ESTRPIPE
,
581 [ENOTEMPTY
] = TARGET_ENOTEMPTY
,
582 [EUSERS
] = TARGET_EUSERS
,
583 [ENOTSOCK
] = TARGET_ENOTSOCK
,
584 [EDESTADDRREQ
] = TARGET_EDESTADDRREQ
,
585 [EMSGSIZE
] = TARGET_EMSGSIZE
,
586 [EPROTOTYPE
] = TARGET_EPROTOTYPE
,
587 [ENOPROTOOPT
] = TARGET_ENOPROTOOPT
,
588 [EPROTONOSUPPORT
] = TARGET_EPROTONOSUPPORT
,
589 [ESOCKTNOSUPPORT
] = TARGET_ESOCKTNOSUPPORT
,
590 [EOPNOTSUPP
] = TARGET_EOPNOTSUPP
,
591 [EPFNOSUPPORT
] = TARGET_EPFNOSUPPORT
,
592 [EAFNOSUPPORT
] = TARGET_EAFNOSUPPORT
,
593 [EADDRINUSE
] = TARGET_EADDRINUSE
,
594 [EADDRNOTAVAIL
] = TARGET_EADDRNOTAVAIL
,
595 [ENETDOWN
] = TARGET_ENETDOWN
,
596 [ENETUNREACH
] = TARGET_ENETUNREACH
,
597 [ENETRESET
] = TARGET_ENETRESET
,
598 [ECONNABORTED
] = TARGET_ECONNABORTED
,
599 [ECONNRESET
] = TARGET_ECONNRESET
,
600 [ENOBUFS
] = TARGET_ENOBUFS
,
601 [EISCONN
] = TARGET_EISCONN
,
602 [ENOTCONN
] = TARGET_ENOTCONN
,
603 [EUCLEAN
] = TARGET_EUCLEAN
,
604 [ENOTNAM
] = TARGET_ENOTNAM
,
605 [ENAVAIL
] = TARGET_ENAVAIL
,
606 [EISNAM
] = TARGET_EISNAM
,
607 [EREMOTEIO
] = TARGET_EREMOTEIO
,
608 [ESHUTDOWN
] = TARGET_ESHUTDOWN
,
609 [ETOOMANYREFS
] = TARGET_ETOOMANYREFS
,
610 [ETIMEDOUT
] = TARGET_ETIMEDOUT
,
611 [ECONNREFUSED
] = TARGET_ECONNREFUSED
,
612 [EHOSTDOWN
] = TARGET_EHOSTDOWN
,
613 [EHOSTUNREACH
] = TARGET_EHOSTUNREACH
,
614 [EALREADY
] = TARGET_EALREADY
,
615 [EINPROGRESS
] = TARGET_EINPROGRESS
,
616 [ESTALE
] = TARGET_ESTALE
,
617 [ECANCELED
] = TARGET_ECANCELED
,
618 [ENOMEDIUM
] = TARGET_ENOMEDIUM
,
619 [EMEDIUMTYPE
] = TARGET_EMEDIUMTYPE
,
621 [ENOKEY
] = TARGET_ENOKEY
,
624 [EKEYEXPIRED
] = TARGET_EKEYEXPIRED
,
627 [EKEYREVOKED
] = TARGET_EKEYREVOKED
,
630 [EKEYREJECTED
] = TARGET_EKEYREJECTED
,
633 [EOWNERDEAD
] = TARGET_EOWNERDEAD
,
635 #ifdef ENOTRECOVERABLE
636 [ENOTRECOVERABLE
] = TARGET_ENOTRECOVERABLE
,
640 static inline int host_to_target_errno(int err
)
642 if(host_to_target_errno_table
[err
])
643 return host_to_target_errno_table
[err
];
647 static inline int target_to_host_errno(int err
)
649 if (target_to_host_errno_table
[err
])
650 return target_to_host_errno_table
[err
];
654 static inline abi_long
get_errno(abi_long ret
)
657 return -host_to_target_errno(errno
);
662 static inline int is_error(abi_long ret
)
664 return (abi_ulong
)ret
>= (abi_ulong
)(-4096);
667 char *target_strerror(int err
)
669 return strerror(target_to_host_errno(err
));
672 static abi_ulong target_brk
;
673 static abi_ulong target_original_brk
;
675 void target_set_brk(abi_ulong new_brk
)
677 target_original_brk
= target_brk
= HOST_PAGE_ALIGN(new_brk
);
680 /* do_brk() must return target values and target errnos. */
681 abi_long
do_brk(abi_ulong new_brk
)
684 abi_long mapped_addr
;
689 if (new_brk
< target_original_brk
)
692 brk_page
= HOST_PAGE_ALIGN(target_brk
);
694 /* If the new brk is less than this, set it and we're done... */
695 if (new_brk
< brk_page
) {
696 target_brk
= new_brk
;
700 /* We need to allocate more memory after the brk... */
701 new_alloc_size
= HOST_PAGE_ALIGN(new_brk
- brk_page
+ 1);
702 mapped_addr
= get_errno(target_mmap(brk_page
, new_alloc_size
,
703 PROT_READ
|PROT_WRITE
,
704 MAP_ANON
|MAP_FIXED
|MAP_PRIVATE
, 0, 0));
706 if (!is_error(mapped_addr
))
707 target_brk
= new_brk
;
712 static inline abi_long
copy_from_user_fdset(fd_set
*fds
,
713 abi_ulong target_fds_addr
,
717 abi_ulong b
, *target_fds
;
719 nw
= (n
+ TARGET_ABI_BITS
- 1) / TARGET_ABI_BITS
;
720 if (!(target_fds
= lock_user(VERIFY_READ
,
722 sizeof(abi_ulong
) * nw
,
724 return -TARGET_EFAULT
;
728 for (i
= 0; i
< nw
; i
++) {
729 /* grab the abi_ulong */
730 __get_user(b
, &target_fds
[i
]);
731 for (j
= 0; j
< TARGET_ABI_BITS
; j
++) {
732 /* check the bit inside the abi_ulong */
739 unlock_user(target_fds
, target_fds_addr
, 0);
744 static inline abi_long
copy_to_user_fdset(abi_ulong target_fds_addr
,
750 abi_ulong
*target_fds
;
752 nw
= (n
+ TARGET_ABI_BITS
- 1) / TARGET_ABI_BITS
;
753 if (!(target_fds
= lock_user(VERIFY_WRITE
,
755 sizeof(abi_ulong
) * nw
,
757 return -TARGET_EFAULT
;
760 for (i
= 0; i
< nw
; i
++) {
762 for (j
= 0; j
< TARGET_ABI_BITS
; j
++) {
763 v
|= ((FD_ISSET(k
, fds
) != 0) << j
);
766 __put_user(v
, &target_fds
[i
]);
769 unlock_user(target_fds
, target_fds_addr
, sizeof(abi_ulong
) * nw
);
774 #if defined(__alpha__)
780 static inline abi_long
host_to_target_clock_t(long ticks
)
782 #if HOST_HZ == TARGET_HZ
785 return ((int64_t)ticks
* TARGET_HZ
) / HOST_HZ
;
789 static inline abi_long
host_to_target_rusage(abi_ulong target_addr
,
790 const struct rusage
*rusage
)
792 struct target_rusage
*target_rusage
;
794 if (!lock_user_struct(VERIFY_WRITE
, target_rusage
, target_addr
, 0))
795 return -TARGET_EFAULT
;
796 target_rusage
->ru_utime
.tv_sec
= tswapl(rusage
->ru_utime
.tv_sec
);
797 target_rusage
->ru_utime
.tv_usec
= tswapl(rusage
->ru_utime
.tv_usec
);
798 target_rusage
->ru_stime
.tv_sec
= tswapl(rusage
->ru_stime
.tv_sec
);
799 target_rusage
->ru_stime
.tv_usec
= tswapl(rusage
->ru_stime
.tv_usec
);
800 target_rusage
->ru_maxrss
= tswapl(rusage
->ru_maxrss
);
801 target_rusage
->ru_ixrss
= tswapl(rusage
->ru_ixrss
);
802 target_rusage
->ru_idrss
= tswapl(rusage
->ru_idrss
);
803 target_rusage
->ru_isrss
= tswapl(rusage
->ru_isrss
);
804 target_rusage
->ru_minflt
= tswapl(rusage
->ru_minflt
);
805 target_rusage
->ru_majflt
= tswapl(rusage
->ru_majflt
);
806 target_rusage
->ru_nswap
= tswapl(rusage
->ru_nswap
);
807 target_rusage
->ru_inblock
= tswapl(rusage
->ru_inblock
);
808 target_rusage
->ru_oublock
= tswapl(rusage
->ru_oublock
);
809 target_rusage
->ru_msgsnd
= tswapl(rusage
->ru_msgsnd
);
810 target_rusage
->ru_msgrcv
= tswapl(rusage
->ru_msgrcv
);
811 target_rusage
->ru_nsignals
= tswapl(rusage
->ru_nsignals
);
812 target_rusage
->ru_nvcsw
= tswapl(rusage
->ru_nvcsw
);
813 target_rusage
->ru_nivcsw
= tswapl(rusage
->ru_nivcsw
);
814 unlock_user_struct(target_rusage
, target_addr
, 1);
819 static inline abi_long
copy_from_user_timeval(struct timeval
*tv
,
820 abi_ulong target_tv_addr
)
822 struct target_timeval
*target_tv
;
824 if (!lock_user_struct(VERIFY_READ
, target_tv
, target_tv_addr
, 1))
825 return -TARGET_EFAULT
;
827 __get_user(tv
->tv_sec
, &target_tv
->tv_sec
);
828 __get_user(tv
->tv_usec
, &target_tv
->tv_usec
);
830 unlock_user_struct(target_tv
, target_tv_addr
, 0);
835 static inline abi_long
copy_to_user_timeval(abi_ulong target_tv_addr
,
836 const struct timeval
*tv
)
838 struct target_timeval
*target_tv
;
840 if (!lock_user_struct(VERIFY_WRITE
, target_tv
, target_tv_addr
, 0))
841 return -TARGET_EFAULT
;
843 __put_user(tv
->tv_sec
, &target_tv
->tv_sec
);
844 __put_user(tv
->tv_usec
, &target_tv
->tv_usec
);
846 unlock_user_struct(target_tv
, target_tv_addr
, 1);
851 static inline abi_long
copy_from_user_mq_attr(struct mq_attr
*attr
,
852 abi_ulong target_mq_attr_addr
)
854 struct target_mq_attr
*target_mq_attr
;
856 if (!lock_user_struct(VERIFY_READ
, target_mq_attr
,
857 target_mq_attr_addr
, 1))
858 return -TARGET_EFAULT
;
860 __get_user(attr
->mq_flags
, &target_mq_attr
->mq_flags
);
861 __get_user(attr
->mq_maxmsg
, &target_mq_attr
->mq_maxmsg
);
862 __get_user(attr
->mq_msgsize
, &target_mq_attr
->mq_msgsize
);
863 __get_user(attr
->mq_curmsgs
, &target_mq_attr
->mq_curmsgs
);
865 unlock_user_struct(target_mq_attr
, target_mq_attr_addr
, 0);
870 static inline abi_long
copy_to_user_mq_attr(abi_ulong target_mq_attr_addr
,
871 const struct mq_attr
*attr
)
873 struct target_mq_attr
*target_mq_attr
;
875 if (!lock_user_struct(VERIFY_WRITE
, target_mq_attr
,
876 target_mq_attr_addr
, 0))
877 return -TARGET_EFAULT
;
879 __put_user(attr
->mq_flags
, &target_mq_attr
->mq_flags
);
880 __put_user(attr
->mq_maxmsg
, &target_mq_attr
->mq_maxmsg
);
881 __put_user(attr
->mq_msgsize
, &target_mq_attr
->mq_msgsize
);
882 __put_user(attr
->mq_curmsgs
, &target_mq_attr
->mq_curmsgs
);
884 unlock_user_struct(target_mq_attr
, target_mq_attr_addr
, 1);
889 /* do_select() must return target values and target errnos. */
890 static abi_long
do_select(int n
,
891 abi_ulong rfd_addr
, abi_ulong wfd_addr
,
892 abi_ulong efd_addr
, abi_ulong target_tv_addr
)
894 fd_set rfds
, wfds
, efds
;
895 fd_set
*rfds_ptr
, *wfds_ptr
, *efds_ptr
;
896 struct timeval tv
, *tv_ptr
;
900 if (copy_from_user_fdset(&rfds
, rfd_addr
, n
))
901 return -TARGET_EFAULT
;
907 if (copy_from_user_fdset(&wfds
, wfd_addr
, n
))
908 return -TARGET_EFAULT
;
914 if (copy_from_user_fdset(&efds
, efd_addr
, n
))
915 return -TARGET_EFAULT
;
921 if (target_tv_addr
) {
922 if (copy_from_user_timeval(&tv
, target_tv_addr
))
923 return -TARGET_EFAULT
;
929 ret
= get_errno(select(n
, rfds_ptr
, wfds_ptr
, efds_ptr
, tv_ptr
));
931 if (!is_error(ret
)) {
932 if (rfd_addr
&& copy_to_user_fdset(rfd_addr
, &rfds
, n
))
933 return -TARGET_EFAULT
;
934 if (wfd_addr
&& copy_to_user_fdset(wfd_addr
, &wfds
, n
))
935 return -TARGET_EFAULT
;
936 if (efd_addr
&& copy_to_user_fdset(efd_addr
, &efds
, n
))
937 return -TARGET_EFAULT
;
939 if (target_tv_addr
&& copy_to_user_timeval(target_tv_addr
, &tv
))
940 return -TARGET_EFAULT
;
946 static inline abi_long
target_to_host_sockaddr(struct sockaddr
*addr
,
947 abi_ulong target_addr
,
950 const socklen_t unix_maxlen
= sizeof (struct sockaddr_un
);
951 sa_family_t sa_family
;
952 struct target_sockaddr
*target_saddr
;
954 target_saddr
= lock_user(VERIFY_READ
, target_addr
, len
, 1);
956 return -TARGET_EFAULT
;
958 sa_family
= tswap16(target_saddr
->sa_family
);
960 /* Oops. The caller might send a incomplete sun_path; sun_path
961 * must be terminated by \0 (see the manual page), but
962 * unfortunately it is quite common to specify sockaddr_un
963 * length as "strlen(x->sun_path)" while it should be
964 * "strlen(...) + 1". We'll fix that here if needed.
965 * Linux kernel has a similar feature.
968 if (sa_family
== AF_UNIX
) {
969 if (len
< unix_maxlen
&& len
> 0) {
970 char *cp
= (char*)target_saddr
;
972 if ( cp
[len
-1] && !cp
[len
] )
975 if (len
> unix_maxlen
)
979 memcpy(addr
, target_saddr
, len
);
980 addr
->sa_family
= sa_family
;
981 unlock_user(target_saddr
, target_addr
, 0);
986 static inline abi_long
host_to_target_sockaddr(abi_ulong target_addr
,
987 struct sockaddr
*addr
,
990 struct target_sockaddr
*target_saddr
;
992 target_saddr
= lock_user(VERIFY_WRITE
, target_addr
, len
, 0);
994 return -TARGET_EFAULT
;
995 memcpy(target_saddr
, addr
, len
);
996 target_saddr
->sa_family
= tswap16(addr
->sa_family
);
997 unlock_user(target_saddr
, target_addr
, len
);
1002 /* ??? Should this also swap msgh->name? */
1003 static inline abi_long
target_to_host_cmsg(struct msghdr
*msgh
,
1004 struct target_msghdr
*target_msgh
)
1006 struct cmsghdr
*cmsg
= CMSG_FIRSTHDR(msgh
);
1007 abi_long msg_controllen
;
1008 abi_ulong target_cmsg_addr
;
1009 struct target_cmsghdr
*target_cmsg
;
1010 socklen_t space
= 0;
1012 msg_controllen
= tswapl(target_msgh
->msg_controllen
);
1013 if (msg_controllen
< sizeof (struct target_cmsghdr
))
1015 target_cmsg_addr
= tswapl(target_msgh
->msg_control
);
1016 target_cmsg
= lock_user(VERIFY_READ
, target_cmsg_addr
, msg_controllen
, 1);
1018 return -TARGET_EFAULT
;
1020 while (cmsg
&& target_cmsg
) {
1021 void *data
= CMSG_DATA(cmsg
);
1022 void *target_data
= TARGET_CMSG_DATA(target_cmsg
);
1024 int len
= tswapl(target_cmsg
->cmsg_len
)
1025 - TARGET_CMSG_ALIGN(sizeof (struct target_cmsghdr
));
1027 space
+= CMSG_SPACE(len
);
1028 if (space
> msgh
->msg_controllen
) {
1029 space
-= CMSG_SPACE(len
);
1030 gemu_log("Host cmsg overflow\n");
1034 cmsg
->cmsg_level
= tswap32(target_cmsg
->cmsg_level
);
1035 cmsg
->cmsg_type
= tswap32(target_cmsg
->cmsg_type
);
1036 cmsg
->cmsg_len
= CMSG_LEN(len
);
1038 if (cmsg
->cmsg_level
!= TARGET_SOL_SOCKET
|| cmsg
->cmsg_type
!= SCM_RIGHTS
) {
1039 gemu_log("Unsupported ancillary data: %d/%d\n", cmsg
->cmsg_level
, cmsg
->cmsg_type
);
1040 memcpy(data
, target_data
, len
);
1042 int *fd
= (int *)data
;
1043 int *target_fd
= (int *)target_data
;
1044 int i
, numfds
= len
/ sizeof(int);
1046 for (i
= 0; i
< numfds
; i
++)
1047 fd
[i
] = tswap32(target_fd
[i
]);
1050 cmsg
= CMSG_NXTHDR(msgh
, cmsg
);
1051 target_cmsg
= TARGET_CMSG_NXTHDR(target_msgh
, target_cmsg
);
1053 unlock_user(target_cmsg
, target_cmsg_addr
, 0);
1055 msgh
->msg_controllen
= space
;
1059 /* ??? Should this also swap msgh->name? */
1060 static inline abi_long
host_to_target_cmsg(struct target_msghdr
*target_msgh
,
1061 struct msghdr
*msgh
)
1063 struct cmsghdr
*cmsg
= CMSG_FIRSTHDR(msgh
);
1064 abi_long msg_controllen
;
1065 abi_ulong target_cmsg_addr
;
1066 struct target_cmsghdr
*target_cmsg
;
1067 socklen_t space
= 0;
1069 msg_controllen
= tswapl(target_msgh
->msg_controllen
);
1070 if (msg_controllen
< sizeof (struct target_cmsghdr
))
1072 target_cmsg_addr
= tswapl(target_msgh
->msg_control
);
1073 target_cmsg
= lock_user(VERIFY_WRITE
, target_cmsg_addr
, msg_controllen
, 0);
1075 return -TARGET_EFAULT
;
1077 while (cmsg
&& target_cmsg
) {
1078 void *data
= CMSG_DATA(cmsg
);
1079 void *target_data
= TARGET_CMSG_DATA(target_cmsg
);
1081 int len
= cmsg
->cmsg_len
- CMSG_ALIGN(sizeof (struct cmsghdr
));
1083 space
+= TARGET_CMSG_SPACE(len
);
1084 if (space
> msg_controllen
) {
1085 space
-= TARGET_CMSG_SPACE(len
);
1086 gemu_log("Target cmsg overflow\n");
1090 target_cmsg
->cmsg_level
= tswap32(cmsg
->cmsg_level
);
1091 target_cmsg
->cmsg_type
= tswap32(cmsg
->cmsg_type
);
1092 target_cmsg
->cmsg_len
= tswapl(TARGET_CMSG_LEN(len
));
1094 if (cmsg
->cmsg_level
!= TARGET_SOL_SOCKET
|| cmsg
->cmsg_type
!= SCM_RIGHTS
) {
1095 gemu_log("Unsupported ancillary data: %d/%d\n", cmsg
->cmsg_level
, cmsg
->cmsg_type
);
1096 memcpy(target_data
, data
, len
);
1098 int *fd
= (int *)data
;
1099 int *target_fd
= (int *)target_data
;
1100 int i
, numfds
= len
/ sizeof(int);
1102 for (i
= 0; i
< numfds
; i
++)
1103 target_fd
[i
] = tswap32(fd
[i
]);
1106 cmsg
= CMSG_NXTHDR(msgh
, cmsg
);
1107 target_cmsg
= TARGET_CMSG_NXTHDR(target_msgh
, target_cmsg
);
1109 unlock_user(target_cmsg
, target_cmsg_addr
, space
);
1111 target_msgh
->msg_controllen
= tswapl(space
);
1115 /* do_setsockopt() Must return target values and target errnos. */
1116 static abi_long
do_setsockopt(int sockfd
, int level
, int optname
,
1117 abi_ulong optval_addr
, socklen_t optlen
)
1124 /* TCP options all take an 'int' value. */
1125 if (optlen
< sizeof(uint32_t))
1126 return -TARGET_EINVAL
;
1128 if (get_user_u32(val
, optval_addr
))
1129 return -TARGET_EFAULT
;
1130 ret
= get_errno(setsockopt(sockfd
, level
, optname
, &val
, sizeof(val
)));
1137 case IP_ROUTER_ALERT
:
1141 case IP_MTU_DISCOVER
:
1147 case IP_MULTICAST_TTL
:
1148 case IP_MULTICAST_LOOP
:
1150 if (optlen
>= sizeof(uint32_t)) {
1151 if (get_user_u32(val
, optval_addr
))
1152 return -TARGET_EFAULT
;
1153 } else if (optlen
>= 1) {
1154 if (get_user_u8(val
, optval_addr
))
1155 return -TARGET_EFAULT
;
1157 ret
= get_errno(setsockopt(sockfd
, level
, optname
, &val
, sizeof(val
)));
1163 case TARGET_SOL_SOCKET
:
1165 /* Options with 'int' argument. */
1166 case TARGET_SO_DEBUG
:
1169 case TARGET_SO_REUSEADDR
:
1170 optname
= SO_REUSEADDR
;
1172 case TARGET_SO_TYPE
:
1175 case TARGET_SO_ERROR
:
1178 case TARGET_SO_DONTROUTE
:
1179 optname
= SO_DONTROUTE
;
1181 case TARGET_SO_BROADCAST
:
1182 optname
= SO_BROADCAST
;
1184 case TARGET_SO_SNDBUF
:
1185 optname
= SO_SNDBUF
;
1187 case TARGET_SO_RCVBUF
:
1188 optname
= SO_RCVBUF
;
1190 case TARGET_SO_KEEPALIVE
:
1191 optname
= SO_KEEPALIVE
;
1193 case TARGET_SO_OOBINLINE
:
1194 optname
= SO_OOBINLINE
;
1196 case TARGET_SO_NO_CHECK
:
1197 optname
= SO_NO_CHECK
;
1199 case TARGET_SO_PRIORITY
:
1200 optname
= SO_PRIORITY
;
1203 case TARGET_SO_BSDCOMPAT
:
1204 optname
= SO_BSDCOMPAT
;
1207 case TARGET_SO_PASSCRED
:
1208 optname
= SO_PASSCRED
;
1210 case TARGET_SO_TIMESTAMP
:
1211 optname
= SO_TIMESTAMP
;
1213 case TARGET_SO_RCVLOWAT
:
1214 optname
= SO_RCVLOWAT
;
1216 case TARGET_SO_RCVTIMEO
:
1217 optname
= SO_RCVTIMEO
;
1219 case TARGET_SO_SNDTIMEO
:
1220 optname
= SO_SNDTIMEO
;
1226 if (optlen
< sizeof(uint32_t))
1227 return -TARGET_EINVAL
;
1229 if (get_user_u32(val
, optval_addr
))
1230 return -TARGET_EFAULT
;
1231 ret
= get_errno(setsockopt(sockfd
, SOL_SOCKET
, optname
, &val
, sizeof(val
)));
1235 gemu_log("Unsupported setsockopt level=%d optname=%d \n", level
, optname
);
1236 ret
= -TARGET_ENOPROTOOPT
;
1241 /* do_getsockopt() Must return target values and target errnos. */
1242 static abi_long
do_getsockopt(int sockfd
, int level
, int optname
,
1243 abi_ulong optval_addr
, abi_ulong optlen
)
1250 case TARGET_SOL_SOCKET
:
1253 case TARGET_SO_LINGER
:
1254 case TARGET_SO_RCVTIMEO
:
1255 case TARGET_SO_SNDTIMEO
:
1256 case TARGET_SO_PEERCRED
:
1257 case TARGET_SO_PEERNAME
:
1258 /* These don't just return a single integer */
1265 /* TCP options all take an 'int' value. */
1267 if (get_user_u32(len
, optlen
))
1268 return -TARGET_EFAULT
;
1270 return -TARGET_EINVAL
;
1272 ret
= get_errno(getsockopt(sockfd
, level
, optname
, &val
, &lv
));
1279 if (put_user_u32(val
, optval_addr
))
1280 return -TARGET_EFAULT
;
1282 if (put_user_u8(val
, optval_addr
))
1283 return -TARGET_EFAULT
;
1285 if (put_user_u32(len
, optlen
))
1286 return -TARGET_EFAULT
;
1293 case IP_ROUTER_ALERT
:
1297 case IP_MTU_DISCOVER
:
1303 case IP_MULTICAST_TTL
:
1304 case IP_MULTICAST_LOOP
:
1305 if (get_user_u32(len
, optlen
))
1306 return -TARGET_EFAULT
;
1308 return -TARGET_EINVAL
;
1310 ret
= get_errno(getsockopt(sockfd
, level
, optname
, &val
, &lv
));
1313 if (len
< sizeof(int) && len
> 0 && val
>= 0 && val
< 255) {
1315 if (put_user_u32(len
, optlen
)
1316 || put_user_u8(val
, optval_addr
))
1317 return -TARGET_EFAULT
;
1319 if (len
> sizeof(int))
1321 if (put_user_u32(len
, optlen
)
1322 || put_user_u32(val
, optval_addr
))
1323 return -TARGET_EFAULT
;
1327 ret
= -TARGET_ENOPROTOOPT
;
1333 gemu_log("getsockopt level=%d optname=%d not yet supported\n",
1335 ret
= -TARGET_EOPNOTSUPP
;
1342 * lock_iovec()/unlock_iovec() have a return code of 0 for success where
1343 * other lock functions have a return code of 0 for failure.
1345 static abi_long
lock_iovec(int type
, struct iovec
*vec
, abi_ulong target_addr
,
1346 int count
, int copy
)
1348 struct target_iovec
*target_vec
;
1352 target_vec
= lock_user(VERIFY_READ
, target_addr
, count
* sizeof(struct target_iovec
), 1);
1354 return -TARGET_EFAULT
;
1355 for(i
= 0;i
< count
; i
++) {
1356 base
= tswapl(target_vec
[i
].iov_base
);
1357 vec
[i
].iov_len
= tswapl(target_vec
[i
].iov_len
);
1358 if (vec
[i
].iov_len
!= 0) {
1359 vec
[i
].iov_base
= lock_user(type
, base
, vec
[i
].iov_len
, copy
);
1360 /* Don't check lock_user return value. We must call writev even
1361 if a element has invalid base address. */
1363 /* zero length pointer is ignored */
1364 vec
[i
].iov_base
= NULL
;
1367 unlock_user (target_vec
, target_addr
, 0);
1371 static abi_long
unlock_iovec(struct iovec
*vec
, abi_ulong target_addr
,
1372 int count
, int copy
)
1374 struct target_iovec
*target_vec
;
1378 target_vec
= lock_user(VERIFY_READ
, target_addr
, count
* sizeof(struct target_iovec
), 1);
1380 return -TARGET_EFAULT
;
1381 for(i
= 0;i
< count
; i
++) {
1382 if (target_vec
[i
].iov_base
) {
1383 base
= tswapl(target_vec
[i
].iov_base
);
1384 unlock_user(vec
[i
].iov_base
, base
, copy
? vec
[i
].iov_len
: 0);
1387 unlock_user (target_vec
, target_addr
, 0);
1392 /* do_socket() Must return target values and target errnos. */
1393 static abi_long
do_socket(int domain
, int type
, int protocol
)
1395 #if defined(TARGET_MIPS)
1397 case TARGET_SOCK_DGRAM
:
1400 case TARGET_SOCK_STREAM
:
1403 case TARGET_SOCK_RAW
:
1406 case TARGET_SOCK_RDM
:
1409 case TARGET_SOCK_SEQPACKET
:
1410 type
= SOCK_SEQPACKET
;
1412 case TARGET_SOCK_PACKET
:
1417 if (domain
== PF_NETLINK
)
1418 return -EAFNOSUPPORT
; /* do not NETLINK socket connections possible */
1419 return get_errno(socket(domain
, type
, protocol
));
1422 /* do_bind() Must return target values and target errnos. */
1423 static abi_long
do_bind(int sockfd
, abi_ulong target_addr
,
1429 return -TARGET_EINVAL
;
1431 addr
= alloca(addrlen
+1);
1433 target_to_host_sockaddr(addr
, target_addr
, addrlen
);
1434 return get_errno(bind(sockfd
, addr
, addrlen
));
1437 /* do_connect() Must return target values and target errnos. */
1438 static abi_long
do_connect(int sockfd
, abi_ulong target_addr
,
1444 return -TARGET_EINVAL
;
1446 addr
= alloca(addrlen
);
1448 target_to_host_sockaddr(addr
, target_addr
, addrlen
);
1449 return get_errno(connect(sockfd
, addr
, addrlen
));
1452 /* do_sendrecvmsg() Must return target values and target errnos. */
1453 static abi_long
do_sendrecvmsg(int fd
, abi_ulong target_msg
,
1454 int flags
, int send
)
1457 struct target_msghdr
*msgp
;
1461 abi_ulong target_vec
;
1464 if (!lock_user_struct(send
? VERIFY_READ
: VERIFY_WRITE
,
1468 return -TARGET_EFAULT
;
1469 if (msgp
->msg_name
) {
1470 msg
.msg_namelen
= tswap32(msgp
->msg_namelen
);
1471 msg
.msg_name
= alloca(msg
.msg_namelen
);
1472 target_to_host_sockaddr(msg
.msg_name
, tswapl(msgp
->msg_name
),
1475 msg
.msg_name
= NULL
;
1476 msg
.msg_namelen
= 0;
1478 msg
.msg_controllen
= 2 * tswapl(msgp
->msg_controllen
);
1479 msg
.msg_control
= alloca(msg
.msg_controllen
);
1480 msg
.msg_flags
= tswap32(msgp
->msg_flags
);
1482 count
= tswapl(msgp
->msg_iovlen
);
1483 vec
= alloca(count
* sizeof(struct iovec
));
1484 target_vec
= tswapl(msgp
->msg_iov
);
1485 lock_iovec(send
? VERIFY_READ
: VERIFY_WRITE
, vec
, target_vec
, count
, send
);
1486 msg
.msg_iovlen
= count
;
1490 ret
= target_to_host_cmsg(&msg
, msgp
);
1492 ret
= get_errno(sendmsg(fd
, &msg
, flags
));
1494 ret
= get_errno(recvmsg(fd
, &msg
, flags
));
1495 if (!is_error(ret
)) {
1497 ret
= host_to_target_cmsg(msgp
, &msg
);
1502 unlock_iovec(vec
, target_vec
, count
, !send
);
1503 unlock_user_struct(msgp
, target_msg
, send
? 0 : 1);
1507 /* do_accept() Must return target values and target errnos. */
1508 static abi_long
do_accept(int fd
, abi_ulong target_addr
,
1509 abi_ulong target_addrlen_addr
)
1515 if (get_user_u32(addrlen
, target_addrlen_addr
))
1516 return -TARGET_EFAULT
;
1519 return -TARGET_EINVAL
;
1521 addr
= alloca(addrlen
);
1523 ret
= get_errno(accept(fd
, addr
, &addrlen
));
1524 if (!is_error(ret
)) {
1525 host_to_target_sockaddr(target_addr
, addr
, addrlen
);
1526 if (put_user_u32(addrlen
, target_addrlen_addr
))
1527 ret
= -TARGET_EFAULT
;
1532 /* do_getpeername() Must return target values and target errnos. */
1533 static abi_long
do_getpeername(int fd
, abi_ulong target_addr
,
1534 abi_ulong target_addrlen_addr
)
1540 if (get_user_u32(addrlen
, target_addrlen_addr
))
1541 return -TARGET_EFAULT
;
1544 return -TARGET_EINVAL
;
1546 addr
= alloca(addrlen
);
1548 ret
= get_errno(getpeername(fd
, addr
, &addrlen
));
1549 if (!is_error(ret
)) {
1550 host_to_target_sockaddr(target_addr
, addr
, addrlen
);
1551 if (put_user_u32(addrlen
, target_addrlen_addr
))
1552 ret
= -TARGET_EFAULT
;
1557 /* do_getsockname() Must return target values and target errnos. */
1558 static abi_long
do_getsockname(int fd
, abi_ulong target_addr
,
1559 abi_ulong target_addrlen_addr
)
1565 if (target_addr
== 0)
1566 return get_errno(accept(fd
, NULL
, NULL
));
1568 if (get_user_u32(addrlen
, target_addrlen_addr
))
1569 return -TARGET_EFAULT
;
1572 return -TARGET_EINVAL
;
1574 addr
= alloca(addrlen
);
1576 ret
= get_errno(getsockname(fd
, addr
, &addrlen
));
1577 if (!is_error(ret
)) {
1578 host_to_target_sockaddr(target_addr
, addr
, addrlen
);
1579 if (put_user_u32(addrlen
, target_addrlen_addr
))
1580 ret
= -TARGET_EFAULT
;
1585 /* do_socketpair() Must return target values and target errnos. */
1586 static abi_long
do_socketpair(int domain
, int type
, int protocol
,
1587 abi_ulong target_tab_addr
)
1592 ret
= get_errno(socketpair(domain
, type
, protocol
, tab
));
1593 if (!is_error(ret
)) {
1594 if (put_user_s32(tab
[0], target_tab_addr
)
1595 || put_user_s32(tab
[1], target_tab_addr
+ sizeof(tab
[0])))
1596 ret
= -TARGET_EFAULT
;
1601 /* do_sendto() Must return target values and target errnos. */
1602 static abi_long
do_sendto(int fd
, abi_ulong msg
, size_t len
, int flags
,
1603 abi_ulong target_addr
, socklen_t addrlen
)
1610 return -TARGET_EINVAL
;
1612 host_msg
= lock_user(VERIFY_READ
, msg
, len
, 1);
1614 return -TARGET_EFAULT
;
1616 addr
= alloca(addrlen
);
1617 target_to_host_sockaddr(addr
, target_addr
, addrlen
);
1618 ret
= get_errno(sendto(fd
, host_msg
, len
, flags
, addr
, addrlen
));
1620 ret
= get_errno(send(fd
, host_msg
, len
, flags
));
1622 unlock_user(host_msg
, msg
, 0);
1626 /* do_recvfrom() Must return target values and target errnos. */
1627 static abi_long
do_recvfrom(int fd
, abi_ulong msg
, size_t len
, int flags
,
1628 abi_ulong target_addr
,
1629 abi_ulong target_addrlen
)
1636 host_msg
= lock_user(VERIFY_WRITE
, msg
, len
, 0);
1638 return -TARGET_EFAULT
;
1640 if (get_user_u32(addrlen
, target_addrlen
)) {
1641 ret
= -TARGET_EFAULT
;
1645 ret
= -TARGET_EINVAL
;
1648 addr
= alloca(addrlen
);
1649 ret
= get_errno(recvfrom(fd
, host_msg
, len
, flags
, addr
, &addrlen
));
1651 addr
= NULL
; /* To keep compiler quiet. */
1652 ret
= get_errno(recv(fd
, host_msg
, len
, flags
));
1654 if (!is_error(ret
)) {
1656 host_to_target_sockaddr(target_addr
, addr
, addrlen
);
1657 if (put_user_u32(addrlen
, target_addrlen
)) {
1658 ret
= -TARGET_EFAULT
;
1662 unlock_user(host_msg
, msg
, len
);
1665 unlock_user(host_msg
, msg
, 0);
1670 #ifdef TARGET_NR_socketcall
1671 /* do_socketcall() Must return target values and target errnos. */
1672 static abi_long
do_socketcall(int num
, abi_ulong vptr
)
1675 const int n
= sizeof(abi_ulong
);
1680 int domain
, type
, protocol
;
1682 if (get_user_s32(domain
, vptr
)
1683 || get_user_s32(type
, vptr
+ n
)
1684 || get_user_s32(protocol
, vptr
+ 2 * n
))
1685 return -TARGET_EFAULT
;
1687 ret
= do_socket(domain
, type
, protocol
);
1693 abi_ulong target_addr
;
1696 if (get_user_s32(sockfd
, vptr
)
1697 || get_user_ual(target_addr
, vptr
+ n
)
1698 || get_user_u32(addrlen
, vptr
+ 2 * n
))
1699 return -TARGET_EFAULT
;
1701 ret
= do_bind(sockfd
, target_addr
, addrlen
);
1704 case SOCKOP_connect
:
1707 abi_ulong target_addr
;
1710 if (get_user_s32(sockfd
, vptr
)
1711 || get_user_ual(target_addr
, vptr
+ n
)
1712 || get_user_u32(addrlen
, vptr
+ 2 * n
))
1713 return -TARGET_EFAULT
;
1715 ret
= do_connect(sockfd
, target_addr
, addrlen
);
1720 int sockfd
, backlog
;
1722 if (get_user_s32(sockfd
, vptr
)
1723 || get_user_s32(backlog
, vptr
+ n
))
1724 return -TARGET_EFAULT
;
1726 ret
= get_errno(listen(sockfd
, backlog
));
1732 abi_ulong target_addr
, target_addrlen
;
1734 if (get_user_s32(sockfd
, vptr
)
1735 || get_user_ual(target_addr
, vptr
+ n
)
1736 || get_user_u32(target_addrlen
, vptr
+ 2 * n
))
1737 return -TARGET_EFAULT
;
1739 ret
= do_accept(sockfd
, target_addr
, target_addrlen
);
1742 case SOCKOP_getsockname
:
1745 abi_ulong target_addr
, target_addrlen
;
1747 if (get_user_s32(sockfd
, vptr
)
1748 || get_user_ual(target_addr
, vptr
+ n
)
1749 || get_user_u32(target_addrlen
, vptr
+ 2 * n
))
1750 return -TARGET_EFAULT
;
1752 ret
= do_getsockname(sockfd
, target_addr
, target_addrlen
);
1755 case SOCKOP_getpeername
:
1758 abi_ulong target_addr
, target_addrlen
;
1760 if (get_user_s32(sockfd
, vptr
)
1761 || get_user_ual(target_addr
, vptr
+ n
)
1762 || get_user_u32(target_addrlen
, vptr
+ 2 * n
))
1763 return -TARGET_EFAULT
;
1765 ret
= do_getpeername(sockfd
, target_addr
, target_addrlen
);
1768 case SOCKOP_socketpair
:
1770 int domain
, type
, protocol
;
1773 if (get_user_s32(domain
, vptr
)
1774 || get_user_s32(type
, vptr
+ n
)
1775 || get_user_s32(protocol
, vptr
+ 2 * n
)
1776 || get_user_ual(tab
, vptr
+ 3 * n
))
1777 return -TARGET_EFAULT
;
1779 ret
= do_socketpair(domain
, type
, protocol
, tab
);
1789 if (get_user_s32(sockfd
, vptr
)
1790 || get_user_ual(msg
, vptr
+ n
)
1791 || get_user_ual(len
, vptr
+ 2 * n
)
1792 || get_user_s32(flags
, vptr
+ 3 * n
))
1793 return -TARGET_EFAULT
;
1795 ret
= do_sendto(sockfd
, msg
, len
, flags
, 0, 0);
1805 if (get_user_s32(sockfd
, vptr
)
1806 || get_user_ual(msg
, vptr
+ n
)
1807 || get_user_ual(len
, vptr
+ 2 * n
)
1808 || get_user_s32(flags
, vptr
+ 3 * n
))
1809 return -TARGET_EFAULT
;
1811 ret
= do_recvfrom(sockfd
, msg
, len
, flags
, 0, 0);
1823 if (get_user_s32(sockfd
, vptr
)
1824 || get_user_ual(msg
, vptr
+ n
)
1825 || get_user_ual(len
, vptr
+ 2 * n
)
1826 || get_user_s32(flags
, vptr
+ 3 * n
)
1827 || get_user_ual(addr
, vptr
+ 4 * n
)
1828 || get_user_u32(addrlen
, vptr
+ 5 * n
))
1829 return -TARGET_EFAULT
;
1831 ret
= do_sendto(sockfd
, msg
, len
, flags
, addr
, addrlen
);
1834 case SOCKOP_recvfrom
:
1843 if (get_user_s32(sockfd
, vptr
)
1844 || get_user_ual(msg
, vptr
+ n
)
1845 || get_user_ual(len
, vptr
+ 2 * n
)
1846 || get_user_s32(flags
, vptr
+ 3 * n
)
1847 || get_user_ual(addr
, vptr
+ 4 * n
)
1848 || get_user_u32(addrlen
, vptr
+ 5 * n
))
1849 return -TARGET_EFAULT
;
1851 ret
= do_recvfrom(sockfd
, msg
, len
, flags
, addr
, addrlen
);
1854 case SOCKOP_shutdown
:
1858 if (get_user_s32(sockfd
, vptr
)
1859 || get_user_s32(how
, vptr
+ n
))
1860 return -TARGET_EFAULT
;
1862 ret
= get_errno(shutdown(sockfd
, how
));
1865 case SOCKOP_sendmsg
:
1866 case SOCKOP_recvmsg
:
1869 abi_ulong target_msg
;
1872 if (get_user_s32(fd
, vptr
)
1873 || get_user_ual(target_msg
, vptr
+ n
)
1874 || get_user_s32(flags
, vptr
+ 2 * n
))
1875 return -TARGET_EFAULT
;
1877 ret
= do_sendrecvmsg(fd
, target_msg
, flags
,
1878 (num
== SOCKOP_sendmsg
));
1881 case SOCKOP_setsockopt
:
1889 if (get_user_s32(sockfd
, vptr
)
1890 || get_user_s32(level
, vptr
+ n
)
1891 || get_user_s32(optname
, vptr
+ 2 * n
)
1892 || get_user_ual(optval
, vptr
+ 3 * n
)
1893 || get_user_u32(optlen
, vptr
+ 4 * n
))
1894 return -TARGET_EFAULT
;
1896 ret
= do_setsockopt(sockfd
, level
, optname
, optval
, optlen
);
1899 case SOCKOP_getsockopt
:
1907 if (get_user_s32(sockfd
, vptr
)
1908 || get_user_s32(level
, vptr
+ n
)
1909 || get_user_s32(optname
, vptr
+ 2 * n
)
1910 || get_user_ual(optval
, vptr
+ 3 * n
)
1911 || get_user_u32(optlen
, vptr
+ 4 * n
))
1912 return -TARGET_EFAULT
;
1914 ret
= do_getsockopt(sockfd
, level
, optname
, optval
, optlen
);
1918 gemu_log("Unsupported socketcall: %d\n", num
);
1919 ret
= -TARGET_ENOSYS
;
1926 #define N_SHM_REGIONS 32
1928 static struct shm_region
{
1931 } shm_regions
[N_SHM_REGIONS
];
1933 struct target_ipc_perm
1940 unsigned short int mode
;
1941 unsigned short int __pad1
;
1942 unsigned short int __seq
;
1943 unsigned short int __pad2
;
1944 abi_ulong __unused1
;
1945 abi_ulong __unused2
;
1948 struct target_semid_ds
1950 struct target_ipc_perm sem_perm
;
1951 abi_ulong sem_otime
;
1952 abi_ulong __unused1
;
1953 abi_ulong sem_ctime
;
1954 abi_ulong __unused2
;
1955 abi_ulong sem_nsems
;
1956 abi_ulong __unused3
;
1957 abi_ulong __unused4
;
1960 static inline abi_long
target_to_host_ipc_perm(struct ipc_perm
*host_ip
,
1961 abi_ulong target_addr
)
1963 struct target_ipc_perm
*target_ip
;
1964 struct target_semid_ds
*target_sd
;
1966 if (!lock_user_struct(VERIFY_READ
, target_sd
, target_addr
, 1))
1967 return -TARGET_EFAULT
;
1968 target_ip
=&(target_sd
->sem_perm
);
1969 host_ip
->__key
= tswapl(target_ip
->__key
);
1970 host_ip
->uid
= tswapl(target_ip
->uid
);
1971 host_ip
->gid
= tswapl(target_ip
->gid
);
1972 host_ip
->cuid
= tswapl(target_ip
->cuid
);
1973 host_ip
->cgid
= tswapl(target_ip
->cgid
);
1974 host_ip
->mode
= tswapl(target_ip
->mode
);
1975 unlock_user_struct(target_sd
, target_addr
, 0);
1979 static inline abi_long
host_to_target_ipc_perm(abi_ulong target_addr
,
1980 struct ipc_perm
*host_ip
)
1982 struct target_ipc_perm
*target_ip
;
1983 struct target_semid_ds
*target_sd
;
1985 if (!lock_user_struct(VERIFY_WRITE
, target_sd
, target_addr
, 0))
1986 return -TARGET_EFAULT
;
1987 target_ip
= &(target_sd
->sem_perm
);
1988 target_ip
->__key
= tswapl(host_ip
->__key
);
1989 target_ip
->uid
= tswapl(host_ip
->uid
);
1990 target_ip
->gid
= tswapl(host_ip
->gid
);
1991 target_ip
->cuid
= tswapl(host_ip
->cuid
);
1992 target_ip
->cgid
= tswapl(host_ip
->cgid
);
1993 target_ip
->mode
= tswapl(host_ip
->mode
);
1994 unlock_user_struct(target_sd
, target_addr
, 1);
1998 static inline abi_long
target_to_host_semid_ds(struct semid_ds
*host_sd
,
1999 abi_ulong target_addr
)
2001 struct target_semid_ds
*target_sd
;
2003 if (!lock_user_struct(VERIFY_READ
, target_sd
, target_addr
, 1))
2004 return -TARGET_EFAULT
;
2005 if (target_to_host_ipc_perm(&(host_sd
->sem_perm
),target_addr
))
2006 return -TARGET_EFAULT
;
2007 host_sd
->sem_nsems
= tswapl(target_sd
->sem_nsems
);
2008 host_sd
->sem_otime
= tswapl(target_sd
->sem_otime
);
2009 host_sd
->sem_ctime
= tswapl(target_sd
->sem_ctime
);
2010 unlock_user_struct(target_sd
, target_addr
, 0);
2014 static inline abi_long
host_to_target_semid_ds(abi_ulong target_addr
,
2015 struct semid_ds
*host_sd
)
2017 struct target_semid_ds
*target_sd
;
2019 if (!lock_user_struct(VERIFY_WRITE
, target_sd
, target_addr
, 0))
2020 return -TARGET_EFAULT
;
2021 if (host_to_target_ipc_perm(target_addr
,&(host_sd
->sem_perm
)))
2022 return -TARGET_EFAULT
;;
2023 target_sd
->sem_nsems
= tswapl(host_sd
->sem_nsems
);
2024 target_sd
->sem_otime
= tswapl(host_sd
->sem_otime
);
2025 target_sd
->sem_ctime
= tswapl(host_sd
->sem_ctime
);
2026 unlock_user_struct(target_sd
, target_addr
, 1);
2030 struct target_seminfo
{
2043 static inline abi_long
host_to_target_seminfo(abi_ulong target_addr
,
2044 struct seminfo
*host_seminfo
)
2046 struct target_seminfo
*target_seminfo
;
2047 if (!lock_user_struct(VERIFY_WRITE
, target_seminfo
, target_addr
, 0))
2048 return -TARGET_EFAULT
;
2049 __put_user(host_seminfo
->semmap
, &target_seminfo
->semmap
);
2050 __put_user(host_seminfo
->semmni
, &target_seminfo
->semmni
);
2051 __put_user(host_seminfo
->semmns
, &target_seminfo
->semmns
);
2052 __put_user(host_seminfo
->semmnu
, &target_seminfo
->semmnu
);
2053 __put_user(host_seminfo
->semmsl
, &target_seminfo
->semmsl
);
2054 __put_user(host_seminfo
->semopm
, &target_seminfo
->semopm
);
2055 __put_user(host_seminfo
->semume
, &target_seminfo
->semume
);
2056 __put_user(host_seminfo
->semusz
, &target_seminfo
->semusz
);
2057 __put_user(host_seminfo
->semvmx
, &target_seminfo
->semvmx
);
2058 __put_user(host_seminfo
->semaem
, &target_seminfo
->semaem
);
2059 unlock_user_struct(target_seminfo
, target_addr
, 1);
2065 struct semid_ds
*buf
;
2066 unsigned short *array
;
2067 struct seminfo
*__buf
;
2070 union target_semun
{
2077 static inline abi_long
target_to_host_semarray(int semid
, unsigned short **host_array
,
2078 abi_ulong target_addr
)
2081 unsigned short *array
;
2083 struct semid_ds semid_ds
;
2086 semun
.buf
= &semid_ds
;
2088 ret
= semctl(semid
, 0, IPC_STAT
, semun
);
2090 return get_errno(ret
);
2092 nsems
= semid_ds
.sem_nsems
;
2094 *host_array
= malloc(nsems
*sizeof(unsigned short));
2095 array
= lock_user(VERIFY_READ
, target_addr
,
2096 nsems
*sizeof(unsigned short), 1);
2098 return -TARGET_EFAULT
;
2100 for(i
=0; i
<nsems
; i
++) {
2101 __get_user((*host_array
)[i
], &array
[i
]);
2103 unlock_user(array
, target_addr
, 0);
2108 static inline abi_long
host_to_target_semarray(int semid
, abi_ulong target_addr
,
2109 unsigned short **host_array
)
2112 unsigned short *array
;
2114 struct semid_ds semid_ds
;
2117 semun
.buf
= &semid_ds
;
2119 ret
= semctl(semid
, 0, IPC_STAT
, semun
);
2121 return get_errno(ret
);
2123 nsems
= semid_ds
.sem_nsems
;
2125 array
= lock_user(VERIFY_WRITE
, target_addr
,
2126 nsems
*sizeof(unsigned short), 0);
2128 return -TARGET_EFAULT
;
2130 for(i
=0; i
<nsems
; i
++) {
2131 __put_user((*host_array
)[i
], &array
[i
]);
2134 unlock_user(array
, target_addr
, 1);
2139 static inline abi_long
do_semctl(int semid
, int semnum
, int cmd
,
2140 union target_semun target_su
)
2143 struct semid_ds dsarg
;
2144 unsigned short *array
;
2145 struct seminfo seminfo
;
2146 abi_long ret
= -TARGET_EINVAL
;
2153 arg
.val
= tswapl(target_su
.val
);
2154 ret
= get_errno(semctl(semid
, semnum
, cmd
, arg
));
2155 target_su
.val
= tswapl(arg
.val
);
2159 err
= target_to_host_semarray(semid
, &array
, target_su
.array
);
2163 ret
= get_errno(semctl(semid
, semnum
, cmd
, arg
));
2164 err
= host_to_target_semarray(semid
, target_su
.array
, &array
);
2171 err
= target_to_host_semid_ds(&dsarg
, target_su
.buf
);
2175 ret
= get_errno(semctl(semid
, semnum
, cmd
, arg
));
2176 err
= host_to_target_semid_ds(target_su
.buf
, &dsarg
);
2182 arg
.__buf
= &seminfo
;
2183 ret
= get_errno(semctl(semid
, semnum
, cmd
, arg
));
2184 err
= host_to_target_seminfo(target_su
.__buf
, &seminfo
);
2192 ret
= get_errno(semctl(semid
, semnum
, cmd
, NULL
));
2199 struct target_sembuf
{
2200 unsigned short sem_num
;
2205 static inline abi_long
target_to_host_sembuf(struct sembuf
*host_sembuf
,
2206 abi_ulong target_addr
,
2209 struct target_sembuf
*target_sembuf
;
2212 target_sembuf
= lock_user(VERIFY_READ
, target_addr
,
2213 nsops
*sizeof(struct target_sembuf
), 1);
2215 return -TARGET_EFAULT
;
2217 for(i
=0; i
<nsops
; i
++) {
2218 __get_user(host_sembuf
[i
].sem_num
, &target_sembuf
[i
].sem_num
);
2219 __get_user(host_sembuf
[i
].sem_op
, &target_sembuf
[i
].sem_op
);
2220 __get_user(host_sembuf
[i
].sem_flg
, &target_sembuf
[i
].sem_flg
);
2223 unlock_user(target_sembuf
, target_addr
, 0);
2228 static inline abi_long
do_semop(int semid
, abi_long ptr
, unsigned nsops
)
2230 struct sembuf sops
[nsops
];
2232 if (target_to_host_sembuf(sops
, ptr
, nsops
))
2233 return -TARGET_EFAULT
;
2235 return semop(semid
, sops
, nsops
);
2238 struct target_msqid_ds
2240 struct target_ipc_perm msg_perm
;
2241 abi_ulong msg_stime
;
2242 #if TARGET_ABI_BITS == 32
2243 abi_ulong __unused1
;
2245 abi_ulong msg_rtime
;
2246 #if TARGET_ABI_BITS == 32
2247 abi_ulong __unused2
;
2249 abi_ulong msg_ctime
;
2250 #if TARGET_ABI_BITS == 32
2251 abi_ulong __unused3
;
2253 abi_ulong __msg_cbytes
;
2255 abi_ulong msg_qbytes
;
2256 abi_ulong msg_lspid
;
2257 abi_ulong msg_lrpid
;
2258 abi_ulong __unused4
;
2259 abi_ulong __unused5
;
2262 static inline abi_long
target_to_host_msqid_ds(struct msqid_ds
*host_md
,
2263 abi_ulong target_addr
)
2265 struct target_msqid_ds
*target_md
;
2267 if (!lock_user_struct(VERIFY_READ
, target_md
, target_addr
, 1))
2268 return -TARGET_EFAULT
;
2269 if (target_to_host_ipc_perm(&(host_md
->msg_perm
),target_addr
))
2270 return -TARGET_EFAULT
;
2271 host_md
->msg_stime
= tswapl(target_md
->msg_stime
);
2272 host_md
->msg_rtime
= tswapl(target_md
->msg_rtime
);
2273 host_md
->msg_ctime
= tswapl(target_md
->msg_ctime
);
2274 host_md
->__msg_cbytes
= tswapl(target_md
->__msg_cbytes
);
2275 host_md
->msg_qnum
= tswapl(target_md
->msg_qnum
);
2276 host_md
->msg_qbytes
= tswapl(target_md
->msg_qbytes
);
2277 host_md
->msg_lspid
= tswapl(target_md
->msg_lspid
);
2278 host_md
->msg_lrpid
= tswapl(target_md
->msg_lrpid
);
2279 unlock_user_struct(target_md
, target_addr
, 0);
2283 static inline abi_long
host_to_target_msqid_ds(abi_ulong target_addr
,
2284 struct msqid_ds
*host_md
)
2286 struct target_msqid_ds
*target_md
;
2288 if (!lock_user_struct(VERIFY_WRITE
, target_md
, target_addr
, 0))
2289 return -TARGET_EFAULT
;
2290 if (host_to_target_ipc_perm(target_addr
,&(host_md
->msg_perm
)))
2291 return -TARGET_EFAULT
;
2292 target_md
->msg_stime
= tswapl(host_md
->msg_stime
);
2293 target_md
->msg_rtime
= tswapl(host_md
->msg_rtime
);
2294 target_md
->msg_ctime
= tswapl(host_md
->msg_ctime
);
2295 target_md
->__msg_cbytes
= tswapl(host_md
->__msg_cbytes
);
2296 target_md
->msg_qnum
= tswapl(host_md
->msg_qnum
);
2297 target_md
->msg_qbytes
= tswapl(host_md
->msg_qbytes
);
2298 target_md
->msg_lspid
= tswapl(host_md
->msg_lspid
);
2299 target_md
->msg_lrpid
= tswapl(host_md
->msg_lrpid
);
2300 unlock_user_struct(target_md
, target_addr
, 1);
2304 struct target_msginfo
{
2312 unsigned short int msgseg
;
2315 static inline abi_long
host_to_target_msginfo(abi_ulong target_addr
,
2316 struct msginfo
*host_msginfo
)
2318 struct target_msginfo
*target_msginfo
;
2319 if (!lock_user_struct(VERIFY_WRITE
, target_msginfo
, target_addr
, 0))
2320 return -TARGET_EFAULT
;
2321 __put_user(host_msginfo
->msgpool
, &target_msginfo
->msgpool
);
2322 __put_user(host_msginfo
->msgmap
, &target_msginfo
->msgmap
);
2323 __put_user(host_msginfo
->msgmax
, &target_msginfo
->msgmax
);
2324 __put_user(host_msginfo
->msgmnb
, &target_msginfo
->msgmnb
);
2325 __put_user(host_msginfo
->msgmni
, &target_msginfo
->msgmni
);
2326 __put_user(host_msginfo
->msgssz
, &target_msginfo
->msgssz
);
2327 __put_user(host_msginfo
->msgtql
, &target_msginfo
->msgtql
);
2328 __put_user(host_msginfo
->msgseg
, &target_msginfo
->msgseg
);
2329 unlock_user_struct(target_msginfo
, target_addr
, 1);
2333 static inline abi_long
do_msgctl(int msgid
, int cmd
, abi_long ptr
)
2335 struct msqid_ds dsarg
;
2336 struct msginfo msginfo
;
2337 abi_long ret
= -TARGET_EINVAL
;
2345 if (target_to_host_msqid_ds(&dsarg
,ptr
))
2346 return -TARGET_EFAULT
;
2347 ret
= get_errno(msgctl(msgid
, cmd
, &dsarg
));
2348 if (host_to_target_msqid_ds(ptr
,&dsarg
))
2349 return -TARGET_EFAULT
;
2352 ret
= get_errno(msgctl(msgid
, cmd
, NULL
));
2356 ret
= get_errno(msgctl(msgid
, cmd
, (struct msqid_ds
*)&msginfo
));
2357 if (host_to_target_msginfo(ptr
, &msginfo
))
2358 return -TARGET_EFAULT
;
2365 struct target_msgbuf
{
2370 static inline abi_long
do_msgsnd(int msqid
, abi_long msgp
,
2371 unsigned int msgsz
, int msgflg
)
2373 struct target_msgbuf
*target_mb
;
2374 struct msgbuf
*host_mb
;
2377 if (!lock_user_struct(VERIFY_READ
, target_mb
, msgp
, 0))
2378 return -TARGET_EFAULT
;
2379 host_mb
= malloc(msgsz
+sizeof(long));
2380 host_mb
->mtype
= (abi_long
) tswapl(target_mb
->mtype
);
2381 memcpy(host_mb
->mtext
, target_mb
->mtext
, msgsz
);
2382 ret
= get_errno(msgsnd(msqid
, host_mb
, msgsz
, msgflg
));
2384 unlock_user_struct(target_mb
, msgp
, 0);
2389 static inline abi_long
do_msgrcv(int msqid
, abi_long msgp
,
2390 unsigned int msgsz
, abi_long msgtyp
,
2393 struct target_msgbuf
*target_mb
;
2395 struct msgbuf
*host_mb
;
2398 if (!lock_user_struct(VERIFY_WRITE
, target_mb
, msgp
, 0))
2399 return -TARGET_EFAULT
;
2401 host_mb
= malloc(msgsz
+sizeof(long));
2402 ret
= get_errno(msgrcv(msqid
, host_mb
, msgsz
, tswapl(msgtyp
), msgflg
));
2405 abi_ulong target_mtext_addr
= msgp
+ sizeof(abi_ulong
);
2406 target_mtext
= lock_user(VERIFY_WRITE
, target_mtext_addr
, ret
, 0);
2407 if (!target_mtext
) {
2408 ret
= -TARGET_EFAULT
;
2411 memcpy(target_mb
->mtext
, host_mb
->mtext
, ret
);
2412 unlock_user(target_mtext
, target_mtext_addr
, ret
);
2415 target_mb
->mtype
= tswapl(host_mb
->mtype
);
2420 unlock_user_struct(target_mb
, msgp
, 1);
2424 struct target_shmid_ds
2426 struct target_ipc_perm shm_perm
;
2427 abi_ulong shm_segsz
;
2428 abi_ulong shm_atime
;
2429 #if TARGET_ABI_BITS == 32
2430 abi_ulong __unused1
;
2432 abi_ulong shm_dtime
;
2433 #if TARGET_ABI_BITS == 32
2434 abi_ulong __unused2
;
2436 abi_ulong shm_ctime
;
2437 #if TARGET_ABI_BITS == 32
2438 abi_ulong __unused3
;
2442 abi_ulong shm_nattch
;
2443 unsigned long int __unused4
;
2444 unsigned long int __unused5
;
2447 static inline abi_long
target_to_host_shmid_ds(struct shmid_ds
*host_sd
,
2448 abi_ulong target_addr
)
2450 struct target_shmid_ds
*target_sd
;
2452 if (!lock_user_struct(VERIFY_READ
, target_sd
, target_addr
, 1))
2453 return -TARGET_EFAULT
;
2454 if (target_to_host_ipc_perm(&(host_sd
->shm_perm
), target_addr
))
2455 return -TARGET_EFAULT
;
2456 __get_user(host_sd
->shm_segsz
, &target_sd
->shm_segsz
);
2457 __get_user(host_sd
->shm_atime
, &target_sd
->shm_atime
);
2458 __get_user(host_sd
->shm_dtime
, &target_sd
->shm_dtime
);
2459 __get_user(host_sd
->shm_ctime
, &target_sd
->shm_ctime
);
2460 __get_user(host_sd
->shm_cpid
, &target_sd
->shm_cpid
);
2461 __get_user(host_sd
->shm_lpid
, &target_sd
->shm_lpid
);
2462 __get_user(host_sd
->shm_nattch
, &target_sd
->shm_nattch
);
2463 unlock_user_struct(target_sd
, target_addr
, 0);
2467 static inline abi_long
host_to_target_shmid_ds(abi_ulong target_addr
,
2468 struct shmid_ds
*host_sd
)
2470 struct target_shmid_ds
*target_sd
;
2472 if (!lock_user_struct(VERIFY_WRITE
, target_sd
, target_addr
, 0))
2473 return -TARGET_EFAULT
;
2474 if (host_to_target_ipc_perm(target_addr
, &(host_sd
->shm_perm
)))
2475 return -TARGET_EFAULT
;
2476 __put_user(host_sd
->shm_segsz
, &target_sd
->shm_segsz
);
2477 __put_user(host_sd
->shm_atime
, &target_sd
->shm_atime
);
2478 __put_user(host_sd
->shm_dtime
, &target_sd
->shm_dtime
);
2479 __put_user(host_sd
->shm_ctime
, &target_sd
->shm_ctime
);
2480 __put_user(host_sd
->shm_cpid
, &target_sd
->shm_cpid
);
2481 __put_user(host_sd
->shm_lpid
, &target_sd
->shm_lpid
);
2482 __put_user(host_sd
->shm_nattch
, &target_sd
->shm_nattch
);
2483 unlock_user_struct(target_sd
, target_addr
, 1);
2487 struct target_shminfo
{
2495 static inline abi_long
host_to_target_shminfo(abi_ulong target_addr
,
2496 struct shminfo
*host_shminfo
)
2498 struct target_shminfo
*target_shminfo
;
2499 if (!lock_user_struct(VERIFY_WRITE
, target_shminfo
, target_addr
, 0))
2500 return -TARGET_EFAULT
;
2501 __put_user(host_shminfo
->shmmax
, &target_shminfo
->shmmax
);
2502 __put_user(host_shminfo
->shmmin
, &target_shminfo
->shmmin
);
2503 __put_user(host_shminfo
->shmmni
, &target_shminfo
->shmmni
);
2504 __put_user(host_shminfo
->shmseg
, &target_shminfo
->shmseg
);
2505 __put_user(host_shminfo
->shmall
, &target_shminfo
->shmall
);
2506 unlock_user_struct(target_shminfo
, target_addr
, 1);
2510 struct target_shm_info
{
2515 abi_ulong swap_attempts
;
2516 abi_ulong swap_successes
;
2519 static inline abi_long
host_to_target_shm_info(abi_ulong target_addr
,
2520 struct shm_info
*host_shm_info
)
2522 struct target_shm_info
*target_shm_info
;
2523 if (!lock_user_struct(VERIFY_WRITE
, target_shm_info
, target_addr
, 0))
2524 return -TARGET_EFAULT
;
2525 __put_user(host_shm_info
->used_ids
, &target_shm_info
->used_ids
);
2526 __put_user(host_shm_info
->shm_tot
, &target_shm_info
->shm_tot
);
2527 __put_user(host_shm_info
->shm_rss
, &target_shm_info
->shm_rss
);
2528 __put_user(host_shm_info
->shm_swp
, &target_shm_info
->shm_swp
);
2529 __put_user(host_shm_info
->swap_attempts
, &target_shm_info
->swap_attempts
);
2530 __put_user(host_shm_info
->swap_successes
, &target_shm_info
->swap_successes
);
2531 unlock_user_struct(target_shm_info
, target_addr
, 1);
2535 static inline abi_long
do_shmctl(int shmid
, int cmd
, abi_long buf
)
2537 struct shmid_ds dsarg
;
2538 struct shminfo shminfo
;
2539 struct shm_info shm_info
;
2540 abi_long ret
= -TARGET_EINVAL
;
2548 if (target_to_host_shmid_ds(&dsarg
, buf
))
2549 return -TARGET_EFAULT
;
2550 ret
= get_errno(shmctl(shmid
, cmd
, &dsarg
));
2551 if (host_to_target_shmid_ds(buf
, &dsarg
))
2552 return -TARGET_EFAULT
;
2555 ret
= get_errno(shmctl(shmid
, cmd
, (struct shmid_ds
*)&shminfo
));
2556 if (host_to_target_shminfo(buf
, &shminfo
))
2557 return -TARGET_EFAULT
;
2560 ret
= get_errno(shmctl(shmid
, cmd
, (struct shmid_ds
*)&shm_info
));
2561 if (host_to_target_shm_info(buf
, &shm_info
))
2562 return -TARGET_EFAULT
;
2567 ret
= get_errno(shmctl(shmid
, cmd
, NULL
));
2574 static inline abi_ulong
do_shmat(int shmid
, abi_ulong shmaddr
, int shmflg
)
2578 struct shmid_ds shm_info
;
2581 /* find out the length of the shared memory segment */
2582 ret
= get_errno(shmctl(shmid
, IPC_STAT
, &shm_info
));
2583 if (is_error(ret
)) {
2584 /* can't get length, bail out */
2591 host_raddr
= shmat(shmid
, (void *)g2h(shmaddr
), shmflg
);
2593 abi_ulong mmap_start
;
2595 mmap_start
= mmap_find_vma(0, shm_info
.shm_segsz
);
2597 if (mmap_start
== -1) {
2599 host_raddr
= (void *)-1;
2601 host_raddr
= shmat(shmid
, g2h(mmap_start
), shmflg
| SHM_REMAP
);
2604 if (host_raddr
== (void *)-1) {
2606 return get_errno((long)host_raddr
);
2608 raddr
=h2g((unsigned long)host_raddr
);
2610 page_set_flags(raddr
, raddr
+ shm_info
.shm_segsz
,
2611 PAGE_VALID
| PAGE_READ
|
2612 ((shmflg
& SHM_RDONLY
)? 0 : PAGE_WRITE
));
2614 for (i
= 0; i
< N_SHM_REGIONS
; i
++) {
2615 if (shm_regions
[i
].start
== 0) {
2616 shm_regions
[i
].start
= raddr
;
2617 shm_regions
[i
].size
= shm_info
.shm_segsz
;
2627 static inline abi_long
do_shmdt(abi_ulong shmaddr
)
2631 for (i
= 0; i
< N_SHM_REGIONS
; ++i
) {
2632 if (shm_regions
[i
].start
== shmaddr
) {
2633 shm_regions
[i
].start
= 0;
2634 page_set_flags(shmaddr
, shm_regions
[i
].size
, 0);
2639 return get_errno(shmdt(g2h(shmaddr
)));
2642 #ifdef TARGET_NR_ipc
2643 /* ??? This only works with linear mappings. */
2644 /* do_ipc() must return target values and target errnos. */
2645 static abi_long
do_ipc(unsigned int call
, int first
,
2646 int second
, int third
,
2647 abi_long ptr
, abi_long fifth
)
2652 version
= call
>> 16;
2657 ret
= do_semop(first
, ptr
, second
);
2661 ret
= get_errno(semget(first
, second
, third
));
2665 ret
= do_semctl(first
, second
, third
, (union target_semun
)(abi_ulong
) ptr
);
2669 ret
= get_errno(msgget(first
, second
));
2673 ret
= do_msgsnd(first
, ptr
, second
, third
);
2677 ret
= do_msgctl(first
, second
, ptr
);
2684 struct target_ipc_kludge
{
2689 if (!lock_user_struct(VERIFY_READ
, tmp
, ptr
, 1)) {
2690 ret
= -TARGET_EFAULT
;
2694 ret
= do_msgrcv(first
, tmp
->msgp
, second
, tmp
->msgtyp
, third
);
2696 unlock_user_struct(tmp
, ptr
, 0);
2700 ret
= do_msgrcv(first
, ptr
, second
, fifth
, third
);
2709 raddr
= do_shmat(first
, ptr
, second
);
2710 if (is_error(raddr
))
2711 return get_errno(raddr
);
2712 if (put_user_ual(raddr
, third
))
2713 return -TARGET_EFAULT
;
2717 ret
= -TARGET_EINVAL
;
2722 ret
= do_shmdt(ptr
);
2726 /* IPC_* flag values are the same on all linux platforms */
2727 ret
= get_errno(shmget(first
, second
, third
));
2730 /* IPC_* and SHM_* command values are the same on all linux platforms */
2732 ret
= do_shmctl(first
, second
, third
);
2735 gemu_log("Unsupported ipc call: %d (version %d)\n", call
, version
);
2736 ret
= -TARGET_ENOSYS
;
2743 /* kernel structure types definitions */
2746 #define STRUCT(name, ...) STRUCT_ ## name,
2747 #define STRUCT_SPECIAL(name) STRUCT_ ## name,
2749 #include "syscall_types.h"
2752 #undef STRUCT_SPECIAL
2754 #define STRUCT(name, ...) static const argtype struct_ ## name ## _def[] = { __VA_ARGS__, TYPE_NULL };
2755 #define STRUCT_SPECIAL(name)
2756 #include "syscall_types.h"
2758 #undef STRUCT_SPECIAL
2760 typedef struct IOCTLEntry
{
2761 unsigned int target_cmd
;
2762 unsigned int host_cmd
;
2765 const argtype arg_type
[5];
2768 #define IOC_R 0x0001
2769 #define IOC_W 0x0002
2770 #define IOC_RW (IOC_R | IOC_W)
2772 #define MAX_STRUCT_SIZE 4096
2774 static IOCTLEntry ioctl_entries
[] = {
2775 #define IOCTL(cmd, access, ...) \
2776 { TARGET_ ## cmd, cmd, #cmd, access, { __VA_ARGS__ } },
2781 /* ??? Implement proper locking for ioctls. */
2782 /* do_ioctl() Must return target values and target errnos. */
2783 static abi_long
do_ioctl(int fd
, abi_long cmd
, abi_long arg
)
2785 const IOCTLEntry
*ie
;
2786 const argtype
*arg_type
;
2788 uint8_t buf_temp
[MAX_STRUCT_SIZE
];
2794 if (ie
->target_cmd
== 0) {
2795 gemu_log("Unsupported ioctl: cmd=0x%04lx\n", (long)cmd
);
2796 return -TARGET_ENOSYS
;
2798 if (ie
->target_cmd
== cmd
)
2802 arg_type
= ie
->arg_type
;
2804 gemu_log("ioctl: cmd=0x%04lx (%s)\n", (long)cmd
, ie
->name
);
2806 switch(arg_type
[0]) {
2809 ret
= get_errno(ioctl(fd
, ie
->host_cmd
));
2814 ret
= get_errno(ioctl(fd
, ie
->host_cmd
, arg
));
2818 target_size
= thunk_type_size(arg_type
, 0);
2819 switch(ie
->access
) {
2821 ret
= get_errno(ioctl(fd
, ie
->host_cmd
, buf_temp
));
2822 if (!is_error(ret
)) {
2823 argptr
= lock_user(VERIFY_WRITE
, arg
, target_size
, 0);
2825 return -TARGET_EFAULT
;
2826 thunk_convert(argptr
, buf_temp
, arg_type
, THUNK_TARGET
);
2827 unlock_user(argptr
, arg
, target_size
);
2831 argptr
= lock_user(VERIFY_READ
, arg
, target_size
, 1);
2833 return -TARGET_EFAULT
;
2834 thunk_convert(buf_temp
, argptr
, arg_type
, THUNK_HOST
);
2835 unlock_user(argptr
, arg
, 0);
2836 ret
= get_errno(ioctl(fd
, ie
->host_cmd
, buf_temp
));
2840 argptr
= lock_user(VERIFY_READ
, arg
, target_size
, 1);
2842 return -TARGET_EFAULT
;
2843 thunk_convert(buf_temp
, argptr
, arg_type
, THUNK_HOST
);
2844 unlock_user(argptr
, arg
, 0);
2845 ret
= get_errno(ioctl(fd
, ie
->host_cmd
, buf_temp
));
2846 if (!is_error(ret
)) {
2847 argptr
= lock_user(VERIFY_WRITE
, arg
, target_size
, 0);
2849 return -TARGET_EFAULT
;
2850 thunk_convert(argptr
, buf_temp
, arg_type
, THUNK_TARGET
);
2851 unlock_user(argptr
, arg
, target_size
);
2857 gemu_log("Unsupported ioctl type: cmd=0x%04lx type=%d\n",
2858 (long)cmd
, arg_type
[0]);
2859 ret
= -TARGET_ENOSYS
;
2865 static const bitmask_transtbl iflag_tbl
[] = {
2866 { TARGET_IGNBRK
, TARGET_IGNBRK
, IGNBRK
, IGNBRK
},
2867 { TARGET_BRKINT
, TARGET_BRKINT
, BRKINT
, BRKINT
},
2868 { TARGET_IGNPAR
, TARGET_IGNPAR
, IGNPAR
, IGNPAR
},
2869 { TARGET_PARMRK
, TARGET_PARMRK
, PARMRK
, PARMRK
},
2870 { TARGET_INPCK
, TARGET_INPCK
, INPCK
, INPCK
},
2871 { TARGET_ISTRIP
, TARGET_ISTRIP
, ISTRIP
, ISTRIP
},
2872 { TARGET_INLCR
, TARGET_INLCR
, INLCR
, INLCR
},
2873 { TARGET_IGNCR
, TARGET_IGNCR
, IGNCR
, IGNCR
},
2874 { TARGET_ICRNL
, TARGET_ICRNL
, ICRNL
, ICRNL
},
2875 { TARGET_IUCLC
, TARGET_IUCLC
, IUCLC
, IUCLC
},
2876 { TARGET_IXON
, TARGET_IXON
, IXON
, IXON
},
2877 { TARGET_IXANY
, TARGET_IXANY
, IXANY
, IXANY
},
2878 { TARGET_IXOFF
, TARGET_IXOFF
, IXOFF
, IXOFF
},
2879 { TARGET_IMAXBEL
, TARGET_IMAXBEL
, IMAXBEL
, IMAXBEL
},
2883 static const bitmask_transtbl oflag_tbl
[] = {
2884 { TARGET_OPOST
, TARGET_OPOST
, OPOST
, OPOST
},
2885 { TARGET_OLCUC
, TARGET_OLCUC
, OLCUC
, OLCUC
},
2886 { TARGET_ONLCR
, TARGET_ONLCR
, ONLCR
, ONLCR
},
2887 { TARGET_OCRNL
, TARGET_OCRNL
, OCRNL
, OCRNL
},
2888 { TARGET_ONOCR
, TARGET_ONOCR
, ONOCR
, ONOCR
},
2889 { TARGET_ONLRET
, TARGET_ONLRET
, ONLRET
, ONLRET
},
2890 { TARGET_OFILL
, TARGET_OFILL
, OFILL
, OFILL
},
2891 { TARGET_OFDEL
, TARGET_OFDEL
, OFDEL
, OFDEL
},
2892 { TARGET_NLDLY
, TARGET_NL0
, NLDLY
, NL0
},
2893 { TARGET_NLDLY
, TARGET_NL1
, NLDLY
, NL1
},
2894 { TARGET_CRDLY
, TARGET_CR0
, CRDLY
, CR0
},
2895 { TARGET_CRDLY
, TARGET_CR1
, CRDLY
, CR1
},
2896 { TARGET_CRDLY
, TARGET_CR2
, CRDLY
, CR2
},
2897 { TARGET_CRDLY
, TARGET_CR3
, CRDLY
, CR3
},
2898 { TARGET_TABDLY
, TARGET_TAB0
, TABDLY
, TAB0
},
2899 { TARGET_TABDLY
, TARGET_TAB1
, TABDLY
, TAB1
},
2900 { TARGET_TABDLY
, TARGET_TAB2
, TABDLY
, TAB2
},
2901 { TARGET_TABDLY
, TARGET_TAB3
, TABDLY
, TAB3
},
2902 { TARGET_BSDLY
, TARGET_BS0
, BSDLY
, BS0
},
2903 { TARGET_BSDLY
, TARGET_BS1
, BSDLY
, BS1
},
2904 { TARGET_VTDLY
, TARGET_VT0
, VTDLY
, VT0
},
2905 { TARGET_VTDLY
, TARGET_VT1
, VTDLY
, VT1
},
2906 { TARGET_FFDLY
, TARGET_FF0
, FFDLY
, FF0
},
2907 { TARGET_FFDLY
, TARGET_FF1
, FFDLY
, FF1
},
2911 static const bitmask_transtbl cflag_tbl
[] = {
2912 { TARGET_CBAUD
, TARGET_B0
, CBAUD
, B0
},
2913 { TARGET_CBAUD
, TARGET_B50
, CBAUD
, B50
},
2914 { TARGET_CBAUD
, TARGET_B75
, CBAUD
, B75
},
2915 { TARGET_CBAUD
, TARGET_B110
, CBAUD
, B110
},
2916 { TARGET_CBAUD
, TARGET_B134
, CBAUD
, B134
},
2917 { TARGET_CBAUD
, TARGET_B150
, CBAUD
, B150
},
2918 { TARGET_CBAUD
, TARGET_B200
, CBAUD
, B200
},
2919 { TARGET_CBAUD
, TARGET_B300
, CBAUD
, B300
},
2920 { TARGET_CBAUD
, TARGET_B600
, CBAUD
, B600
},
2921 { TARGET_CBAUD
, TARGET_B1200
, CBAUD
, B1200
},
2922 { TARGET_CBAUD
, TARGET_B1800
, CBAUD
, B1800
},
2923 { TARGET_CBAUD
, TARGET_B2400
, CBAUD
, B2400
},
2924 { TARGET_CBAUD
, TARGET_B4800
, CBAUD
, B4800
},
2925 { TARGET_CBAUD
, TARGET_B9600
, CBAUD
, B9600
},
2926 { TARGET_CBAUD
, TARGET_B19200
, CBAUD
, B19200
},
2927 { TARGET_CBAUD
, TARGET_B38400
, CBAUD
, B38400
},
2928 { TARGET_CBAUD
, TARGET_B57600
, CBAUD
, B57600
},
2929 { TARGET_CBAUD
, TARGET_B115200
, CBAUD
, B115200
},
2930 { TARGET_CBAUD
, TARGET_B230400
, CBAUD
, B230400
},
2931 { TARGET_CBAUD
, TARGET_B460800
, CBAUD
, B460800
},
2932 { TARGET_CSIZE
, TARGET_CS5
, CSIZE
, CS5
},
2933 { TARGET_CSIZE
, TARGET_CS6
, CSIZE
, CS6
},
2934 { TARGET_CSIZE
, TARGET_CS7
, CSIZE
, CS7
},
2935 { TARGET_CSIZE
, TARGET_CS8
, CSIZE
, CS8
},
2936 { TARGET_CSTOPB
, TARGET_CSTOPB
, CSTOPB
, CSTOPB
},
2937 { TARGET_CREAD
, TARGET_CREAD
, CREAD
, CREAD
},
2938 { TARGET_PARENB
, TARGET_PARENB
, PARENB
, PARENB
},
2939 { TARGET_PARODD
, TARGET_PARODD
, PARODD
, PARODD
},
2940 { TARGET_HUPCL
, TARGET_HUPCL
, HUPCL
, HUPCL
},
2941 { TARGET_CLOCAL
, TARGET_CLOCAL
, CLOCAL
, CLOCAL
},
2942 { TARGET_CRTSCTS
, TARGET_CRTSCTS
, CRTSCTS
, CRTSCTS
},
2946 static const bitmask_transtbl lflag_tbl
[] = {
2947 { TARGET_ISIG
, TARGET_ISIG
, ISIG
, ISIG
},
2948 { TARGET_ICANON
, TARGET_ICANON
, ICANON
, ICANON
},
2949 { TARGET_XCASE
, TARGET_XCASE
, XCASE
, XCASE
},
2950 { TARGET_ECHO
, TARGET_ECHO
, ECHO
, ECHO
},
2951 { TARGET_ECHOE
, TARGET_ECHOE
, ECHOE
, ECHOE
},
2952 { TARGET_ECHOK
, TARGET_ECHOK
, ECHOK
, ECHOK
},
2953 { TARGET_ECHONL
, TARGET_ECHONL
, ECHONL
, ECHONL
},
2954 { TARGET_NOFLSH
, TARGET_NOFLSH
, NOFLSH
, NOFLSH
},
2955 { TARGET_TOSTOP
, TARGET_TOSTOP
, TOSTOP
, TOSTOP
},
2956 { TARGET_ECHOCTL
, TARGET_ECHOCTL
, ECHOCTL
, ECHOCTL
},
2957 { TARGET_ECHOPRT
, TARGET_ECHOPRT
, ECHOPRT
, ECHOPRT
},
2958 { TARGET_ECHOKE
, TARGET_ECHOKE
, ECHOKE
, ECHOKE
},
2959 { TARGET_FLUSHO
, TARGET_FLUSHO
, FLUSHO
, FLUSHO
},
2960 { TARGET_PENDIN
, TARGET_PENDIN
, PENDIN
, PENDIN
},
2961 { TARGET_IEXTEN
, TARGET_IEXTEN
, IEXTEN
, IEXTEN
},
2965 static void target_to_host_termios (void *dst
, const void *src
)
2967 struct host_termios
*host
= dst
;
2968 const struct target_termios
*target
= src
;
2971 target_to_host_bitmask(tswap32(target
->c_iflag
), iflag_tbl
);
2973 target_to_host_bitmask(tswap32(target
->c_oflag
), oflag_tbl
);
2975 target_to_host_bitmask(tswap32(target
->c_cflag
), cflag_tbl
);
2977 target_to_host_bitmask(tswap32(target
->c_lflag
), lflag_tbl
);
2978 host
->c_line
= target
->c_line
;
2980 memset(host
->c_cc
, 0, sizeof(host
->c_cc
));
2981 host
->c_cc
[VINTR
] = target
->c_cc
[TARGET_VINTR
];
2982 host
->c_cc
[VQUIT
] = target
->c_cc
[TARGET_VQUIT
];
2983 host
->c_cc
[VERASE
] = target
->c_cc
[TARGET_VERASE
];
2984 host
->c_cc
[VKILL
] = target
->c_cc
[TARGET_VKILL
];
2985 host
->c_cc
[VEOF
] = target
->c_cc
[TARGET_VEOF
];
2986 host
->c_cc
[VTIME
] = target
->c_cc
[TARGET_VTIME
];
2987 host
->c_cc
[VMIN
] = target
->c_cc
[TARGET_VMIN
];
2988 host
->c_cc
[VSWTC
] = target
->c_cc
[TARGET_VSWTC
];
2989 host
->c_cc
[VSTART
] = target
->c_cc
[TARGET_VSTART
];
2990 host
->c_cc
[VSTOP
] = target
->c_cc
[TARGET_VSTOP
];
2991 host
->c_cc
[VSUSP
] = target
->c_cc
[TARGET_VSUSP
];
2992 host
->c_cc
[VEOL
] = target
->c_cc
[TARGET_VEOL
];
2993 host
->c_cc
[VREPRINT
] = target
->c_cc
[TARGET_VREPRINT
];
2994 host
->c_cc
[VDISCARD
] = target
->c_cc
[TARGET_VDISCARD
];
2995 host
->c_cc
[VWERASE
] = target
->c_cc
[TARGET_VWERASE
];
2996 host
->c_cc
[VLNEXT
] = target
->c_cc
[TARGET_VLNEXT
];
2997 host
->c_cc
[VEOL2
] = target
->c_cc
[TARGET_VEOL2
];
3000 static void host_to_target_termios (void *dst
, const void *src
)
3002 struct target_termios
*target
= dst
;
3003 const struct host_termios
*host
= src
;
3006 tswap32(host_to_target_bitmask(host
->c_iflag
, iflag_tbl
));
3008 tswap32(host_to_target_bitmask(host
->c_oflag
, oflag_tbl
));
3010 tswap32(host_to_target_bitmask(host
->c_cflag
, cflag_tbl
));
3012 tswap32(host_to_target_bitmask(host
->c_lflag
, lflag_tbl
));
3013 target
->c_line
= host
->c_line
;
3015 memset(target
->c_cc
, 0, sizeof(target
->c_cc
));
3016 target
->c_cc
[TARGET_VINTR
] = host
->c_cc
[VINTR
];
3017 target
->c_cc
[TARGET_VQUIT
] = host
->c_cc
[VQUIT
];
3018 target
->c_cc
[TARGET_VERASE
] = host
->c_cc
[VERASE
];
3019 target
->c_cc
[TARGET_VKILL
] = host
->c_cc
[VKILL
];
3020 target
->c_cc
[TARGET_VEOF
] = host
->c_cc
[VEOF
];
3021 target
->c_cc
[TARGET_VTIME
] = host
->c_cc
[VTIME
];
3022 target
->c_cc
[TARGET_VMIN
] = host
->c_cc
[VMIN
];
3023 target
->c_cc
[TARGET_VSWTC
] = host
->c_cc
[VSWTC
];
3024 target
->c_cc
[TARGET_VSTART
] = host
->c_cc
[VSTART
];
3025 target
->c_cc
[TARGET_VSTOP
] = host
->c_cc
[VSTOP
];
3026 target
->c_cc
[TARGET_VSUSP
] = host
->c_cc
[VSUSP
];
3027 target
->c_cc
[TARGET_VEOL
] = host
->c_cc
[VEOL
];
3028 target
->c_cc
[TARGET_VREPRINT
] = host
->c_cc
[VREPRINT
];
3029 target
->c_cc
[TARGET_VDISCARD
] = host
->c_cc
[VDISCARD
];
3030 target
->c_cc
[TARGET_VWERASE
] = host
->c_cc
[VWERASE
];
3031 target
->c_cc
[TARGET_VLNEXT
] = host
->c_cc
[VLNEXT
];
3032 target
->c_cc
[TARGET_VEOL2
] = host
->c_cc
[VEOL2
];
3035 static const StructEntry struct_termios_def
= {
3036 .convert
= { host_to_target_termios
, target_to_host_termios
},
3037 .size
= { sizeof(struct target_termios
), sizeof(struct host_termios
) },
3038 .align
= { __alignof__(struct target_termios
), __alignof__(struct host_termios
) },
3041 static bitmask_transtbl mmap_flags_tbl
[] = {
3042 { TARGET_MAP_SHARED
, TARGET_MAP_SHARED
, MAP_SHARED
, MAP_SHARED
},
3043 { TARGET_MAP_PRIVATE
, TARGET_MAP_PRIVATE
, MAP_PRIVATE
, MAP_PRIVATE
},
3044 { TARGET_MAP_FIXED
, TARGET_MAP_FIXED
, MAP_FIXED
, MAP_FIXED
},
3045 { TARGET_MAP_ANONYMOUS
, TARGET_MAP_ANONYMOUS
, MAP_ANONYMOUS
, MAP_ANONYMOUS
},
3046 { TARGET_MAP_GROWSDOWN
, TARGET_MAP_GROWSDOWN
, MAP_GROWSDOWN
, MAP_GROWSDOWN
},
3047 { TARGET_MAP_DENYWRITE
, TARGET_MAP_DENYWRITE
, MAP_DENYWRITE
, MAP_DENYWRITE
},
3048 { TARGET_MAP_EXECUTABLE
, TARGET_MAP_EXECUTABLE
, MAP_EXECUTABLE
, MAP_EXECUTABLE
},
3049 { TARGET_MAP_LOCKED
, TARGET_MAP_LOCKED
, MAP_LOCKED
, MAP_LOCKED
},
3053 #if defined(TARGET_I386)
3055 /* NOTE: there is really one LDT for all the threads */
3056 static uint8_t *ldt_table
;
3058 static abi_long
read_ldt(abi_ulong ptr
, unsigned long bytecount
)
3065 size
= TARGET_LDT_ENTRIES
* TARGET_LDT_ENTRY_SIZE
;
3066 if (size
> bytecount
)
3068 p
= lock_user(VERIFY_WRITE
, ptr
, size
, 0);
3070 return -TARGET_EFAULT
;
3071 /* ??? Should this by byteswapped? */
3072 memcpy(p
, ldt_table
, size
);
3073 unlock_user(p
, ptr
, size
);
3077 /* XXX: add locking support */
3078 static abi_long
write_ldt(CPUX86State
*env
,
3079 abi_ulong ptr
, unsigned long bytecount
, int oldmode
)
3081 struct target_modify_ldt_ldt_s ldt_info
;
3082 struct target_modify_ldt_ldt_s
*target_ldt_info
;
3083 int seg_32bit
, contents
, read_exec_only
, limit_in_pages
;
3084 int seg_not_present
, useable
, lm
;
3085 uint32_t *lp
, entry_1
, entry_2
;
3087 if (bytecount
!= sizeof(ldt_info
))
3088 return -TARGET_EINVAL
;
3089 if (!lock_user_struct(VERIFY_READ
, target_ldt_info
, ptr
, 1))
3090 return -TARGET_EFAULT
;
3091 ldt_info
.entry_number
= tswap32(target_ldt_info
->entry_number
);
3092 ldt_info
.base_addr
= tswapl(target_ldt_info
->base_addr
);
3093 ldt_info
.limit
= tswap32(target_ldt_info
->limit
);
3094 ldt_info
.flags
= tswap32(target_ldt_info
->flags
);
3095 unlock_user_struct(target_ldt_info
, ptr
, 0);
3097 if (ldt_info
.entry_number
>= TARGET_LDT_ENTRIES
)
3098 return -TARGET_EINVAL
;
3099 seg_32bit
= ldt_info
.flags
& 1;
3100 contents
= (ldt_info
.flags
>> 1) & 3;
3101 read_exec_only
= (ldt_info
.flags
>> 3) & 1;
3102 limit_in_pages
= (ldt_info
.flags
>> 4) & 1;
3103 seg_not_present
= (ldt_info
.flags
>> 5) & 1;
3104 useable
= (ldt_info
.flags
>> 6) & 1;
3108 lm
= (ldt_info
.flags
>> 7) & 1;
3110 if (contents
== 3) {
3112 return -TARGET_EINVAL
;
3113 if (seg_not_present
== 0)
3114 return -TARGET_EINVAL
;
3116 /* allocate the LDT */
3118 env
->ldt
.base
= target_mmap(0,
3119 TARGET_LDT_ENTRIES
* TARGET_LDT_ENTRY_SIZE
,
3120 PROT_READ
|PROT_WRITE
,
3121 MAP_ANONYMOUS
|MAP_PRIVATE
, -1, 0);
3122 if (env
->ldt
.base
== -1)
3123 return -TARGET_ENOMEM
;
3124 memset(g2h(env
->ldt
.base
), 0,
3125 TARGET_LDT_ENTRIES
* TARGET_LDT_ENTRY_SIZE
);
3126 env
->ldt
.limit
= 0xffff;
3127 ldt_table
= g2h(env
->ldt
.base
);
3130 /* NOTE: same code as Linux kernel */
3131 /* Allow LDTs to be cleared by the user. */
3132 if (ldt_info
.base_addr
== 0 && ldt_info
.limit
== 0) {
3135 read_exec_only
== 1 &&
3137 limit_in_pages
== 0 &&
3138 seg_not_present
== 1 &&
3146 entry_1
= ((ldt_info
.base_addr
& 0x0000ffff) << 16) |
3147 (ldt_info
.limit
& 0x0ffff);
3148 entry_2
= (ldt_info
.base_addr
& 0xff000000) |
3149 ((ldt_info
.base_addr
& 0x00ff0000) >> 16) |
3150 (ldt_info
.limit
& 0xf0000) |
3151 ((read_exec_only
^ 1) << 9) |
3153 ((seg_not_present
^ 1) << 15) |
3155 (limit_in_pages
<< 23) |
3159 entry_2
|= (useable
<< 20);
3161 /* Install the new entry ... */
3163 lp
= (uint32_t *)(ldt_table
+ (ldt_info
.entry_number
<< 3));
3164 lp
[0] = tswap32(entry_1
);
3165 lp
[1] = tswap32(entry_2
);
3169 /* specific and weird i386 syscalls */
3170 static abi_long
do_modify_ldt(CPUX86State
*env
, int func
, abi_ulong ptr
,
3171 unsigned long bytecount
)
3177 ret
= read_ldt(ptr
, bytecount
);
3180 ret
= write_ldt(env
, ptr
, bytecount
, 1);
3183 ret
= write_ldt(env
, ptr
, bytecount
, 0);
3186 ret
= -TARGET_ENOSYS
;
3192 #if defined(TARGET_I386) && defined(TARGET_ABI32)
3193 static abi_long
do_set_thread_area(CPUX86State
*env
, abi_ulong ptr
)
3195 uint64_t *gdt_table
= g2h(env
->gdt
.base
);
3196 struct target_modify_ldt_ldt_s ldt_info
;
3197 struct target_modify_ldt_ldt_s
*target_ldt_info
;
3198 int seg_32bit
, contents
, read_exec_only
, limit_in_pages
;
3199 int seg_not_present
, useable
, lm
;
3200 uint32_t *lp
, entry_1
, entry_2
;
3203 lock_user_struct(VERIFY_WRITE
, target_ldt_info
, ptr
, 1);
3204 if (!target_ldt_info
)
3205 return -TARGET_EFAULT
;
3206 ldt_info
.entry_number
= tswap32(target_ldt_info
->entry_number
);
3207 ldt_info
.base_addr
= tswapl(target_ldt_info
->base_addr
);
3208 ldt_info
.limit
= tswap32(target_ldt_info
->limit
);
3209 ldt_info
.flags
= tswap32(target_ldt_info
->flags
);
3210 if (ldt_info
.entry_number
== -1) {
3211 for (i
=TARGET_GDT_ENTRY_TLS_MIN
; i
<=TARGET_GDT_ENTRY_TLS_MAX
; i
++) {
3212 if (gdt_table
[i
] == 0) {
3213 ldt_info
.entry_number
= i
;
3214 target_ldt_info
->entry_number
= tswap32(i
);
3219 unlock_user_struct(target_ldt_info
, ptr
, 1);
3221 if (ldt_info
.entry_number
< TARGET_GDT_ENTRY_TLS_MIN
||
3222 ldt_info
.entry_number
> TARGET_GDT_ENTRY_TLS_MAX
)
3223 return -TARGET_EINVAL
;
3224 seg_32bit
= ldt_info
.flags
& 1;
3225 contents
= (ldt_info
.flags
>> 1) & 3;
3226 read_exec_only
= (ldt_info
.flags
>> 3) & 1;
3227 limit_in_pages
= (ldt_info
.flags
>> 4) & 1;
3228 seg_not_present
= (ldt_info
.flags
>> 5) & 1;
3229 useable
= (ldt_info
.flags
>> 6) & 1;
3233 lm
= (ldt_info
.flags
>> 7) & 1;
3236 if (contents
== 3) {
3237 if (seg_not_present
== 0)
3238 return -TARGET_EINVAL
;
3241 /* NOTE: same code as Linux kernel */
3242 /* Allow LDTs to be cleared by the user. */
3243 if (ldt_info
.base_addr
== 0 && ldt_info
.limit
== 0) {
3244 if ((contents
== 0 &&
3245 read_exec_only
== 1 &&
3247 limit_in_pages
== 0 &&
3248 seg_not_present
== 1 &&
3256 entry_1
= ((ldt_info
.base_addr
& 0x0000ffff) << 16) |
3257 (ldt_info
.limit
& 0x0ffff);
3258 entry_2
= (ldt_info
.base_addr
& 0xff000000) |
3259 ((ldt_info
.base_addr
& 0x00ff0000) >> 16) |
3260 (ldt_info
.limit
& 0xf0000) |
3261 ((read_exec_only
^ 1) << 9) |
3263 ((seg_not_present
^ 1) << 15) |
3265 (limit_in_pages
<< 23) |
3270 /* Install the new entry ... */
3272 lp
= (uint32_t *)(gdt_table
+ ldt_info
.entry_number
);
3273 lp
[0] = tswap32(entry_1
);
3274 lp
[1] = tswap32(entry_2
);
3278 static abi_long
do_get_thread_area(CPUX86State
*env
, abi_ulong ptr
)
3280 struct target_modify_ldt_ldt_s
*target_ldt_info
;
3281 uint64_t *gdt_table
= g2h(env
->gdt
.base
);
3282 uint32_t base_addr
, limit
, flags
;
3283 int seg_32bit
, contents
, read_exec_only
, limit_in_pages
, idx
;
3284 int seg_not_present
, useable
, lm
;
3285 uint32_t *lp
, entry_1
, entry_2
;
3287 lock_user_struct(VERIFY_WRITE
, target_ldt_info
, ptr
, 1);
3288 if (!target_ldt_info
)
3289 return -TARGET_EFAULT
;
3290 idx
= tswap32(target_ldt_info
->entry_number
);
3291 if (idx
< TARGET_GDT_ENTRY_TLS_MIN
||
3292 idx
> TARGET_GDT_ENTRY_TLS_MAX
) {
3293 unlock_user_struct(target_ldt_info
, ptr
, 1);
3294 return -TARGET_EINVAL
;
3296 lp
= (uint32_t *)(gdt_table
+ idx
);
3297 entry_1
= tswap32(lp
[0]);
3298 entry_2
= tswap32(lp
[1]);
3300 read_exec_only
= ((entry_2
>> 9) & 1) ^ 1;
3301 contents
= (entry_2
>> 10) & 3;
3302 seg_not_present
= ((entry_2
>> 15) & 1) ^ 1;
3303 seg_32bit
= (entry_2
>> 22) & 1;
3304 limit_in_pages
= (entry_2
>> 23) & 1;
3305 useable
= (entry_2
>> 20) & 1;
3309 lm
= (entry_2
>> 21) & 1;
3311 flags
= (seg_32bit
<< 0) | (contents
<< 1) |
3312 (read_exec_only
<< 3) | (limit_in_pages
<< 4) |
3313 (seg_not_present
<< 5) | (useable
<< 6) | (lm
<< 7);
3314 limit
= (entry_1
& 0xffff) | (entry_2
& 0xf0000);
3315 base_addr
= (entry_1
>> 16) |
3316 (entry_2
& 0xff000000) |
3317 ((entry_2
& 0xff) << 16);
3318 target_ldt_info
->base_addr
= tswapl(base_addr
);
3319 target_ldt_info
->limit
= tswap32(limit
);
3320 target_ldt_info
->flags
= tswap32(flags
);
3321 unlock_user_struct(target_ldt_info
, ptr
, 1);
3324 #endif /* TARGET_I386 && TARGET_ABI32 */
3326 #ifndef TARGET_ABI32
3327 static abi_long
do_arch_prctl(CPUX86State
*env
, int code
, abi_ulong addr
)
3334 case TARGET_ARCH_SET_GS
:
3335 case TARGET_ARCH_SET_FS
:
3336 if (code
== TARGET_ARCH_SET_GS
)
3340 cpu_x86_load_seg(env
, idx
, 0);
3341 env
->segs
[idx
].base
= addr
;
3343 case TARGET_ARCH_GET_GS
:
3344 case TARGET_ARCH_GET_FS
:
3345 if (code
== TARGET_ARCH_GET_GS
)
3349 val
= env
->segs
[idx
].base
;
3350 if (put_user(val
, addr
, abi_ulong
))
3351 return -TARGET_EFAULT
;
3354 ret
= -TARGET_EINVAL
;
3361 #endif /* defined(TARGET_I386) */
3363 #if defined(USE_NPTL)
3365 #define NEW_STACK_SIZE PTHREAD_STACK_MIN
3367 static pthread_mutex_t clone_lock
= PTHREAD_MUTEX_INITIALIZER
;
3370 pthread_mutex_t mutex
;
3371 pthread_cond_t cond
;
3374 abi_ulong child_tidptr
;
3375 abi_ulong parent_tidptr
;
3379 static void *clone_func(void *arg
)
3381 new_thread_info
*info
= arg
;
3387 ts
= (TaskState
*)thread_env
->opaque
;
3388 info
->tid
= gettid();
3389 env
->host_tid
= info
->tid
;
3391 if (info
->child_tidptr
)
3392 put_user_u32(info
->tid
, info
->child_tidptr
);
3393 if (info
->parent_tidptr
)
3394 put_user_u32(info
->tid
, info
->parent_tidptr
);
3395 /* Enable signals. */
3396 sigprocmask(SIG_SETMASK
, &info
->sigmask
, NULL
);
3397 /* Signal to the parent that we're ready. */
3398 pthread_mutex_lock(&info
->mutex
);
3399 pthread_cond_broadcast(&info
->cond
);
3400 pthread_mutex_unlock(&info
->mutex
);
3401 /* Wait until the parent has finshed initializing the tls state. */
3402 pthread_mutex_lock(&clone_lock
);
3403 pthread_mutex_unlock(&clone_lock
);
3409 /* this stack is the equivalent of the kernel stack associated with a
3411 #define NEW_STACK_SIZE 8192
3413 static int clone_func(void *arg
)
3415 CPUState
*env
= arg
;
3422 /* do_fork() Must return host values and target errnos (unlike most
3423 do_*() functions). */
3424 static int do_fork(CPUState
*env
, unsigned int flags
, abi_ulong newsp
,
3425 abi_ulong parent_tidptr
, target_ulong newtls
,
3426 abi_ulong child_tidptr
)
3432 #if defined(USE_NPTL)
3433 unsigned int nptl_flags
;
3437 /* Emulate vfork() with fork() */
3438 if (flags
& CLONE_VFORK
)
3439 flags
&= ~(CLONE_VFORK
| CLONE_VM
);
3441 if (flags
& CLONE_VM
) {
3442 TaskState
*parent_ts
= (TaskState
*)env
->opaque
;
3443 #if defined(USE_NPTL)
3444 new_thread_info info
;
3445 pthread_attr_t attr
;
3447 ts
= qemu_mallocz(sizeof(TaskState
) + NEW_STACK_SIZE
);
3448 init_task_state(ts
);
3449 new_stack
= ts
->stack
;
3450 /* we create a new CPU instance. */
3451 new_env
= cpu_copy(env
);
3452 /* Init regs that differ from the parent. */
3453 cpu_clone_regs(new_env
, newsp
);
3454 new_env
->opaque
= ts
;
3455 ts
->bprm
= parent_ts
->bprm
;
3456 ts
->info
= parent_ts
->info
;
3457 #if defined(USE_NPTL)
3459 flags
&= ~CLONE_NPTL_FLAGS2
;
3461 if (nptl_flags
& CLONE_CHILD_CLEARTID
) {
3462 ts
->child_tidptr
= child_tidptr
;
3465 if (nptl_flags
& CLONE_SETTLS
)
3466 cpu_set_tls (new_env
, newtls
);
3468 /* Grab a mutex so that thread setup appears atomic. */
3469 pthread_mutex_lock(&clone_lock
);
3471 memset(&info
, 0, sizeof(info
));
3472 pthread_mutex_init(&info
.mutex
, NULL
);
3473 pthread_mutex_lock(&info
.mutex
);
3474 pthread_cond_init(&info
.cond
, NULL
);
3476 if (nptl_flags
& CLONE_CHILD_SETTID
)
3477 info
.child_tidptr
= child_tidptr
;
3478 if (nptl_flags
& CLONE_PARENT_SETTID
)
3479 info
.parent_tidptr
= parent_tidptr
;
3481 ret
= pthread_attr_init(&attr
);
3482 ret
= pthread_attr_setstack(&attr
, new_stack
, NEW_STACK_SIZE
);
3483 /* It is not safe to deliver signals until the child has finished
3484 initializing, so temporarily block all signals. */
3485 sigfillset(&sigmask
);
3486 sigprocmask(SIG_BLOCK
, &sigmask
, &info
.sigmask
);
3488 ret
= pthread_create(&info
.thread
, &attr
, clone_func
, &info
);
3489 /* TODO: Free new CPU state if thread creation failed. */
3491 sigprocmask(SIG_SETMASK
, &info
.sigmask
, NULL
);
3492 pthread_attr_destroy(&attr
);
3494 /* Wait for the child to initialize. */
3495 pthread_cond_wait(&info
.cond
, &info
.mutex
);
3497 if (flags
& CLONE_PARENT_SETTID
)
3498 put_user_u32(ret
, parent_tidptr
);
3502 pthread_mutex_unlock(&info
.mutex
);
3503 pthread_cond_destroy(&info
.cond
);
3504 pthread_mutex_destroy(&info
.mutex
);
3505 pthread_mutex_unlock(&clone_lock
);
3507 if (flags
& CLONE_NPTL_FLAGS2
)
3509 /* This is probably going to die very quickly, but do it anyway. */
3511 ret
= __clone2(clone_func
, new_stack
+ NEW_STACK_SIZE
, flags
, new_env
);
3513 ret
= clone(clone_func
, new_stack
+ NEW_STACK_SIZE
, flags
, new_env
);
3517 /* if no CLONE_VM, we consider it is a fork */
3518 if ((flags
& ~(CSIGNAL
| CLONE_NPTL_FLAGS2
)) != 0)
3523 /* Child Process. */
3524 cpu_clone_regs(env
, newsp
);
3526 #if defined(USE_NPTL)
3527 /* There is a race condition here. The parent process could
3528 theoretically read the TID in the child process before the child
3529 tid is set. This would require using either ptrace
3530 (not implemented) or having *_tidptr to point at a shared memory
3531 mapping. We can't repeat the spinlock hack used above because
3532 the child process gets its own copy of the lock. */
3533 if (flags
& CLONE_CHILD_SETTID
)
3534 put_user_u32(gettid(), child_tidptr
);
3535 if (flags
& CLONE_PARENT_SETTID
)
3536 put_user_u32(gettid(), parent_tidptr
);
3537 ts
= (TaskState
*)env
->opaque
;
3538 if (flags
& CLONE_SETTLS
)
3539 cpu_set_tls (env
, newtls
);
3540 if (flags
& CLONE_CHILD_CLEARTID
)
3541 ts
->child_tidptr
= child_tidptr
;
3550 static abi_long
do_fcntl(int fd
, int cmd
, abi_ulong arg
)
3553 struct target_flock
*target_fl
;
3554 struct flock64 fl64
;
3555 struct target_flock64
*target_fl64
;
3559 case TARGET_F_GETLK
:
3560 if (!lock_user_struct(VERIFY_READ
, target_fl
, arg
, 1))
3561 return -TARGET_EFAULT
;
3562 fl
.l_type
= tswap16(target_fl
->l_type
);
3563 fl
.l_whence
= tswap16(target_fl
->l_whence
);
3564 fl
.l_start
= tswapl(target_fl
->l_start
);
3565 fl
.l_len
= tswapl(target_fl
->l_len
);
3566 fl
.l_pid
= tswapl(target_fl
->l_pid
);
3567 unlock_user_struct(target_fl
, arg
, 0);
3568 ret
= get_errno(fcntl(fd
, cmd
, &fl
));
3570 if (!lock_user_struct(VERIFY_WRITE
, target_fl
, arg
, 0))
3571 return -TARGET_EFAULT
;
3572 target_fl
->l_type
= tswap16(fl
.l_type
);
3573 target_fl
->l_whence
= tswap16(fl
.l_whence
);
3574 target_fl
->l_start
= tswapl(fl
.l_start
);
3575 target_fl
->l_len
= tswapl(fl
.l_len
);
3576 target_fl
->l_pid
= tswapl(fl
.l_pid
);
3577 unlock_user_struct(target_fl
, arg
, 1);
3581 case TARGET_F_SETLK
:
3582 case TARGET_F_SETLKW
:
3583 if (!lock_user_struct(VERIFY_READ
, target_fl
, arg
, 1))
3584 return -TARGET_EFAULT
;
3585 fl
.l_type
= tswap16(target_fl
->l_type
);
3586 fl
.l_whence
= tswap16(target_fl
->l_whence
);
3587 fl
.l_start
= tswapl(target_fl
->l_start
);
3588 fl
.l_len
= tswapl(target_fl
->l_len
);
3589 fl
.l_pid
= tswapl(target_fl
->l_pid
);
3590 unlock_user_struct(target_fl
, arg
, 0);
3591 ret
= get_errno(fcntl(fd
, cmd
, &fl
));
3594 case TARGET_F_GETLK64
:
3595 if (!lock_user_struct(VERIFY_READ
, target_fl64
, arg
, 1))
3596 return -TARGET_EFAULT
;
3597 fl64
.l_type
= tswap16(target_fl64
->l_type
) >> 1;
3598 fl64
.l_whence
= tswap16(target_fl64
->l_whence
);
3599 fl64
.l_start
= tswapl(target_fl64
->l_start
);
3600 fl64
.l_len
= tswapl(target_fl64
->l_len
);
3601 fl64
.l_pid
= tswap16(target_fl64
->l_pid
);
3602 unlock_user_struct(target_fl64
, arg
, 0);
3603 ret
= get_errno(fcntl(fd
, cmd
>> 1, &fl64
));
3605 if (!lock_user_struct(VERIFY_WRITE
, target_fl64
, arg
, 0))
3606 return -TARGET_EFAULT
;
3607 target_fl64
->l_type
= tswap16(fl64
.l_type
) >> 1;
3608 target_fl64
->l_whence
= tswap16(fl64
.l_whence
);
3609 target_fl64
->l_start
= tswapl(fl64
.l_start
);
3610 target_fl64
->l_len
= tswapl(fl64
.l_len
);
3611 target_fl64
->l_pid
= tswapl(fl64
.l_pid
);
3612 unlock_user_struct(target_fl64
, arg
, 1);
3615 case TARGET_F_SETLK64
:
3616 case TARGET_F_SETLKW64
:
3617 if (!lock_user_struct(VERIFY_READ
, target_fl64
, arg
, 1))
3618 return -TARGET_EFAULT
;
3619 fl64
.l_type
= tswap16(target_fl64
->l_type
) >> 1;
3620 fl64
.l_whence
= tswap16(target_fl64
->l_whence
);
3621 fl64
.l_start
= tswapl(target_fl64
->l_start
);
3622 fl64
.l_len
= tswapl(target_fl64
->l_len
);
3623 fl64
.l_pid
= tswap16(target_fl64
->l_pid
);
3624 unlock_user_struct(target_fl64
, arg
, 0);
3625 ret
= get_errno(fcntl(fd
, cmd
>> 1, &fl64
));
3629 ret
= get_errno(fcntl(fd
, cmd
, arg
));
3631 ret
= host_to_target_bitmask(ret
, fcntl_flags_tbl
);
3636 ret
= get_errno(fcntl(fd
, cmd
, target_to_host_bitmask(arg
, fcntl_flags_tbl
)));
3640 ret
= get_errno(fcntl(fd
, cmd
, arg
));
3648 static inline int high2lowuid(int uid
)
3656 static inline int high2lowgid(int gid
)
3664 static inline int low2highuid(int uid
)
3666 if ((int16_t)uid
== -1)
3672 static inline int low2highgid(int gid
)
3674 if ((int16_t)gid
== -1)
3680 #endif /* USE_UID16 */
3682 void syscall_init(void)
3685 const argtype
*arg_type
;
3689 #define STRUCT(name, ...) thunk_register_struct(STRUCT_ ## name, #name, struct_ ## name ## _def);
3690 #define STRUCT_SPECIAL(name) thunk_register_struct_direct(STRUCT_ ## name, #name, &struct_ ## name ## _def);
3691 #include "syscall_types.h"
3693 #undef STRUCT_SPECIAL
3695 /* we patch the ioctl size if necessary. We rely on the fact that
3696 no ioctl has all the bits at '1' in the size field */
3698 while (ie
->target_cmd
!= 0) {
3699 if (((ie
->target_cmd
>> TARGET_IOC_SIZESHIFT
) & TARGET_IOC_SIZEMASK
) ==
3700 TARGET_IOC_SIZEMASK
) {
3701 arg_type
= ie
->arg_type
;
3702 if (arg_type
[0] != TYPE_PTR
) {
3703 fprintf(stderr
, "cannot patch size for ioctl 0x%x\n",
3708 size
= thunk_type_size(arg_type
, 0);
3709 ie
->target_cmd
= (ie
->target_cmd
&
3710 ~(TARGET_IOC_SIZEMASK
<< TARGET_IOC_SIZESHIFT
)) |
3711 (size
<< TARGET_IOC_SIZESHIFT
);
3714 /* Build target_to_host_errno_table[] table from
3715 * host_to_target_errno_table[]. */
3716 for (i
=0; i
< ERRNO_TABLE_SIZE
; i
++)
3717 target_to_host_errno_table
[host_to_target_errno_table
[i
]] = i
;
3719 /* automatic consistency check if same arch */
3720 #if (defined(__i386__) && defined(TARGET_I386) && defined(TARGET_ABI32)) || \
3721 (defined(__x86_64__) && defined(TARGET_X86_64))
3722 if (unlikely(ie
->target_cmd
!= ie
->host_cmd
)) {
3723 fprintf(stderr
, "ERROR: ioctl(%s): target=0x%x host=0x%x\n",
3724 ie
->name
, ie
->target_cmd
, ie
->host_cmd
);
3731 #if TARGET_ABI_BITS == 32
3732 static inline uint64_t target_offset64(uint32_t word0
, uint32_t word1
)
3734 #ifdef TARGET_WORDS_BIGENDIAN
3735 return ((uint64_t)word0
<< 32) | word1
;
3737 return ((uint64_t)word1
<< 32) | word0
;
3740 #else /* TARGET_ABI_BITS == 32 */
3741 static inline uint64_t target_offset64(uint64_t word0
, uint64_t word1
)
3745 #endif /* TARGET_ABI_BITS != 32 */
3747 #ifdef TARGET_NR_truncate64
3748 static inline abi_long
target_truncate64(void *cpu_env
, const char *arg1
,
3754 if (((CPUARMState
*)cpu_env
)->eabi
)
3760 return get_errno(truncate64(arg1
, target_offset64(arg2
, arg3
)));
3764 #ifdef TARGET_NR_ftruncate64
3765 static inline abi_long
target_ftruncate64(void *cpu_env
, abi_long arg1
,
3771 if (((CPUARMState
*)cpu_env
)->eabi
)
3777 return get_errno(ftruncate64(arg1
, target_offset64(arg2
, arg3
)));
3781 static inline abi_long
target_to_host_timespec(struct timespec
*host_ts
,
3782 abi_ulong target_addr
)
3784 struct target_timespec
*target_ts
;
3786 if (!lock_user_struct(VERIFY_READ
, target_ts
, target_addr
, 1))
3787 return -TARGET_EFAULT
;
3788 host_ts
->tv_sec
= tswapl(target_ts
->tv_sec
);
3789 host_ts
->tv_nsec
= tswapl(target_ts
->tv_nsec
);
3790 unlock_user_struct(target_ts
, target_addr
, 0);
3794 static inline abi_long
host_to_target_timespec(abi_ulong target_addr
,
3795 struct timespec
*host_ts
)
3797 struct target_timespec
*target_ts
;
3799 if (!lock_user_struct(VERIFY_WRITE
, target_ts
, target_addr
, 0))
3800 return -TARGET_EFAULT
;
3801 target_ts
->tv_sec
= tswapl(host_ts
->tv_sec
);
3802 target_ts
->tv_nsec
= tswapl(host_ts
->tv_nsec
);
3803 unlock_user_struct(target_ts
, target_addr
, 1);
3807 #if defined(TARGET_NR_stat64) || defined(TARGET_NR_newfstatat)
3808 static inline abi_long
host_to_target_stat64(void *cpu_env
,
3809 abi_ulong target_addr
,
3810 struct stat
*host_st
)
3813 if (((CPUARMState
*)cpu_env
)->eabi
) {
3814 struct target_eabi_stat64
*target_st
;
3816 if (!lock_user_struct(VERIFY_WRITE
, target_st
, target_addr
, 0))
3817 return -TARGET_EFAULT
;
3818 memset(target_st
, 0, sizeof(struct target_eabi_stat64
));
3819 __put_user(host_st
->st_dev
, &target_st
->st_dev
);
3820 __put_user(host_st
->st_ino
, &target_st
->st_ino
);
3821 #ifdef TARGET_STAT64_HAS_BROKEN_ST_INO
3822 __put_user(host_st
->st_ino
, &target_st
->__st_ino
);
3824 __put_user(host_st
->st_mode
, &target_st
->st_mode
);
3825 __put_user(host_st
->st_nlink
, &target_st
->st_nlink
);
3826 __put_user(host_st
->st_uid
, &target_st
->st_uid
);
3827 __put_user(host_st
->st_gid
, &target_st
->st_gid
);
3828 __put_user(host_st
->st_rdev
, &target_st
->st_rdev
);
3829 __put_user(host_st
->st_size
, &target_st
->st_size
);
3830 __put_user(host_st
->st_blksize
, &target_st
->st_blksize
);
3831 __put_user(host_st
->st_blocks
, &target_st
->st_blocks
);
3832 __put_user(host_st
->st_atime
, &target_st
->target_st_atime
);
3833 __put_user(host_st
->st_mtime
, &target_st
->target_st_mtime
);
3834 __put_user(host_st
->st_ctime
, &target_st
->target_st_ctime
);
3835 unlock_user_struct(target_st
, target_addr
, 1);
3839 #if TARGET_LONG_BITS == 64
3840 struct target_stat
*target_st
;
3842 struct target_stat64
*target_st
;
3845 if (!lock_user_struct(VERIFY_WRITE
, target_st
, target_addr
, 0))
3846 return -TARGET_EFAULT
;
3847 memset(target_st
, 0, sizeof(*target_st
));
3848 __put_user(host_st
->st_dev
, &target_st
->st_dev
);
3849 __put_user(host_st
->st_ino
, &target_st
->st_ino
);
3850 #ifdef TARGET_STAT64_HAS_BROKEN_ST_INO
3851 __put_user(host_st
->st_ino
, &target_st
->__st_ino
);
3853 __put_user(host_st
->st_mode
, &target_st
->st_mode
);
3854 __put_user(host_st
->st_nlink
, &target_st
->st_nlink
);
3855 __put_user(host_st
->st_uid
, &target_st
->st_uid
);
3856 __put_user(host_st
->st_gid
, &target_st
->st_gid
);
3857 __put_user(host_st
->st_rdev
, &target_st
->st_rdev
);
3858 /* XXX: better use of kernel struct */
3859 __put_user(host_st
->st_size
, &target_st
->st_size
);
3860 __put_user(host_st
->st_blksize
, &target_st
->st_blksize
);
3861 __put_user(host_st
->st_blocks
, &target_st
->st_blocks
);
3862 __put_user(host_st
->st_atime
, &target_st
->target_st_atime
);
3863 __put_user(host_st
->st_mtime
, &target_st
->target_st_mtime
);
3864 __put_user(host_st
->st_ctime
, &target_st
->target_st_ctime
);
3865 unlock_user_struct(target_st
, target_addr
, 1);
3872 #if defined(USE_NPTL)
3873 /* ??? Using host futex calls even when target atomic operations
3874 are not really atomic probably breaks things. However implementing
3875 futexes locally would make futexes shared between multiple processes
3876 tricky. However they're probably useless because guest atomic
3877 operations won't work either. */
3878 static int do_futex(target_ulong uaddr
, int op
, int val
, target_ulong timeout
,
3879 target_ulong uaddr2
, int val3
)
3881 struct timespec ts
, *pts
;
3883 /* ??? We assume FUTEX_* constants are the same on both host
3889 target_to_host_timespec(pts
, timeout
);
3893 return get_errno(sys_futex(g2h(uaddr
), FUTEX_WAIT
, tswap32(val
),
3896 return get_errno(sys_futex(g2h(uaddr
), FUTEX_WAKE
, val
, NULL
, NULL
, 0));
3898 return get_errno(sys_futex(g2h(uaddr
), FUTEX_FD
, val
, NULL
, NULL
, 0));
3900 return get_errno(sys_futex(g2h(uaddr
), FUTEX_REQUEUE
, val
,
3901 NULL
, g2h(uaddr2
), 0));
3902 case FUTEX_CMP_REQUEUE
:
3903 return get_errno(sys_futex(g2h(uaddr
), FUTEX_CMP_REQUEUE
, val
,
3904 NULL
, g2h(uaddr2
), tswap32(val3
)));
3906 return -TARGET_ENOSYS
;
3911 /* Map host to target signal numbers for the wait family of syscalls.
3912 Assume all other status bits are the same. */
3913 static int host_to_target_waitstatus(int status
)
3915 if (WIFSIGNALED(status
)) {
3916 return host_to_target_signal(WTERMSIG(status
)) | (status
& ~0x7f);
3918 if (WIFSTOPPED(status
)) {
3919 return (host_to_target_signal(WSTOPSIG(status
)) << 8)
3925 int get_osversion(void)
3927 static int osversion
;
3928 struct new_utsname buf
;
3933 if (qemu_uname_release
&& *qemu_uname_release
) {
3934 s
= qemu_uname_release
;
3936 if (sys_uname(&buf
))
3941 for (i
= 0; i
< 3; i
++) {
3943 while (*s
>= '0' && *s
<= '9') {
3948 tmp
= (tmp
<< 8) + n
;
3956 /* do_syscall() should always have a single exit point at the end so
3957 that actions, such as logging of syscall results, can be performed.
3958 All errnos that do_syscall() returns must be -TARGET_<errcode>. */
3959 abi_long
do_syscall(void *cpu_env
, int num
, abi_long arg1
,
3960 abi_long arg2
, abi_long arg3
, abi_long arg4
,
3961 abi_long arg5
, abi_long arg6
)
3969 gemu_log("syscall %d", num
);
3972 print_syscall(num
, arg1
, arg2
, arg3
, arg4
, arg5
, arg6
);
3975 case TARGET_NR_exit
:
3977 /* In old applications this may be used to implement _exit(2).
3978 However in threaded applictions it is used for thread termination,
3979 and _exit_group is used for application termination.
3980 Do thread termination if we have more then one thread. */
3981 /* FIXME: This probably breaks if a signal arrives. We should probably
3982 be disabling signals. */
3983 if (first_cpu
->next_cpu
) {
3991 while (p
&& p
!= (CPUState
*)cpu_env
) {
3992 lastp
= &p
->next_cpu
;
3995 /* If we didn't find the CPU for this thread then something is
3999 /* Remove the CPU from the list. */
4000 *lastp
= p
->next_cpu
;
4002 ts
= ((CPUState
*)cpu_env
)->opaque
;
4003 if (ts
->child_tidptr
) {
4004 put_user_u32(0, ts
->child_tidptr
);
4005 sys_futex(g2h(ts
->child_tidptr
), FUTEX_WAKE
, INT_MAX
,
4008 /* TODO: Free CPU state. */
4015 gdb_exit(cpu_env
, arg1
);
4017 ret
= 0; /* avoid warning */
4019 case TARGET_NR_read
:
4023 if (!(p
= lock_user(VERIFY_WRITE
, arg2
, arg3
, 0)))
4025 ret
= get_errno(read(arg1
, p
, arg3
));
4026 unlock_user(p
, arg2
, ret
);
4029 case TARGET_NR_write
:
4030 if (!(p
= lock_user(VERIFY_READ
, arg2
, arg3
, 1)))
4032 ret
= get_errno(write(arg1
, p
, arg3
));
4033 unlock_user(p
, arg2
, 0);
4035 case TARGET_NR_open
:
4036 if (!(p
= lock_user_string(arg1
)))
4038 ret
= get_errno(open(path(p
),
4039 target_to_host_bitmask(arg2
, fcntl_flags_tbl
),
4041 unlock_user(p
, arg1
, 0);
4043 #if defined(TARGET_NR_openat) && defined(__NR_openat)
4044 case TARGET_NR_openat
:
4045 if (!(p
= lock_user_string(arg2
)))
4047 ret
= get_errno(sys_openat(arg1
,
4049 target_to_host_bitmask(arg3
, fcntl_flags_tbl
),
4051 unlock_user(p
, arg2
, 0);
4054 case TARGET_NR_close
:
4055 ret
= get_errno(close(arg1
));
4060 case TARGET_NR_fork
:
4061 ret
= get_errno(do_fork(cpu_env
, SIGCHLD
, 0, 0, 0, 0));
4063 #ifdef TARGET_NR_waitpid
4064 case TARGET_NR_waitpid
:
4067 ret
= get_errno(waitpid(arg1
, &status
, arg3
));
4068 if (!is_error(ret
) && arg2
4069 && put_user_s32(host_to_target_waitstatus(status
), arg2
))
4074 #ifdef TARGET_NR_waitid
4075 case TARGET_NR_waitid
:
4079 ret
= get_errno(waitid(arg1
, arg2
, &info
, arg4
));
4080 if (!is_error(ret
) && arg3
&& info
.si_pid
!= 0) {
4081 if (!(p
= lock_user(VERIFY_WRITE
, arg3
, sizeof(target_siginfo_t
), 0)))
4083 host_to_target_siginfo(p
, &info
);
4084 unlock_user(p
, arg3
, sizeof(target_siginfo_t
));
4089 #ifdef TARGET_NR_creat /* not on alpha */
4090 case TARGET_NR_creat
:
4091 if (!(p
= lock_user_string(arg1
)))
4093 ret
= get_errno(creat(p
, arg2
));
4094 unlock_user(p
, arg1
, 0);
4097 case TARGET_NR_link
:
4100 p
= lock_user_string(arg1
);
4101 p2
= lock_user_string(arg2
);
4103 ret
= -TARGET_EFAULT
;
4105 ret
= get_errno(link(p
, p2
));
4106 unlock_user(p2
, arg2
, 0);
4107 unlock_user(p
, arg1
, 0);
4110 #if defined(TARGET_NR_linkat) && defined(__NR_linkat)
4111 case TARGET_NR_linkat
:
4116 p
= lock_user_string(arg2
);
4117 p2
= lock_user_string(arg4
);
4119 ret
= -TARGET_EFAULT
;
4121 ret
= get_errno(sys_linkat(arg1
, p
, arg3
, p2
, arg5
));
4122 unlock_user(p
, arg2
, 0);
4123 unlock_user(p2
, arg4
, 0);
4127 case TARGET_NR_unlink
:
4128 if (!(p
= lock_user_string(arg1
)))
4130 ret
= get_errno(unlink(p
));
4131 unlock_user(p
, arg1
, 0);
4133 #if defined(TARGET_NR_unlinkat) && defined(__NR_unlinkat)
4134 case TARGET_NR_unlinkat
:
4135 if (!(p
= lock_user_string(arg2
)))
4137 ret
= get_errno(sys_unlinkat(arg1
, p
, arg3
));
4138 unlock_user(p
, arg2
, 0);
4141 case TARGET_NR_execve
:
4143 char **argp
, **envp
;
4146 abi_ulong guest_argp
;
4147 abi_ulong guest_envp
;
4153 for (gp
= guest_argp
; gp
; gp
+= sizeof(abi_ulong
)) {
4154 if (get_user_ual(addr
, gp
))
4162 for (gp
= guest_envp
; gp
; gp
+= sizeof(abi_ulong
)) {
4163 if (get_user_ual(addr
, gp
))
4170 argp
= alloca((argc
+ 1) * sizeof(void *));
4171 envp
= alloca((envc
+ 1) * sizeof(void *));
4173 for (gp
= guest_argp
, q
= argp
; gp
;
4174 gp
+= sizeof(abi_ulong
), q
++) {
4175 if (get_user_ual(addr
, gp
))
4179 if (!(*q
= lock_user_string(addr
)))
4184 for (gp
= guest_envp
, q
= envp
; gp
;
4185 gp
+= sizeof(abi_ulong
), q
++) {
4186 if (get_user_ual(addr
, gp
))
4190 if (!(*q
= lock_user_string(addr
)))
4195 if (!(p
= lock_user_string(arg1
)))
4197 ret
= get_errno(execve(p
, argp
, envp
));
4198 unlock_user(p
, arg1
, 0);
4203 ret
= -TARGET_EFAULT
;
4206 for (gp
= guest_argp
, q
= argp
; *q
;
4207 gp
+= sizeof(abi_ulong
), q
++) {
4208 if (get_user_ual(addr
, gp
)
4211 unlock_user(*q
, addr
, 0);
4213 for (gp
= guest_envp
, q
= envp
; *q
;
4214 gp
+= sizeof(abi_ulong
), q
++) {
4215 if (get_user_ual(addr
, gp
)
4218 unlock_user(*q
, addr
, 0);
4222 case TARGET_NR_chdir
:
4223 if (!(p
= lock_user_string(arg1
)))
4225 ret
= get_errno(chdir(p
));
4226 unlock_user(p
, arg1
, 0);
4228 #ifdef TARGET_NR_time
4229 case TARGET_NR_time
:
4232 ret
= get_errno(time(&host_time
));
4235 && put_user_sal(host_time
, arg1
))
4240 case TARGET_NR_mknod
:
4241 if (!(p
= lock_user_string(arg1
)))
4243 ret
= get_errno(mknod(p
, arg2
, arg3
));
4244 unlock_user(p
, arg1
, 0);
4246 #if defined(TARGET_NR_mknodat) && defined(__NR_mknodat)
4247 case TARGET_NR_mknodat
:
4248 if (!(p
= lock_user_string(arg2
)))
4250 ret
= get_errno(sys_mknodat(arg1
, p
, arg3
, arg4
));
4251 unlock_user(p
, arg2
, 0);
4254 case TARGET_NR_chmod
:
4255 if (!(p
= lock_user_string(arg1
)))
4257 ret
= get_errno(chmod(p
, arg2
));
4258 unlock_user(p
, arg1
, 0);
4260 #ifdef TARGET_NR_break
4261 case TARGET_NR_break
:
4264 #ifdef TARGET_NR_oldstat
4265 case TARGET_NR_oldstat
:
4268 case TARGET_NR_lseek
:
4269 ret
= get_errno(lseek(arg1
, arg2
, arg3
));
4271 #ifdef TARGET_NR_getxpid
4272 case TARGET_NR_getxpid
:
4274 case TARGET_NR_getpid
:
4276 ret
= get_errno(getpid());
4278 case TARGET_NR_mount
:
4280 /* need to look at the data field */
4282 p
= lock_user_string(arg1
);
4283 p2
= lock_user_string(arg2
);
4284 p3
= lock_user_string(arg3
);
4285 if (!p
|| !p2
|| !p3
)
4286 ret
= -TARGET_EFAULT
;
4288 /* FIXME - arg5 should be locked, but it isn't clear how to
4289 * do that since it's not guaranteed to be a NULL-terminated
4292 ret
= get_errno(mount(p
, p2
, p3
, (unsigned long)arg4
, g2h(arg5
)));
4293 unlock_user(p
, arg1
, 0);
4294 unlock_user(p2
, arg2
, 0);
4295 unlock_user(p3
, arg3
, 0);
4298 #ifdef TARGET_NR_umount
4299 case TARGET_NR_umount
:
4300 if (!(p
= lock_user_string(arg1
)))
4302 ret
= get_errno(umount(p
));
4303 unlock_user(p
, arg1
, 0);
4306 #ifdef TARGET_NR_stime /* not on alpha */
4307 case TARGET_NR_stime
:
4310 if (get_user_sal(host_time
, arg1
))
4312 ret
= get_errno(stime(&host_time
));
4316 case TARGET_NR_ptrace
:
4318 #ifdef TARGET_NR_alarm /* not on alpha */
4319 case TARGET_NR_alarm
:
4323 #ifdef TARGET_NR_oldfstat
4324 case TARGET_NR_oldfstat
:
4327 #ifdef TARGET_NR_pause /* not on alpha */
4328 case TARGET_NR_pause
:
4329 ret
= get_errno(pause());
4332 #ifdef TARGET_NR_utime
4333 case TARGET_NR_utime
:
4335 struct utimbuf tbuf
, *host_tbuf
;
4336 struct target_utimbuf
*target_tbuf
;
4338 if (!lock_user_struct(VERIFY_READ
, target_tbuf
, arg2
, 1))
4340 tbuf
.actime
= tswapl(target_tbuf
->actime
);
4341 tbuf
.modtime
= tswapl(target_tbuf
->modtime
);
4342 unlock_user_struct(target_tbuf
, arg2
, 0);
4347 if (!(p
= lock_user_string(arg1
)))
4349 ret
= get_errno(utime(p
, host_tbuf
));
4350 unlock_user(p
, arg1
, 0);
4354 case TARGET_NR_utimes
:
4356 struct timeval
*tvp
, tv
[2];
4358 if (copy_from_user_timeval(&tv
[0], arg2
)
4359 || copy_from_user_timeval(&tv
[1],
4360 arg2
+ sizeof(struct target_timeval
)))
4366 if (!(p
= lock_user_string(arg1
)))
4368 ret
= get_errno(utimes(p
, tvp
));
4369 unlock_user(p
, arg1
, 0);
4372 #if defined(TARGET_NR_futimesat) && defined(__NR_futimesat)
4373 case TARGET_NR_futimesat
:
4375 struct timeval
*tvp
, tv
[2];
4377 if (copy_from_user_timeval(&tv
[0], arg3
)
4378 || copy_from_user_timeval(&tv
[1],
4379 arg3
+ sizeof(struct target_timeval
)))
4385 if (!(p
= lock_user_string(arg2
)))
4387 ret
= get_errno(sys_futimesat(arg1
, path(p
), tvp
));
4388 unlock_user(p
, arg2
, 0);
4392 #ifdef TARGET_NR_stty
4393 case TARGET_NR_stty
:
4396 #ifdef TARGET_NR_gtty
4397 case TARGET_NR_gtty
:
4400 case TARGET_NR_access
:
4401 if (!(p
= lock_user_string(arg1
)))
4403 ret
= get_errno(access(p
, arg2
));
4404 unlock_user(p
, arg1
, 0);
4406 #if defined(TARGET_NR_faccessat) && defined(__NR_faccessat)
4407 case TARGET_NR_faccessat
:
4408 if (!(p
= lock_user_string(arg2
)))
4410 ret
= get_errno(sys_faccessat(arg1
, p
, arg3
));
4411 unlock_user(p
, arg2
, 0);
4414 #ifdef TARGET_NR_nice /* not on alpha */
4415 case TARGET_NR_nice
:
4416 ret
= get_errno(nice(arg1
));
4419 #ifdef TARGET_NR_ftime
4420 case TARGET_NR_ftime
:
4423 case TARGET_NR_sync
:
4427 case TARGET_NR_kill
:
4428 ret
= get_errno(kill(arg1
, target_to_host_signal(arg2
)));
4430 case TARGET_NR_rename
:
4433 p
= lock_user_string(arg1
);
4434 p2
= lock_user_string(arg2
);
4436 ret
= -TARGET_EFAULT
;
4438 ret
= get_errno(rename(p
, p2
));
4439 unlock_user(p2
, arg2
, 0);
4440 unlock_user(p
, arg1
, 0);
4443 #if defined(TARGET_NR_renameat) && defined(__NR_renameat)
4444 case TARGET_NR_renameat
:
4447 p
= lock_user_string(arg2
);
4448 p2
= lock_user_string(arg4
);
4450 ret
= -TARGET_EFAULT
;
4452 ret
= get_errno(sys_renameat(arg1
, p
, arg3
, p2
));
4453 unlock_user(p2
, arg4
, 0);
4454 unlock_user(p
, arg2
, 0);
4458 case TARGET_NR_mkdir
:
4459 if (!(p
= lock_user_string(arg1
)))
4461 ret
= get_errno(mkdir(p
, arg2
));
4462 unlock_user(p
, arg1
, 0);
4464 #if defined(TARGET_NR_mkdirat) && defined(__NR_mkdirat)
4465 case TARGET_NR_mkdirat
:
4466 if (!(p
= lock_user_string(arg2
)))
4468 ret
= get_errno(sys_mkdirat(arg1
, p
, arg3
));
4469 unlock_user(p
, arg2
, 0);
4472 case TARGET_NR_rmdir
:
4473 if (!(p
= lock_user_string(arg1
)))
4475 ret
= get_errno(rmdir(p
));
4476 unlock_user(p
, arg1
, 0);
4479 ret
= get_errno(dup(arg1
));
4481 case TARGET_NR_pipe
:
4484 ret
= get_errno(pipe(host_pipe
));
4485 if (!is_error(ret
)) {
4486 #if defined(TARGET_MIPS)
4487 CPUMIPSState
*env
= (CPUMIPSState
*)cpu_env
;
4488 env
->active_tc
.gpr
[3] = host_pipe
[1];
4490 #elif defined(TARGET_SH4)
4491 ((CPUSH4State
*)cpu_env
)->gregs
[1] = host_pipe
[1];
4494 if (put_user_s32(host_pipe
[0], arg1
)
4495 || put_user_s32(host_pipe
[1], arg1
+ sizeof(host_pipe
[0])))
4501 case TARGET_NR_times
:
4503 struct target_tms
*tmsp
;
4505 ret
= get_errno(times(&tms
));
4507 tmsp
= lock_user(VERIFY_WRITE
, arg1
, sizeof(struct target_tms
), 0);
4510 tmsp
->tms_utime
= tswapl(host_to_target_clock_t(tms
.tms_utime
));
4511 tmsp
->tms_stime
= tswapl(host_to_target_clock_t(tms
.tms_stime
));
4512 tmsp
->tms_cutime
= tswapl(host_to_target_clock_t(tms
.tms_cutime
));
4513 tmsp
->tms_cstime
= tswapl(host_to_target_clock_t(tms
.tms_cstime
));
4516 ret
= host_to_target_clock_t(ret
);
4519 #ifdef TARGET_NR_prof
4520 case TARGET_NR_prof
:
4523 #ifdef TARGET_NR_signal
4524 case TARGET_NR_signal
:
4527 case TARGET_NR_acct
:
4529 ret
= get_errno(acct(NULL
));
4531 if (!(p
= lock_user_string(arg1
)))
4533 ret
= get_errno(acct(path(p
)));
4534 unlock_user(p
, arg1
, 0);
4537 #ifdef TARGET_NR_umount2 /* not on alpha */
4538 case TARGET_NR_umount2
:
4539 if (!(p
= lock_user_string(arg1
)))
4541 ret
= get_errno(umount2(p
, arg2
));
4542 unlock_user(p
, arg1
, 0);
4545 #ifdef TARGET_NR_lock
4546 case TARGET_NR_lock
:
4549 case TARGET_NR_ioctl
:
4550 ret
= do_ioctl(arg1
, arg2
, arg3
);
4552 case TARGET_NR_fcntl
:
4553 ret
= do_fcntl(arg1
, arg2
, arg3
);
4555 #ifdef TARGET_NR_mpx
4559 case TARGET_NR_setpgid
:
4560 ret
= get_errno(setpgid(arg1
, arg2
));
4562 #ifdef TARGET_NR_ulimit
4563 case TARGET_NR_ulimit
:
4566 #ifdef TARGET_NR_oldolduname
4567 case TARGET_NR_oldolduname
:
4570 case TARGET_NR_umask
:
4571 ret
= get_errno(umask(arg1
));
4573 case TARGET_NR_chroot
:
4574 if (!(p
= lock_user_string(arg1
)))
4576 ret
= get_errno(chroot(p
));
4577 unlock_user(p
, arg1
, 0);
4579 case TARGET_NR_ustat
:
4581 case TARGET_NR_dup2
:
4582 ret
= get_errno(dup2(arg1
, arg2
));
4584 #ifdef TARGET_NR_getppid /* not on alpha */
4585 case TARGET_NR_getppid
:
4586 ret
= get_errno(getppid());
4589 case TARGET_NR_getpgrp
:
4590 ret
= get_errno(getpgrp());
4592 case TARGET_NR_setsid
:
4593 ret
= get_errno(setsid());
4595 #ifdef TARGET_NR_sigaction
4596 case TARGET_NR_sigaction
:
4598 #if !defined(TARGET_MIPS)
4599 struct target_old_sigaction
*old_act
;
4600 struct target_sigaction act
, oact
, *pact
;
4602 if (!lock_user_struct(VERIFY_READ
, old_act
, arg2
, 1))
4604 act
._sa_handler
= old_act
->_sa_handler
;
4605 target_siginitset(&act
.sa_mask
, old_act
->sa_mask
);
4606 act
.sa_flags
= old_act
->sa_flags
;
4607 act
.sa_restorer
= old_act
->sa_restorer
;
4608 unlock_user_struct(old_act
, arg2
, 0);
4613 ret
= get_errno(do_sigaction(arg1
, pact
, &oact
));
4614 if (!is_error(ret
) && arg3
) {
4615 if (!lock_user_struct(VERIFY_WRITE
, old_act
, arg3
, 0))
4617 old_act
->_sa_handler
= oact
._sa_handler
;
4618 old_act
->sa_mask
= oact
.sa_mask
.sig
[0];
4619 old_act
->sa_flags
= oact
.sa_flags
;
4620 old_act
->sa_restorer
= oact
.sa_restorer
;
4621 unlock_user_struct(old_act
, arg3
, 1);
4624 struct target_sigaction act
, oact
, *pact
, *old_act
;
4627 if (!lock_user_struct(VERIFY_READ
, old_act
, arg2
, 1))
4629 act
._sa_handler
= old_act
->_sa_handler
;
4630 target_siginitset(&act
.sa_mask
, old_act
->sa_mask
.sig
[0]);
4631 act
.sa_flags
= old_act
->sa_flags
;
4632 unlock_user_struct(old_act
, arg2
, 0);
4638 ret
= get_errno(do_sigaction(arg1
, pact
, &oact
));
4640 if (!is_error(ret
) && arg3
) {
4641 if (!lock_user_struct(VERIFY_WRITE
, old_act
, arg3
, 0))
4643 old_act
->_sa_handler
= oact
._sa_handler
;
4644 old_act
->sa_flags
= oact
.sa_flags
;
4645 old_act
->sa_mask
.sig
[0] = oact
.sa_mask
.sig
[0];
4646 old_act
->sa_mask
.sig
[1] = 0;
4647 old_act
->sa_mask
.sig
[2] = 0;
4648 old_act
->sa_mask
.sig
[3] = 0;
4649 unlock_user_struct(old_act
, arg3
, 1);
4655 case TARGET_NR_rt_sigaction
:
4657 struct target_sigaction
*act
;
4658 struct target_sigaction
*oact
;
4661 if (!lock_user_struct(VERIFY_READ
, act
, arg2
, 1))
4666 if (!lock_user_struct(VERIFY_WRITE
, oact
, arg3
, 0)) {
4667 ret
= -TARGET_EFAULT
;
4668 goto rt_sigaction_fail
;
4672 ret
= get_errno(do_sigaction(arg1
, act
, oact
));
4675 unlock_user_struct(act
, arg2
, 0);
4677 unlock_user_struct(oact
, arg3
, 1);
4680 #ifdef TARGET_NR_sgetmask /* not on alpha */
4681 case TARGET_NR_sgetmask
:
4684 abi_ulong target_set
;
4685 sigprocmask(0, NULL
, &cur_set
);
4686 host_to_target_old_sigset(&target_set
, &cur_set
);
4691 #ifdef TARGET_NR_ssetmask /* not on alpha */
4692 case TARGET_NR_ssetmask
:
4694 sigset_t set
, oset
, cur_set
;
4695 abi_ulong target_set
= arg1
;
4696 sigprocmask(0, NULL
, &cur_set
);
4697 target_to_host_old_sigset(&set
, &target_set
);
4698 sigorset(&set
, &set
, &cur_set
);
4699 sigprocmask(SIG_SETMASK
, &set
, &oset
);
4700 host_to_target_old_sigset(&target_set
, &oset
);
4705 #ifdef TARGET_NR_sigprocmask
4706 case TARGET_NR_sigprocmask
:
4709 sigset_t set
, oldset
, *set_ptr
;
4713 case TARGET_SIG_BLOCK
:
4716 case TARGET_SIG_UNBLOCK
:
4719 case TARGET_SIG_SETMASK
:
4723 ret
= -TARGET_EINVAL
;
4726 if (!(p
= lock_user(VERIFY_READ
, arg2
, sizeof(target_sigset_t
), 1)))
4728 target_to_host_old_sigset(&set
, p
);
4729 unlock_user(p
, arg2
, 0);
4735 ret
= get_errno(sigprocmask(arg1
, set_ptr
, &oldset
));
4736 if (!is_error(ret
) && arg3
) {
4737 if (!(p
= lock_user(VERIFY_WRITE
, arg3
, sizeof(target_sigset_t
), 0)))
4739 host_to_target_old_sigset(p
, &oldset
);
4740 unlock_user(p
, arg3
, sizeof(target_sigset_t
));
4745 case TARGET_NR_rt_sigprocmask
:
4748 sigset_t set
, oldset
, *set_ptr
;
4752 case TARGET_SIG_BLOCK
:
4755 case TARGET_SIG_UNBLOCK
:
4758 case TARGET_SIG_SETMASK
:
4762 ret
= -TARGET_EINVAL
;
4765 if (!(p
= lock_user(VERIFY_READ
, arg2
, sizeof(target_sigset_t
), 1)))
4767 target_to_host_sigset(&set
, p
);
4768 unlock_user(p
, arg2
, 0);
4774 ret
= get_errno(sigprocmask(how
, set_ptr
, &oldset
));
4775 if (!is_error(ret
) && arg3
) {
4776 if (!(p
= lock_user(VERIFY_WRITE
, arg3
, sizeof(target_sigset_t
), 0)))
4778 host_to_target_sigset(p
, &oldset
);
4779 unlock_user(p
, arg3
, sizeof(target_sigset_t
));
4783 #ifdef TARGET_NR_sigpending
4784 case TARGET_NR_sigpending
:
4787 ret
= get_errno(sigpending(&set
));
4788 if (!is_error(ret
)) {
4789 if (!(p
= lock_user(VERIFY_WRITE
, arg1
, sizeof(target_sigset_t
), 0)))
4791 host_to_target_old_sigset(p
, &set
);
4792 unlock_user(p
, arg1
, sizeof(target_sigset_t
));
4797 case TARGET_NR_rt_sigpending
:
4800 ret
= get_errno(sigpending(&set
));
4801 if (!is_error(ret
)) {
4802 if (!(p
= lock_user(VERIFY_WRITE
, arg1
, sizeof(target_sigset_t
), 0)))
4804 host_to_target_sigset(p
, &set
);
4805 unlock_user(p
, arg1
, sizeof(target_sigset_t
));
4809 #ifdef TARGET_NR_sigsuspend
4810 case TARGET_NR_sigsuspend
:
4813 if (!(p
= lock_user(VERIFY_READ
, arg1
, sizeof(target_sigset_t
), 1)))
4815 target_to_host_old_sigset(&set
, p
);
4816 unlock_user(p
, arg1
, 0);
4817 ret
= get_errno(sigsuspend(&set
));
4821 case TARGET_NR_rt_sigsuspend
:
4824 if (!(p
= lock_user(VERIFY_READ
, arg1
, sizeof(target_sigset_t
), 1)))
4826 target_to_host_sigset(&set
, p
);
4827 unlock_user(p
, arg1
, 0);
4828 ret
= get_errno(sigsuspend(&set
));
4831 case TARGET_NR_rt_sigtimedwait
:
4834 struct timespec uts
, *puts
;
4837 if (!(p
= lock_user(VERIFY_READ
, arg1
, sizeof(target_sigset_t
), 1)))
4839 target_to_host_sigset(&set
, p
);
4840 unlock_user(p
, arg1
, 0);
4843 target_to_host_timespec(puts
, arg3
);
4847 ret
= get_errno(sigtimedwait(&set
, &uinfo
, puts
));
4848 if (!is_error(ret
) && arg2
) {
4849 if (!(p
= lock_user(VERIFY_WRITE
, arg2
, sizeof(target_siginfo_t
), 0)))
4851 host_to_target_siginfo(p
, &uinfo
);
4852 unlock_user(p
, arg2
, sizeof(target_siginfo_t
));
4856 case TARGET_NR_rt_sigqueueinfo
:
4859 if (!(p
= lock_user(VERIFY_READ
, arg3
, sizeof(target_sigset_t
), 1)))
4861 target_to_host_siginfo(&uinfo
, p
);
4862 unlock_user(p
, arg1
, 0);
4863 ret
= get_errno(sys_rt_sigqueueinfo(arg1
, arg2
, &uinfo
));
4866 #ifdef TARGET_NR_sigreturn
4867 case TARGET_NR_sigreturn
:
4868 /* NOTE: ret is eax, so not transcoding must be done */
4869 ret
= do_sigreturn(cpu_env
);
4872 case TARGET_NR_rt_sigreturn
:
4873 /* NOTE: ret is eax, so not transcoding must be done */
4874 ret
= do_rt_sigreturn(cpu_env
);
4876 case TARGET_NR_sethostname
:
4877 if (!(p
= lock_user_string(arg1
)))
4879 ret
= get_errno(sethostname(p
, arg2
));
4880 unlock_user(p
, arg1
, 0);
4882 case TARGET_NR_setrlimit
:
4884 /* XXX: convert resource ? */
4885 int resource
= arg1
;
4886 struct target_rlimit
*target_rlim
;
4888 if (!lock_user_struct(VERIFY_READ
, target_rlim
, arg2
, 1))
4890 rlim
.rlim_cur
= tswapl(target_rlim
->rlim_cur
);
4891 rlim
.rlim_max
= tswapl(target_rlim
->rlim_max
);
4892 unlock_user_struct(target_rlim
, arg2
, 0);
4893 ret
= get_errno(setrlimit(resource
, &rlim
));
4896 case TARGET_NR_getrlimit
:
4898 /* XXX: convert resource ? */
4899 int resource
= arg1
;
4900 struct target_rlimit
*target_rlim
;
4903 ret
= get_errno(getrlimit(resource
, &rlim
));
4904 if (!is_error(ret
)) {
4905 if (!lock_user_struct(VERIFY_WRITE
, target_rlim
, arg2
, 0))
4907 rlim
.rlim_cur
= tswapl(target_rlim
->rlim_cur
);
4908 rlim
.rlim_max
= tswapl(target_rlim
->rlim_max
);
4909 unlock_user_struct(target_rlim
, arg2
, 1);
4913 case TARGET_NR_getrusage
:
4915 struct rusage rusage
;
4916 ret
= get_errno(getrusage(arg1
, &rusage
));
4917 if (!is_error(ret
)) {
4918 host_to_target_rusage(arg2
, &rusage
);
4922 case TARGET_NR_gettimeofday
:
4925 ret
= get_errno(gettimeofday(&tv
, NULL
));
4926 if (!is_error(ret
)) {
4927 if (copy_to_user_timeval(arg1
, &tv
))
4932 case TARGET_NR_settimeofday
:
4935 if (copy_from_user_timeval(&tv
, arg1
))
4937 ret
= get_errno(settimeofday(&tv
, NULL
));
4940 #ifdef TARGET_NR_select
4941 case TARGET_NR_select
:
4943 struct target_sel_arg_struct
*sel
;
4944 abi_ulong inp
, outp
, exp
, tvp
;
4947 if (!lock_user_struct(VERIFY_READ
, sel
, arg1
, 1))
4949 nsel
= tswapl(sel
->n
);
4950 inp
= tswapl(sel
->inp
);
4951 outp
= tswapl(sel
->outp
);
4952 exp
= tswapl(sel
->exp
);
4953 tvp
= tswapl(sel
->tvp
);
4954 unlock_user_struct(sel
, arg1
, 0);
4955 ret
= do_select(nsel
, inp
, outp
, exp
, tvp
);
4959 case TARGET_NR_symlink
:
4962 p
= lock_user_string(arg1
);
4963 p2
= lock_user_string(arg2
);
4965 ret
= -TARGET_EFAULT
;
4967 ret
= get_errno(symlink(p
, p2
));
4968 unlock_user(p2
, arg2
, 0);
4969 unlock_user(p
, arg1
, 0);
4972 #if defined(TARGET_NR_symlinkat) && defined(__NR_symlinkat)
4973 case TARGET_NR_symlinkat
:
4976 p
= lock_user_string(arg1
);
4977 p2
= lock_user_string(arg3
);
4979 ret
= -TARGET_EFAULT
;
4981 ret
= get_errno(sys_symlinkat(p
, arg2
, p2
));
4982 unlock_user(p2
, arg3
, 0);
4983 unlock_user(p
, arg1
, 0);
4987 #ifdef TARGET_NR_oldlstat
4988 case TARGET_NR_oldlstat
:
4991 case TARGET_NR_readlink
:
4994 p
= lock_user_string(arg1
);
4995 p2
= lock_user(VERIFY_WRITE
, arg2
, arg3
, 0);
4997 ret
= -TARGET_EFAULT
;
4999 if (strncmp((const char *)p
, "/proc/self/exe", 14) == 0) {
5000 char real
[PATH_MAX
];
5001 temp
= realpath(exec_path
,real
);
5002 ret
= (temp
==NULL
) ? get_errno(-1) : strlen(real
) ;
5003 snprintf((char *)p2
, arg3
, "%s", real
);
5006 ret
= get_errno(readlink(path(p
), p2
, arg3
));
5008 unlock_user(p2
, arg2
, ret
);
5009 unlock_user(p
, arg1
, 0);
5012 #if defined(TARGET_NR_readlinkat) && defined(__NR_readlinkat)
5013 case TARGET_NR_readlinkat
:
5016 p
= lock_user_string(arg2
);
5017 p2
= lock_user(VERIFY_WRITE
, arg3
, arg4
, 0);
5019 ret
= -TARGET_EFAULT
;
5021 ret
= get_errno(sys_readlinkat(arg1
, path(p
), p2
, arg4
));
5022 unlock_user(p2
, arg3
, ret
);
5023 unlock_user(p
, arg2
, 0);
5027 #ifdef TARGET_NR_uselib
5028 case TARGET_NR_uselib
:
5031 #ifdef TARGET_NR_swapon
5032 case TARGET_NR_swapon
:
5033 if (!(p
= lock_user_string(arg1
)))
5035 ret
= get_errno(swapon(p
, arg2
));
5036 unlock_user(p
, arg1
, 0);
5039 case TARGET_NR_reboot
:
5041 #ifdef TARGET_NR_readdir
5042 case TARGET_NR_readdir
:
5045 #ifdef TARGET_NR_mmap
5046 case TARGET_NR_mmap
:
5047 #if (defined(TARGET_I386) && defined(TARGET_ABI32)) || defined(TARGET_ARM) || defined(TARGET_M68K) || defined(TARGET_CRIS) || defined(TARGET_MICROBLAZE)
5050 abi_ulong v1
, v2
, v3
, v4
, v5
, v6
;
5051 if (!(v
= lock_user(VERIFY_READ
, arg1
, 6 * sizeof(abi_ulong
), 1)))
5059 unlock_user(v
, arg1
, 0);
5060 ret
= get_errno(target_mmap(v1
, v2
, v3
,
5061 target_to_host_bitmask(v4
, mmap_flags_tbl
),
5065 ret
= get_errno(target_mmap(arg1
, arg2
, arg3
,
5066 target_to_host_bitmask(arg4
, mmap_flags_tbl
),
5072 #ifdef TARGET_NR_mmap2
5073 case TARGET_NR_mmap2
:
5075 #define MMAP_SHIFT 12
5077 ret
= get_errno(target_mmap(arg1
, arg2
, arg3
,
5078 target_to_host_bitmask(arg4
, mmap_flags_tbl
),
5080 arg6
<< MMAP_SHIFT
));
5083 case TARGET_NR_munmap
:
5084 ret
= get_errno(target_munmap(arg1
, arg2
));
5086 case TARGET_NR_mprotect
:
5087 ret
= get_errno(target_mprotect(arg1
, arg2
, arg3
));
5089 #ifdef TARGET_NR_mremap
5090 case TARGET_NR_mremap
:
5091 ret
= get_errno(target_mremap(arg1
, arg2
, arg3
, arg4
, arg5
));
5094 /* ??? msync/mlock/munlock are broken for softmmu. */
5095 #ifdef TARGET_NR_msync
5096 case TARGET_NR_msync
:
5097 ret
= get_errno(msync(g2h(arg1
), arg2
, arg3
));
5100 #ifdef TARGET_NR_mlock
5101 case TARGET_NR_mlock
:
5102 ret
= get_errno(mlock(g2h(arg1
), arg2
));
5105 #ifdef TARGET_NR_munlock
5106 case TARGET_NR_munlock
:
5107 ret
= get_errno(munlock(g2h(arg1
), arg2
));
5110 #ifdef TARGET_NR_mlockall
5111 case TARGET_NR_mlockall
:
5112 ret
= get_errno(mlockall(arg1
));
5115 #ifdef TARGET_NR_munlockall
5116 case TARGET_NR_munlockall
:
5117 ret
= get_errno(munlockall());
5120 case TARGET_NR_truncate
:
5121 if (!(p
= lock_user_string(arg1
)))
5123 ret
= get_errno(truncate(p
, arg2
));
5124 unlock_user(p
, arg1
, 0);
5126 case TARGET_NR_ftruncate
:
5127 ret
= get_errno(ftruncate(arg1
, arg2
));
5129 case TARGET_NR_fchmod
:
5130 ret
= get_errno(fchmod(arg1
, arg2
));
5132 #if defined(TARGET_NR_fchmodat) && defined(__NR_fchmodat)
5133 case TARGET_NR_fchmodat
:
5134 if (!(p
= lock_user_string(arg2
)))
5136 ret
= get_errno(sys_fchmodat(arg1
, p
, arg3
));
5137 unlock_user(p
, arg2
, 0);
5140 case TARGET_NR_getpriority
:
5141 /* libc does special remapping of the return value of
5142 * sys_getpriority() so it's just easiest to call
5143 * sys_getpriority() directly rather than through libc. */
5144 ret
= sys_getpriority(arg1
, arg2
);
5146 case TARGET_NR_setpriority
:
5147 ret
= get_errno(setpriority(arg1
, arg2
, arg3
));
5149 #ifdef TARGET_NR_profil
5150 case TARGET_NR_profil
:
5153 case TARGET_NR_statfs
:
5154 if (!(p
= lock_user_string(arg1
)))
5156 ret
= get_errno(statfs(path(p
), &stfs
));
5157 unlock_user(p
, arg1
, 0);
5159 if (!is_error(ret
)) {
5160 struct target_statfs
*target_stfs
;
5162 if (!lock_user_struct(VERIFY_WRITE
, target_stfs
, arg2
, 0))
5164 __put_user(stfs
.f_type
, &target_stfs
->f_type
);
5165 __put_user(stfs
.f_bsize
, &target_stfs
->f_bsize
);
5166 __put_user(stfs
.f_blocks
, &target_stfs
->f_blocks
);
5167 __put_user(stfs
.f_bfree
, &target_stfs
->f_bfree
);
5168 __put_user(stfs
.f_bavail
, &target_stfs
->f_bavail
);
5169 __put_user(stfs
.f_files
, &target_stfs
->f_files
);
5170 __put_user(stfs
.f_ffree
, &target_stfs
->f_ffree
);
5171 __put_user(stfs
.f_fsid
.__val
[0], &target_stfs
->f_fsid
.val
[0]);
5172 __put_user(stfs
.f_fsid
.__val
[1], &target_stfs
->f_fsid
.val
[1]);
5173 __put_user(stfs
.f_namelen
, &target_stfs
->f_namelen
);
5174 unlock_user_struct(target_stfs
, arg2
, 1);
5177 case TARGET_NR_fstatfs
:
5178 ret
= get_errno(fstatfs(arg1
, &stfs
));
5179 goto convert_statfs
;
5180 #ifdef TARGET_NR_statfs64
5181 case TARGET_NR_statfs64
:
5182 if (!(p
= lock_user_string(arg1
)))
5184 ret
= get_errno(statfs(path(p
), &stfs
));
5185 unlock_user(p
, arg1
, 0);
5187 if (!is_error(ret
)) {
5188 struct target_statfs64
*target_stfs
;
5190 if (!lock_user_struct(VERIFY_WRITE
, target_stfs
, arg3
, 0))
5192 __put_user(stfs
.f_type
, &target_stfs
->f_type
);
5193 __put_user(stfs
.f_bsize
, &target_stfs
->f_bsize
);
5194 __put_user(stfs
.f_blocks
, &target_stfs
->f_blocks
);
5195 __put_user(stfs
.f_bfree
, &target_stfs
->f_bfree
);
5196 __put_user(stfs
.f_bavail
, &target_stfs
->f_bavail
);
5197 __put_user(stfs
.f_files
, &target_stfs
->f_files
);
5198 __put_user(stfs
.f_ffree
, &target_stfs
->f_ffree
);
5199 __put_user(stfs
.f_fsid
.__val
[0], &target_stfs
->f_fsid
.val
[0]);
5200 __put_user(stfs
.f_fsid
.__val
[1], &target_stfs
->f_fsid
.val
[1]);
5201 __put_user(stfs
.f_namelen
, &target_stfs
->f_namelen
);
5202 unlock_user_struct(target_stfs
, arg3
, 1);
5205 case TARGET_NR_fstatfs64
:
5206 ret
= get_errno(fstatfs(arg1
, &stfs
));
5207 goto convert_statfs64
;
5209 #ifdef TARGET_NR_ioperm
5210 case TARGET_NR_ioperm
:
5213 #ifdef TARGET_NR_socketcall
5214 case TARGET_NR_socketcall
:
5215 ret
= do_socketcall(arg1
, arg2
);
5218 #ifdef TARGET_NR_accept
5219 case TARGET_NR_accept
:
5220 ret
= do_accept(arg1
, arg2
, arg3
);
5223 #ifdef TARGET_NR_bind
5224 case TARGET_NR_bind
:
5225 ret
= do_bind(arg1
, arg2
, arg3
);
5228 #ifdef TARGET_NR_connect
5229 case TARGET_NR_connect
:
5230 ret
= do_connect(arg1
, arg2
, arg3
);
5233 #ifdef TARGET_NR_getpeername
5234 case TARGET_NR_getpeername
:
5235 ret
= do_getpeername(arg1
, arg2
, arg3
);
5238 #ifdef TARGET_NR_getsockname
5239 case TARGET_NR_getsockname
:
5240 ret
= do_getsockname(arg1
, arg2
, arg3
);
5243 #ifdef TARGET_NR_getsockopt
5244 case TARGET_NR_getsockopt
:
5245 ret
= do_getsockopt(arg1
, arg2
, arg3
, arg4
, arg5
);
5248 #ifdef TARGET_NR_listen
5249 case TARGET_NR_listen
:
5250 ret
= get_errno(listen(arg1
, arg2
));
5253 #ifdef TARGET_NR_recv
5254 case TARGET_NR_recv
:
5255 ret
= do_recvfrom(arg1
, arg2
, arg3
, arg4
, 0, 0);
5258 #ifdef TARGET_NR_recvfrom
5259 case TARGET_NR_recvfrom
:
5260 ret
= do_recvfrom(arg1
, arg2
, arg3
, arg4
, arg5
, arg6
);
5263 #ifdef TARGET_NR_recvmsg
5264 case TARGET_NR_recvmsg
:
5265 ret
= do_sendrecvmsg(arg1
, arg2
, arg3
, 0);
5268 #ifdef TARGET_NR_send
5269 case TARGET_NR_send
:
5270 ret
= do_sendto(arg1
, arg2
, arg3
, arg4
, 0, 0);
5273 #ifdef TARGET_NR_sendmsg
5274 case TARGET_NR_sendmsg
:
5275 ret
= do_sendrecvmsg(arg1
, arg2
, arg3
, 1);
5278 #ifdef TARGET_NR_sendto
5279 case TARGET_NR_sendto
:
5280 ret
= do_sendto(arg1
, arg2
, arg3
, arg4
, arg5
, arg6
);
5283 #ifdef TARGET_NR_shutdown
5284 case TARGET_NR_shutdown
:
5285 ret
= get_errno(shutdown(arg1
, arg2
));
5288 #ifdef TARGET_NR_socket
5289 case TARGET_NR_socket
:
5290 ret
= do_socket(arg1
, arg2
, arg3
);
5293 #ifdef TARGET_NR_socketpair
5294 case TARGET_NR_socketpair
:
5295 ret
= do_socketpair(arg1
, arg2
, arg3
, arg4
);
5298 #ifdef TARGET_NR_setsockopt
5299 case TARGET_NR_setsockopt
:
5300 ret
= do_setsockopt(arg1
, arg2
, arg3
, arg4
, (socklen_t
) arg5
);
5304 case TARGET_NR_syslog
:
5305 if (!(p
= lock_user_string(arg2
)))
5307 ret
= get_errno(sys_syslog((int)arg1
, p
, (int)arg3
));
5308 unlock_user(p
, arg2
, 0);
5311 case TARGET_NR_setitimer
:
5313 struct itimerval value
, ovalue
, *pvalue
;
5317 if (copy_from_user_timeval(&pvalue
->it_interval
, arg2
)
5318 || copy_from_user_timeval(&pvalue
->it_value
,
5319 arg2
+ sizeof(struct target_timeval
)))
5324 ret
= get_errno(setitimer(arg1
, pvalue
, &ovalue
));
5325 if (!is_error(ret
) && arg3
) {
5326 if (copy_to_user_timeval(arg3
,
5327 &ovalue
.it_interval
)
5328 || copy_to_user_timeval(arg3
+ sizeof(struct target_timeval
),
5334 case TARGET_NR_getitimer
:
5336 struct itimerval value
;
5338 ret
= get_errno(getitimer(arg1
, &value
));
5339 if (!is_error(ret
) && arg2
) {
5340 if (copy_to_user_timeval(arg2
,
5342 || copy_to_user_timeval(arg2
+ sizeof(struct target_timeval
),
5348 case TARGET_NR_stat
:
5349 if (!(p
= lock_user_string(arg1
)))
5351 ret
= get_errno(stat(path(p
), &st
));
5352 unlock_user(p
, arg1
, 0);
5354 case TARGET_NR_lstat
:
5355 if (!(p
= lock_user_string(arg1
)))
5357 ret
= get_errno(lstat(path(p
), &st
));
5358 unlock_user(p
, arg1
, 0);
5360 case TARGET_NR_fstat
:
5362 ret
= get_errno(fstat(arg1
, &st
));
5364 if (!is_error(ret
)) {
5365 struct target_stat
*target_st
;
5367 if (!lock_user_struct(VERIFY_WRITE
, target_st
, arg2
, 0))
5369 __put_user(st
.st_dev
, &target_st
->st_dev
);
5370 __put_user(st
.st_ino
, &target_st
->st_ino
);
5371 __put_user(st
.st_mode
, &target_st
->st_mode
);
5372 __put_user(st
.st_uid
, &target_st
->st_uid
);
5373 __put_user(st
.st_gid
, &target_st
->st_gid
);
5374 __put_user(st
.st_nlink
, &target_st
->st_nlink
);
5375 __put_user(st
.st_rdev
, &target_st
->st_rdev
);
5376 __put_user(st
.st_size
, &target_st
->st_size
);
5377 __put_user(st
.st_blksize
, &target_st
->st_blksize
);
5378 __put_user(st
.st_blocks
, &target_st
->st_blocks
);
5379 __put_user(st
.st_atime
, &target_st
->target_st_atime
);
5380 __put_user(st
.st_mtime
, &target_st
->target_st_mtime
);
5381 __put_user(st
.st_ctime
, &target_st
->target_st_ctime
);
5382 unlock_user_struct(target_st
, arg2
, 1);
5386 #ifdef TARGET_NR_olduname
5387 case TARGET_NR_olduname
:
5390 #ifdef TARGET_NR_iopl
5391 case TARGET_NR_iopl
:
5394 case TARGET_NR_vhangup
:
5395 ret
= get_errno(vhangup());
5397 #ifdef TARGET_NR_idle
5398 case TARGET_NR_idle
:
5401 #ifdef TARGET_NR_syscall
5402 case TARGET_NR_syscall
:
5403 ret
= do_syscall(cpu_env
,arg1
& 0xffff,arg2
,arg3
,arg4
,arg5
,arg6
,0);
5406 case TARGET_NR_wait4
:
5409 abi_long status_ptr
= arg2
;
5410 struct rusage rusage
, *rusage_ptr
;
5411 abi_ulong target_rusage
= arg4
;
5413 rusage_ptr
= &rusage
;
5416 ret
= get_errno(wait4(arg1
, &status
, arg3
, rusage_ptr
));
5417 if (!is_error(ret
)) {
5419 status
= host_to_target_waitstatus(status
);
5420 if (put_user_s32(status
, status_ptr
))
5424 host_to_target_rusage(target_rusage
, &rusage
);
5428 #ifdef TARGET_NR_swapoff
5429 case TARGET_NR_swapoff
:
5430 if (!(p
= lock_user_string(arg1
)))
5432 ret
= get_errno(swapoff(p
));
5433 unlock_user(p
, arg1
, 0);
5436 case TARGET_NR_sysinfo
:
5438 struct target_sysinfo
*target_value
;
5439 struct sysinfo value
;
5440 ret
= get_errno(sysinfo(&value
));
5441 if (!is_error(ret
) && arg1
)
5443 if (!lock_user_struct(VERIFY_WRITE
, target_value
, arg1
, 0))
5445 __put_user(value
.uptime
, &target_value
->uptime
);
5446 __put_user(value
.loads
[0], &target_value
->loads
[0]);
5447 __put_user(value
.loads
[1], &target_value
->loads
[1]);
5448 __put_user(value
.loads
[2], &target_value
->loads
[2]);
5449 __put_user(value
.totalram
, &target_value
->totalram
);
5450 __put_user(value
.freeram
, &target_value
->freeram
);
5451 __put_user(value
.sharedram
, &target_value
->sharedram
);
5452 __put_user(value
.bufferram
, &target_value
->bufferram
);
5453 __put_user(value
.totalswap
, &target_value
->totalswap
);
5454 __put_user(value
.freeswap
, &target_value
->freeswap
);
5455 __put_user(value
.procs
, &target_value
->procs
);
5456 __put_user(value
.totalhigh
, &target_value
->totalhigh
);
5457 __put_user(value
.freehigh
, &target_value
->freehigh
);
5458 __put_user(value
.mem_unit
, &target_value
->mem_unit
);
5459 unlock_user_struct(target_value
, arg1
, 1);
5463 #ifdef TARGET_NR_ipc
5465 ret
= do_ipc(arg1
, arg2
, arg3
, arg4
, arg5
, arg6
);
5468 #ifdef TARGET_NR_semget
5469 case TARGET_NR_semget
:
5470 ret
= get_errno(semget(arg1
, arg2
, arg3
));
5473 #ifdef TARGET_NR_semop
5474 case TARGET_NR_semop
:
5475 ret
= get_errno(do_semop(arg1
, arg2
, arg3
));
5478 #ifdef TARGET_NR_semctl
5479 case TARGET_NR_semctl
:
5480 ret
= do_semctl(arg1
, arg2
, arg3
, (union target_semun
)(abi_ulong
)arg4
);
5483 #ifdef TARGET_NR_msgctl
5484 case TARGET_NR_msgctl
:
5485 ret
= do_msgctl(arg1
, arg2
, arg3
);
5488 #ifdef TARGET_NR_msgget
5489 case TARGET_NR_msgget
:
5490 ret
= get_errno(msgget(arg1
, arg2
));
5493 #ifdef TARGET_NR_msgrcv
5494 case TARGET_NR_msgrcv
:
5495 ret
= do_msgrcv(arg1
, arg2
, arg3
, arg4
, arg5
);
5498 #ifdef TARGET_NR_msgsnd
5499 case TARGET_NR_msgsnd
:
5500 ret
= do_msgsnd(arg1
, arg2
, arg3
, arg4
);
5503 #ifdef TARGET_NR_shmget
5504 case TARGET_NR_shmget
:
5505 ret
= get_errno(shmget(arg1
, arg2
, arg3
));
5508 #ifdef TARGET_NR_shmctl
5509 case TARGET_NR_shmctl
:
5510 ret
= do_shmctl(arg1
, arg2
, arg3
);
5513 #ifdef TARGET_NR_shmat
5514 case TARGET_NR_shmat
:
5515 ret
= do_shmat(arg1
, arg2
, arg3
);
5518 #ifdef TARGET_NR_shmdt
5519 case TARGET_NR_shmdt
:
5520 ret
= do_shmdt(arg1
);
5523 case TARGET_NR_fsync
:
5524 ret
= get_errno(fsync(arg1
));
5526 case TARGET_NR_clone
:
5527 #if defined(TARGET_SH4)
5528 ret
= get_errno(do_fork(cpu_env
, arg1
, arg2
, arg3
, arg5
, arg4
));
5529 #elif defined(TARGET_CRIS)
5530 ret
= get_errno(do_fork(cpu_env
, arg2
, arg1
, arg3
, arg4
, arg5
));
5532 ret
= get_errno(do_fork(cpu_env
, arg1
, arg2
, arg3
, arg4
, arg5
));
5535 #ifdef __NR_exit_group
5536 /* new thread calls */
5537 case TARGET_NR_exit_group
:
5541 gdb_exit(cpu_env
, arg1
);
5542 ret
= get_errno(exit_group(arg1
));
5545 case TARGET_NR_setdomainname
:
5546 if (!(p
= lock_user_string(arg1
)))
5548 ret
= get_errno(setdomainname(p
, arg2
));
5549 unlock_user(p
, arg1
, 0);
5551 case TARGET_NR_uname
:
5552 /* no need to transcode because we use the linux syscall */
5554 struct new_utsname
* buf
;
5556 if (!lock_user_struct(VERIFY_WRITE
, buf
, arg1
, 0))
5558 ret
= get_errno(sys_uname(buf
));
5559 if (!is_error(ret
)) {
5560 /* Overrite the native machine name with whatever is being
5562 strcpy (buf
->machine
, UNAME_MACHINE
);
5563 /* Allow the user to override the reported release. */
5564 if (qemu_uname_release
&& *qemu_uname_release
)
5565 strcpy (buf
->release
, qemu_uname_release
);
5567 unlock_user_struct(buf
, arg1
, 1);
5571 case TARGET_NR_modify_ldt
:
5572 ret
= do_modify_ldt(cpu_env
, arg1
, arg2
, arg3
);
5574 #if !defined(TARGET_X86_64)
5575 case TARGET_NR_vm86old
:
5577 case TARGET_NR_vm86
:
5578 ret
= do_vm86(cpu_env
, arg1
, arg2
);
5582 case TARGET_NR_adjtimex
:
5584 #ifdef TARGET_NR_create_module
5585 case TARGET_NR_create_module
:
5587 case TARGET_NR_init_module
:
5588 case TARGET_NR_delete_module
:
5589 #ifdef TARGET_NR_get_kernel_syms
5590 case TARGET_NR_get_kernel_syms
:
5593 case TARGET_NR_quotactl
:
5595 case TARGET_NR_getpgid
:
5596 ret
= get_errno(getpgid(arg1
));
5598 case TARGET_NR_fchdir
:
5599 ret
= get_errno(fchdir(arg1
));
5601 #ifdef TARGET_NR_bdflush /* not on x86_64 */
5602 case TARGET_NR_bdflush
:
5605 #ifdef TARGET_NR_sysfs
5606 case TARGET_NR_sysfs
:
5609 case TARGET_NR_personality
:
5610 ret
= get_errno(personality(arg1
));
5612 #ifdef TARGET_NR_afs_syscall
5613 case TARGET_NR_afs_syscall
:
5616 #ifdef TARGET_NR__llseek /* Not on alpha */
5617 case TARGET_NR__llseek
:
5619 #if defined (__x86_64__)
5620 ret
= get_errno(lseek(arg1
, ((uint64_t )arg2
<< 32) | arg3
, arg5
));
5621 if (put_user_s64(ret
, arg4
))
5625 ret
= get_errno(_llseek(arg1
, arg2
, arg3
, &res
, arg5
));
5626 if (put_user_s64(res
, arg4
))
5632 case TARGET_NR_getdents
:
5633 #if TARGET_ABI_BITS != 32
5635 #elif TARGET_ABI_BITS == 32 && HOST_LONG_BITS == 64
5637 struct target_dirent
*target_dirp
;
5638 struct linux_dirent
*dirp
;
5639 abi_long count
= arg3
;
5641 dirp
= malloc(count
);
5643 ret
= -TARGET_ENOMEM
;
5647 ret
= get_errno(sys_getdents(arg1
, dirp
, count
));
5648 if (!is_error(ret
)) {
5649 struct linux_dirent
*de
;
5650 struct target_dirent
*tde
;
5652 int reclen
, treclen
;
5653 int count1
, tnamelen
;
5657 if (!(target_dirp
= lock_user(VERIFY_WRITE
, arg2
, count
, 0)))
5661 reclen
= de
->d_reclen
;
5662 treclen
= reclen
- (2 * (sizeof(long) - sizeof(abi_long
)));
5663 tde
->d_reclen
= tswap16(treclen
);
5664 tde
->d_ino
= tswapl(de
->d_ino
);
5665 tde
->d_off
= tswapl(de
->d_off
);
5666 tnamelen
= treclen
- (2 * sizeof(abi_long
) + 2);
5669 /* XXX: may not be correct */
5670 pstrcpy(tde
->d_name
, tnamelen
, de
->d_name
);
5671 de
= (struct linux_dirent
*)((char *)de
+ reclen
);
5673 tde
= (struct target_dirent
*)((char *)tde
+ treclen
);
5677 unlock_user(target_dirp
, arg2
, ret
);
5683 struct linux_dirent
*dirp
;
5684 abi_long count
= arg3
;
5686 if (!(dirp
= lock_user(VERIFY_WRITE
, arg2
, count
, 0)))
5688 ret
= get_errno(sys_getdents(arg1
, dirp
, count
));
5689 if (!is_error(ret
)) {
5690 struct linux_dirent
*de
;
5695 reclen
= de
->d_reclen
;
5698 de
->d_reclen
= tswap16(reclen
);
5699 tswapls(&de
->d_ino
);
5700 tswapls(&de
->d_off
);
5701 de
= (struct linux_dirent
*)((char *)de
+ reclen
);
5705 unlock_user(dirp
, arg2
, ret
);
5709 #if defined(TARGET_NR_getdents64) && defined(__NR_getdents64)
5710 case TARGET_NR_getdents64
:
5712 struct linux_dirent64
*dirp
;
5713 abi_long count
= arg3
;
5714 if (!(dirp
= lock_user(VERIFY_WRITE
, arg2
, count
, 0)))
5716 ret
= get_errno(sys_getdents64(arg1
, dirp
, count
));
5717 if (!is_error(ret
)) {
5718 struct linux_dirent64
*de
;
5723 reclen
= de
->d_reclen
;
5726 de
->d_reclen
= tswap16(reclen
);
5727 tswap64s((uint64_t *)&de
->d_ino
);
5728 tswap64s((uint64_t *)&de
->d_off
);
5729 de
= (struct linux_dirent64
*)((char *)de
+ reclen
);
5733 unlock_user(dirp
, arg2
, ret
);
5736 #endif /* TARGET_NR_getdents64 */
5737 #ifdef TARGET_NR__newselect
5738 case TARGET_NR__newselect
:
5739 ret
= do_select(arg1
, arg2
, arg3
, arg4
, arg5
);
5742 #ifdef TARGET_NR_poll
5743 case TARGET_NR_poll
:
5745 struct target_pollfd
*target_pfd
;
5746 unsigned int nfds
= arg2
;
5751 target_pfd
= lock_user(VERIFY_WRITE
, arg1
, sizeof(struct target_pollfd
) * nfds
, 1);
5754 pfd
= alloca(sizeof(struct pollfd
) * nfds
);
5755 for(i
= 0; i
< nfds
; i
++) {
5756 pfd
[i
].fd
= tswap32(target_pfd
[i
].fd
);
5757 pfd
[i
].events
= tswap16(target_pfd
[i
].events
);
5759 ret
= get_errno(poll(pfd
, nfds
, timeout
));
5760 if (!is_error(ret
)) {
5761 for(i
= 0; i
< nfds
; i
++) {
5762 target_pfd
[i
].revents
= tswap16(pfd
[i
].revents
);
5764 ret
+= nfds
* (sizeof(struct target_pollfd
)
5765 - sizeof(struct pollfd
));
5767 unlock_user(target_pfd
, arg1
, ret
);
5771 case TARGET_NR_flock
:
5772 /* NOTE: the flock constant seems to be the same for every
5774 ret
= get_errno(flock(arg1
, arg2
));
5776 case TARGET_NR_readv
:
5781 vec
= alloca(count
* sizeof(struct iovec
));
5782 if (lock_iovec(VERIFY_WRITE
, vec
, arg2
, count
, 0) < 0)
5784 ret
= get_errno(readv(arg1
, vec
, count
));
5785 unlock_iovec(vec
, arg2
, count
, 1);
5788 case TARGET_NR_writev
:
5793 vec
= alloca(count
* sizeof(struct iovec
));
5794 if (lock_iovec(VERIFY_READ
, vec
, arg2
, count
, 1) < 0)
5796 ret
= get_errno(writev(arg1
, vec
, count
));
5797 unlock_iovec(vec
, arg2
, count
, 0);
5800 case TARGET_NR_getsid
:
5801 ret
= get_errno(getsid(arg1
));
5803 #if defined(TARGET_NR_fdatasync) /* Not on alpha (osf_datasync ?) */
5804 case TARGET_NR_fdatasync
:
5805 ret
= get_errno(fdatasync(arg1
));
5808 case TARGET_NR__sysctl
:
5809 /* We don't implement this, but ENOTDIR is always a safe
5811 ret
= -TARGET_ENOTDIR
;
5813 case TARGET_NR_sched_setparam
:
5815 struct sched_param
*target_schp
;
5816 struct sched_param schp
;
5818 if (!lock_user_struct(VERIFY_READ
, target_schp
, arg2
, 1))
5820 schp
.sched_priority
= tswap32(target_schp
->sched_priority
);
5821 unlock_user_struct(target_schp
, arg2
, 0);
5822 ret
= get_errno(sched_setparam(arg1
, &schp
));
5825 case TARGET_NR_sched_getparam
:
5827 struct sched_param
*target_schp
;
5828 struct sched_param schp
;
5829 ret
= get_errno(sched_getparam(arg1
, &schp
));
5830 if (!is_error(ret
)) {
5831 if (!lock_user_struct(VERIFY_WRITE
, target_schp
, arg2
, 0))
5833 target_schp
->sched_priority
= tswap32(schp
.sched_priority
);
5834 unlock_user_struct(target_schp
, arg2
, 1);
5838 case TARGET_NR_sched_setscheduler
:
5840 struct sched_param
*target_schp
;
5841 struct sched_param schp
;
5842 if (!lock_user_struct(VERIFY_READ
, target_schp
, arg3
, 1))
5844 schp
.sched_priority
= tswap32(target_schp
->sched_priority
);
5845 unlock_user_struct(target_schp
, arg3
, 0);
5846 ret
= get_errno(sched_setscheduler(arg1
, arg2
, &schp
));
5849 case TARGET_NR_sched_getscheduler
:
5850 ret
= get_errno(sched_getscheduler(arg1
));
5852 case TARGET_NR_sched_yield
:
5853 ret
= get_errno(sched_yield());
5855 case TARGET_NR_sched_get_priority_max
:
5856 ret
= get_errno(sched_get_priority_max(arg1
));
5858 case TARGET_NR_sched_get_priority_min
:
5859 ret
= get_errno(sched_get_priority_min(arg1
));
5861 case TARGET_NR_sched_rr_get_interval
:
5864 ret
= get_errno(sched_rr_get_interval(arg1
, &ts
));
5865 if (!is_error(ret
)) {
5866 host_to_target_timespec(arg2
, &ts
);
5870 case TARGET_NR_nanosleep
:
5872 struct timespec req
, rem
;
5873 target_to_host_timespec(&req
, arg1
);
5874 ret
= get_errno(nanosleep(&req
, &rem
));
5875 if (is_error(ret
) && arg2
) {
5876 host_to_target_timespec(arg2
, &rem
);
5880 #ifdef TARGET_NR_query_module
5881 case TARGET_NR_query_module
:
5884 #ifdef TARGET_NR_nfsservctl
5885 case TARGET_NR_nfsservctl
:
5888 case TARGET_NR_prctl
:
5891 case PR_GET_PDEATHSIG
:
5894 ret
= get_errno(prctl(arg1
, &deathsig
, arg3
, arg4
, arg5
));
5895 if (!is_error(ret
) && arg2
5896 && put_user_ual(deathsig
, arg2
))
5901 ret
= get_errno(prctl(arg1
, arg2
, arg3
, arg4
, arg5
));
5905 #ifdef TARGET_NR_arch_prctl
5906 case TARGET_NR_arch_prctl
:
5907 #if defined(TARGET_I386) && !defined(TARGET_ABI32)
5908 ret
= do_arch_prctl(cpu_env
, arg1
, arg2
);
5914 #ifdef TARGET_NR_pread
5915 case TARGET_NR_pread
:
5917 if (((CPUARMState
*)cpu_env
)->eabi
)
5920 if (!(p
= lock_user(VERIFY_WRITE
, arg2
, arg3
, 0)))
5922 ret
= get_errno(pread(arg1
, p
, arg3
, arg4
));
5923 unlock_user(p
, arg2
, ret
);
5925 case TARGET_NR_pwrite
:
5927 if (((CPUARMState
*)cpu_env
)->eabi
)
5930 if (!(p
= lock_user(VERIFY_READ
, arg2
, arg3
, 1)))
5932 ret
= get_errno(pwrite(arg1
, p
, arg3
, arg4
));
5933 unlock_user(p
, arg2
, 0);
5936 #ifdef TARGET_NR_pread64
5937 case TARGET_NR_pread64
:
5938 if (!(p
= lock_user(VERIFY_WRITE
, arg2
, arg3
, 0)))
5940 ret
= get_errno(pread64(arg1
, p
, arg3
, target_offset64(arg4
, arg5
)));
5941 unlock_user(p
, arg2
, ret
);
5943 case TARGET_NR_pwrite64
:
5944 if (!(p
= lock_user(VERIFY_READ
, arg2
, arg3
, 1)))
5946 ret
= get_errno(pwrite64(arg1
, p
, arg3
, target_offset64(arg4
, arg5
)));
5947 unlock_user(p
, arg2
, 0);
5950 case TARGET_NR_getcwd
:
5951 if (!(p
= lock_user(VERIFY_WRITE
, arg1
, arg2
, 0)))
5953 ret
= get_errno(sys_getcwd1(p
, arg2
));
5954 unlock_user(p
, arg1
, ret
);
5956 case TARGET_NR_capget
:
5958 case TARGET_NR_capset
:
5960 case TARGET_NR_sigaltstack
:
5961 #if defined(TARGET_I386) || defined(TARGET_ARM) || defined(TARGET_MIPS) || \
5962 defined(TARGET_SPARC) || defined(TARGET_PPC) || defined(TARGET_ALPHA)
5963 ret
= do_sigaltstack(arg1
, arg2
, get_sp_from_cpustate((CPUState
*)cpu_env
));
5968 case TARGET_NR_sendfile
:
5970 #ifdef TARGET_NR_getpmsg
5971 case TARGET_NR_getpmsg
:
5974 #ifdef TARGET_NR_putpmsg
5975 case TARGET_NR_putpmsg
:
5978 #ifdef TARGET_NR_vfork
5979 case TARGET_NR_vfork
:
5980 ret
= get_errno(do_fork(cpu_env
, CLONE_VFORK
| CLONE_VM
| SIGCHLD
,
5984 #ifdef TARGET_NR_ugetrlimit
5985 case TARGET_NR_ugetrlimit
:
5988 ret
= get_errno(getrlimit(arg1
, &rlim
));
5989 if (!is_error(ret
)) {
5990 struct target_rlimit
*target_rlim
;
5991 if (!lock_user_struct(VERIFY_WRITE
, target_rlim
, arg2
, 0))
5993 target_rlim
->rlim_cur
= tswapl(rlim
.rlim_cur
);
5994 target_rlim
->rlim_max
= tswapl(rlim
.rlim_max
);
5995 unlock_user_struct(target_rlim
, arg2
, 1);
6000 #ifdef TARGET_NR_truncate64
6001 case TARGET_NR_truncate64
:
6002 if (!(p
= lock_user_string(arg1
)))
6004 ret
= target_truncate64(cpu_env
, p
, arg2
, arg3
, arg4
);
6005 unlock_user(p
, arg1
, 0);
6008 #ifdef TARGET_NR_ftruncate64
6009 case TARGET_NR_ftruncate64
:
6010 ret
= target_ftruncate64(cpu_env
, arg1
, arg2
, arg3
, arg4
);
6013 #ifdef TARGET_NR_stat64
6014 case TARGET_NR_stat64
:
6015 if (!(p
= lock_user_string(arg1
)))
6017 ret
= get_errno(stat(path(p
), &st
));
6018 unlock_user(p
, arg1
, 0);
6020 ret
= host_to_target_stat64(cpu_env
, arg2
, &st
);
6023 #ifdef TARGET_NR_lstat64
6024 case TARGET_NR_lstat64
:
6025 if (!(p
= lock_user_string(arg1
)))
6027 ret
= get_errno(lstat(path(p
), &st
));
6028 unlock_user(p
, arg1
, 0);
6030 ret
= host_to_target_stat64(cpu_env
, arg2
, &st
);
6033 #ifdef TARGET_NR_fstat64
6034 case TARGET_NR_fstat64
:
6035 ret
= get_errno(fstat(arg1
, &st
));
6037 ret
= host_to_target_stat64(cpu_env
, arg2
, &st
);
6040 #if (defined(TARGET_NR_fstatat64) || defined(TARGET_NR_newfstatat)) && \
6041 (defined(__NR_fstatat64) || defined(__NR_newfstatat))
6042 #ifdef TARGET_NR_fstatat64
6043 case TARGET_NR_fstatat64
:
6045 #ifdef TARGET_NR_newfstatat
6046 case TARGET_NR_newfstatat
:
6048 if (!(p
= lock_user_string(arg2
)))
6050 #ifdef __NR_fstatat64
6051 ret
= get_errno(sys_fstatat64(arg1
, path(p
), &st
, arg4
));
6053 ret
= get_errno(sys_newfstatat(arg1
, path(p
), &st
, arg4
));
6056 ret
= host_to_target_stat64(cpu_env
, arg3
, &st
);
6060 case TARGET_NR_lchown
:
6061 if (!(p
= lock_user_string(arg1
)))
6063 ret
= get_errno(lchown(p
, low2highuid(arg2
), low2highgid(arg3
)));
6064 unlock_user(p
, arg1
, 0);
6066 case TARGET_NR_getuid
:
6067 ret
= get_errno(high2lowuid(getuid()));
6069 case TARGET_NR_getgid
:
6070 ret
= get_errno(high2lowgid(getgid()));
6072 case TARGET_NR_geteuid
:
6073 ret
= get_errno(high2lowuid(geteuid()));
6075 case TARGET_NR_getegid
:
6076 ret
= get_errno(high2lowgid(getegid()));
6078 case TARGET_NR_setreuid
:
6079 ret
= get_errno(setreuid(low2highuid(arg1
), low2highuid(arg2
)));
6081 case TARGET_NR_setregid
:
6082 ret
= get_errno(setregid(low2highgid(arg1
), low2highgid(arg2
)));
6084 case TARGET_NR_getgroups
:
6086 int gidsetsize
= arg1
;
6087 uint16_t *target_grouplist
;
6091 grouplist
= alloca(gidsetsize
* sizeof(gid_t
));
6092 ret
= get_errno(getgroups(gidsetsize
, grouplist
));
6093 if (gidsetsize
== 0)
6095 if (!is_error(ret
)) {
6096 target_grouplist
= lock_user(VERIFY_WRITE
, arg2
, gidsetsize
* 2, 0);
6097 if (!target_grouplist
)
6099 for(i
= 0;i
< ret
; i
++)
6100 target_grouplist
[i
] = tswap16(grouplist
[i
]);
6101 unlock_user(target_grouplist
, arg2
, gidsetsize
* 2);
6105 case TARGET_NR_setgroups
:
6107 int gidsetsize
= arg1
;
6108 uint16_t *target_grouplist
;
6112 grouplist
= alloca(gidsetsize
* sizeof(gid_t
));
6113 target_grouplist
= lock_user(VERIFY_READ
, arg2
, gidsetsize
* 2, 1);
6114 if (!target_grouplist
) {
6115 ret
= -TARGET_EFAULT
;
6118 for(i
= 0;i
< gidsetsize
; i
++)
6119 grouplist
[i
] = tswap16(target_grouplist
[i
]);
6120 unlock_user(target_grouplist
, arg2
, 0);
6121 ret
= get_errno(setgroups(gidsetsize
, grouplist
));
6124 case TARGET_NR_fchown
:
6125 ret
= get_errno(fchown(arg1
, low2highuid(arg2
), low2highgid(arg3
)));
6127 #if defined(TARGET_NR_fchownat) && defined(__NR_fchownat)
6128 case TARGET_NR_fchownat
:
6129 if (!(p
= lock_user_string(arg2
)))
6131 ret
= get_errno(sys_fchownat(arg1
, p
, low2highuid(arg3
), low2highgid(arg4
), arg5
));
6132 unlock_user(p
, arg2
, 0);
6135 #ifdef TARGET_NR_setresuid
6136 case TARGET_NR_setresuid
:
6137 ret
= get_errno(setresuid(low2highuid(arg1
),
6139 low2highuid(arg3
)));
6142 #ifdef TARGET_NR_getresuid
6143 case TARGET_NR_getresuid
:
6145 uid_t ruid
, euid
, suid
;
6146 ret
= get_errno(getresuid(&ruid
, &euid
, &suid
));
6147 if (!is_error(ret
)) {
6148 if (put_user_u16(high2lowuid(ruid
), arg1
)
6149 || put_user_u16(high2lowuid(euid
), arg2
)
6150 || put_user_u16(high2lowuid(suid
), arg3
))
6156 #ifdef TARGET_NR_getresgid
6157 case TARGET_NR_setresgid
:
6158 ret
= get_errno(setresgid(low2highgid(arg1
),
6160 low2highgid(arg3
)));
6163 #ifdef TARGET_NR_getresgid
6164 case TARGET_NR_getresgid
:
6166 gid_t rgid
, egid
, sgid
;
6167 ret
= get_errno(getresgid(&rgid
, &egid
, &sgid
));
6168 if (!is_error(ret
)) {
6169 if (put_user_u16(high2lowgid(rgid
), arg1
)
6170 || put_user_u16(high2lowgid(egid
), arg2
)
6171 || put_user_u16(high2lowgid(sgid
), arg3
))
6177 case TARGET_NR_chown
:
6178 if (!(p
= lock_user_string(arg1
)))
6180 ret
= get_errno(chown(p
, low2highuid(arg2
), low2highgid(arg3
)));
6181 unlock_user(p
, arg1
, 0);
6183 case TARGET_NR_setuid
:
6184 ret
= get_errno(setuid(low2highuid(arg1
)));
6186 case TARGET_NR_setgid
:
6187 ret
= get_errno(setgid(low2highgid(arg1
)));
6189 case TARGET_NR_setfsuid
:
6190 ret
= get_errno(setfsuid(arg1
));
6192 case TARGET_NR_setfsgid
:
6193 ret
= get_errno(setfsgid(arg1
));
6195 #endif /* USE_UID16 */
6197 #ifdef TARGET_NR_lchown32
6198 case TARGET_NR_lchown32
:
6199 if (!(p
= lock_user_string(arg1
)))
6201 ret
= get_errno(lchown(p
, arg2
, arg3
));
6202 unlock_user(p
, arg1
, 0);
6205 #ifdef TARGET_NR_getuid32
6206 case TARGET_NR_getuid32
:
6207 ret
= get_errno(getuid());
6211 #if defined(TARGET_NR_getxuid) && defined(TARGET_ALPHA)
6212 /* Alpha specific */
6213 case TARGET_NR_getxuid
:
6217 ((CPUAlphaState
*)cpu_env
)->ir
[IR_A4
]=euid
;
6219 ret
= get_errno(getuid());
6222 #if defined(TARGET_NR_getxgid) && defined(TARGET_ALPHA)
6223 /* Alpha specific */
6224 case TARGET_NR_getxgid
:
6228 ((CPUAlphaState
*)cpu_env
)->ir
[IR_A4
]=egid
;
6230 ret
= get_errno(getgid());
6234 #ifdef TARGET_NR_getgid32
6235 case TARGET_NR_getgid32
:
6236 ret
= get_errno(getgid());
6239 #ifdef TARGET_NR_geteuid32
6240 case TARGET_NR_geteuid32
:
6241 ret
= get_errno(geteuid());
6244 #ifdef TARGET_NR_getegid32
6245 case TARGET_NR_getegid32
:
6246 ret
= get_errno(getegid());
6249 #ifdef TARGET_NR_setreuid32
6250 case TARGET_NR_setreuid32
:
6251 ret
= get_errno(setreuid(arg1
, arg2
));
6254 #ifdef TARGET_NR_setregid32
6255 case TARGET_NR_setregid32
:
6256 ret
= get_errno(setregid(arg1
, arg2
));
6259 #ifdef TARGET_NR_getgroups32
6260 case TARGET_NR_getgroups32
:
6262 int gidsetsize
= arg1
;
6263 uint32_t *target_grouplist
;
6267 grouplist
= alloca(gidsetsize
* sizeof(gid_t
));
6268 ret
= get_errno(getgroups(gidsetsize
, grouplist
));
6269 if (gidsetsize
== 0)
6271 if (!is_error(ret
)) {
6272 target_grouplist
= lock_user(VERIFY_WRITE
, arg2
, gidsetsize
* 4, 0);
6273 if (!target_grouplist
) {
6274 ret
= -TARGET_EFAULT
;
6277 for(i
= 0;i
< ret
; i
++)
6278 target_grouplist
[i
] = tswap32(grouplist
[i
]);
6279 unlock_user(target_grouplist
, arg2
, gidsetsize
* 4);
6284 #ifdef TARGET_NR_setgroups32
6285 case TARGET_NR_setgroups32
:
6287 int gidsetsize
= arg1
;
6288 uint32_t *target_grouplist
;
6292 grouplist
= alloca(gidsetsize
* sizeof(gid_t
));
6293 target_grouplist
= lock_user(VERIFY_READ
, arg2
, gidsetsize
* 4, 1);
6294 if (!target_grouplist
) {
6295 ret
= -TARGET_EFAULT
;
6298 for(i
= 0;i
< gidsetsize
; i
++)
6299 grouplist
[i
] = tswap32(target_grouplist
[i
]);
6300 unlock_user(target_grouplist
, arg2
, 0);
6301 ret
= get_errno(setgroups(gidsetsize
, grouplist
));
6305 #ifdef TARGET_NR_fchown32
6306 case TARGET_NR_fchown32
:
6307 ret
= get_errno(fchown(arg1
, arg2
, arg3
));
6310 #ifdef TARGET_NR_setresuid32
6311 case TARGET_NR_setresuid32
:
6312 ret
= get_errno(setresuid(arg1
, arg2
, arg3
));
6315 #ifdef TARGET_NR_getresuid32
6316 case TARGET_NR_getresuid32
:
6318 uid_t ruid
, euid
, suid
;
6319 ret
= get_errno(getresuid(&ruid
, &euid
, &suid
));
6320 if (!is_error(ret
)) {
6321 if (put_user_u32(ruid
, arg1
)
6322 || put_user_u32(euid
, arg2
)
6323 || put_user_u32(suid
, arg3
))
6329 #ifdef TARGET_NR_setresgid32
6330 case TARGET_NR_setresgid32
:
6331 ret
= get_errno(setresgid(arg1
, arg2
, arg3
));
6334 #ifdef TARGET_NR_getresgid32
6335 case TARGET_NR_getresgid32
:
6337 gid_t rgid
, egid
, sgid
;
6338 ret
= get_errno(getresgid(&rgid
, &egid
, &sgid
));
6339 if (!is_error(ret
)) {
6340 if (put_user_u32(rgid
, arg1
)
6341 || put_user_u32(egid
, arg2
)
6342 || put_user_u32(sgid
, arg3
))
6348 #ifdef TARGET_NR_chown32
6349 case TARGET_NR_chown32
:
6350 if (!(p
= lock_user_string(arg1
)))
6352 ret
= get_errno(chown(p
, arg2
, arg3
));
6353 unlock_user(p
, arg1
, 0);
6356 #ifdef TARGET_NR_setuid32
6357 case TARGET_NR_setuid32
:
6358 ret
= get_errno(setuid(arg1
));
6361 #ifdef TARGET_NR_setgid32
6362 case TARGET_NR_setgid32
:
6363 ret
= get_errno(setgid(arg1
));
6366 #ifdef TARGET_NR_setfsuid32
6367 case TARGET_NR_setfsuid32
:
6368 ret
= get_errno(setfsuid(arg1
));
6371 #ifdef TARGET_NR_setfsgid32
6372 case TARGET_NR_setfsgid32
:
6373 ret
= get_errno(setfsgid(arg1
));
6377 case TARGET_NR_pivot_root
:
6379 #ifdef TARGET_NR_mincore
6380 case TARGET_NR_mincore
:
6383 ret
= -TARGET_EFAULT
;
6384 if (!(a
= lock_user(VERIFY_READ
, arg1
,arg2
, 0)))
6386 if (!(p
= lock_user_string(arg3
)))
6388 ret
= get_errno(mincore(a
, arg2
, p
));
6389 unlock_user(p
, arg3
, ret
);
6391 unlock_user(a
, arg1
, 0);
6395 #ifdef TARGET_NR_arm_fadvise64_64
6396 case TARGET_NR_arm_fadvise64_64
:
6399 * arm_fadvise64_64 looks like fadvise64_64 but
6400 * with different argument order
6408 #if defined(TARGET_NR_fadvise64_64) || defined(TARGET_NR_arm_fadvise64_64)
6409 #ifdef TARGET_NR_fadvise64_64
6410 case TARGET_NR_fadvise64_64
:
6412 /* This is a hint, so ignoring and returning success is ok. */
6416 #ifdef TARGET_NR_madvise
6417 case TARGET_NR_madvise
:
6418 /* A straight passthrough may not be safe because qemu sometimes
6419 turns private flie-backed mappings into anonymous mappings.
6420 This will break MADV_DONTNEED.
6421 This is a hint, so ignoring and returning success is ok. */
6425 #if TARGET_ABI_BITS == 32
6426 case TARGET_NR_fcntl64
:
6430 struct target_flock64
*target_fl
;
6432 struct target_eabi_flock64
*target_efl
;
6436 case TARGET_F_GETLK64
:
6439 case TARGET_F_SETLK64
:
6442 case TARGET_F_SETLKW64
:
6451 case TARGET_F_GETLK64
:
6453 if (((CPUARMState
*)cpu_env
)->eabi
) {
6454 if (!lock_user_struct(VERIFY_READ
, target_efl
, arg3
, 1))
6456 fl
.l_type
= tswap16(target_efl
->l_type
);
6457 fl
.l_whence
= tswap16(target_efl
->l_whence
);
6458 fl
.l_start
= tswap64(target_efl
->l_start
);
6459 fl
.l_len
= tswap64(target_efl
->l_len
);
6460 fl
.l_pid
= tswapl(target_efl
->l_pid
);
6461 unlock_user_struct(target_efl
, arg3
, 0);
6465 if (!lock_user_struct(VERIFY_READ
, target_fl
, arg3
, 1))
6467 fl
.l_type
= tswap16(target_fl
->l_type
);
6468 fl
.l_whence
= tswap16(target_fl
->l_whence
);
6469 fl
.l_start
= tswap64(target_fl
->l_start
);
6470 fl
.l_len
= tswap64(target_fl
->l_len
);
6471 fl
.l_pid
= tswapl(target_fl
->l_pid
);
6472 unlock_user_struct(target_fl
, arg3
, 0);
6474 ret
= get_errno(fcntl(arg1
, cmd
, &fl
));
6477 if (((CPUARMState
*)cpu_env
)->eabi
) {
6478 if (!lock_user_struct(VERIFY_WRITE
, target_efl
, arg3
, 0))
6480 target_efl
->l_type
= tswap16(fl
.l_type
);
6481 target_efl
->l_whence
= tswap16(fl
.l_whence
);
6482 target_efl
->l_start
= tswap64(fl
.l_start
);
6483 target_efl
->l_len
= tswap64(fl
.l_len
);
6484 target_efl
->l_pid
= tswapl(fl
.l_pid
);
6485 unlock_user_struct(target_efl
, arg3
, 1);
6489 if (!lock_user_struct(VERIFY_WRITE
, target_fl
, arg3
, 0))
6491 target_fl
->l_type
= tswap16(fl
.l_type
);
6492 target_fl
->l_whence
= tswap16(fl
.l_whence
);
6493 target_fl
->l_start
= tswap64(fl
.l_start
);
6494 target_fl
->l_len
= tswap64(fl
.l_len
);
6495 target_fl
->l_pid
= tswapl(fl
.l_pid
);
6496 unlock_user_struct(target_fl
, arg3
, 1);
6501 case TARGET_F_SETLK64
:
6502 case TARGET_F_SETLKW64
:
6504 if (((CPUARMState
*)cpu_env
)->eabi
) {
6505 if (!lock_user_struct(VERIFY_READ
, target_efl
, arg3
, 1))
6507 fl
.l_type
= tswap16(target_efl
->l_type
);
6508 fl
.l_whence
= tswap16(target_efl
->l_whence
);
6509 fl
.l_start
= tswap64(target_efl
->l_start
);
6510 fl
.l_len
= tswap64(target_efl
->l_len
);
6511 fl
.l_pid
= tswapl(target_efl
->l_pid
);
6512 unlock_user_struct(target_efl
, arg3
, 0);
6516 if (!lock_user_struct(VERIFY_READ
, target_fl
, arg3
, 1))
6518 fl
.l_type
= tswap16(target_fl
->l_type
);
6519 fl
.l_whence
= tswap16(target_fl
->l_whence
);
6520 fl
.l_start
= tswap64(target_fl
->l_start
);
6521 fl
.l_len
= tswap64(target_fl
->l_len
);
6522 fl
.l_pid
= tswapl(target_fl
->l_pid
);
6523 unlock_user_struct(target_fl
, arg3
, 0);
6525 ret
= get_errno(fcntl(arg1
, cmd
, &fl
));
6528 ret
= do_fcntl(arg1
, cmd
, arg3
);
6534 #ifdef TARGET_NR_cacheflush
6535 case TARGET_NR_cacheflush
:
6536 /* self-modifying code is handled automatically, so nothing needed */
6540 #ifdef TARGET_NR_security
6541 case TARGET_NR_security
:
6544 #ifdef TARGET_NR_getpagesize
6545 case TARGET_NR_getpagesize
:
6546 ret
= TARGET_PAGE_SIZE
;
6549 case TARGET_NR_gettid
:
6550 ret
= get_errno(gettid());
6552 #ifdef TARGET_NR_readahead
6553 case TARGET_NR_readahead
:
6554 #if TARGET_ABI_BITS == 32
6556 if (((CPUARMState
*)cpu_env
)->eabi
)
6563 ret
= get_errno(readahead(arg1
, ((off64_t
)arg3
<< 32) | arg2
, arg4
));
6565 ret
= get_errno(readahead(arg1
, arg2
, arg3
));
6569 #ifdef TARGET_NR_setxattr
6570 case TARGET_NR_setxattr
:
6571 case TARGET_NR_lsetxattr
:
6572 case TARGET_NR_fsetxattr
:
6573 case TARGET_NR_getxattr
:
6574 case TARGET_NR_lgetxattr
:
6575 case TARGET_NR_fgetxattr
:
6576 case TARGET_NR_listxattr
:
6577 case TARGET_NR_llistxattr
:
6578 case TARGET_NR_flistxattr
:
6579 case TARGET_NR_removexattr
:
6580 case TARGET_NR_lremovexattr
:
6581 case TARGET_NR_fremovexattr
:
6582 goto unimplemented_nowarn
;
6584 #ifdef TARGET_NR_set_thread_area
6585 case TARGET_NR_set_thread_area
:
6586 #if defined(TARGET_MIPS)
6587 ((CPUMIPSState
*) cpu_env
)->tls_value
= arg1
;
6590 #elif defined(TARGET_CRIS)
6592 ret
= -TARGET_EINVAL
;
6594 ((CPUCRISState
*) cpu_env
)->pregs
[PR_PID
] = arg1
;
6598 #elif defined(TARGET_I386) && defined(TARGET_ABI32)
6599 ret
= do_set_thread_area(cpu_env
, arg1
);
6602 goto unimplemented_nowarn
;
6605 #ifdef TARGET_NR_get_thread_area
6606 case TARGET_NR_get_thread_area
:
6607 #if defined(TARGET_I386) && defined(TARGET_ABI32)
6608 ret
= do_get_thread_area(cpu_env
, arg1
);
6610 goto unimplemented_nowarn
;
6613 #ifdef TARGET_NR_getdomainname
6614 case TARGET_NR_getdomainname
:
6615 goto unimplemented_nowarn
;
6618 #ifdef TARGET_NR_clock_gettime
6619 case TARGET_NR_clock_gettime
:
6622 ret
= get_errno(clock_gettime(arg1
, &ts
));
6623 if (!is_error(ret
)) {
6624 host_to_target_timespec(arg2
, &ts
);
6629 #ifdef TARGET_NR_clock_getres
6630 case TARGET_NR_clock_getres
:
6633 ret
= get_errno(clock_getres(arg1
, &ts
));
6634 if (!is_error(ret
)) {
6635 host_to_target_timespec(arg2
, &ts
);
6640 #ifdef TARGET_NR_clock_nanosleep
6641 case TARGET_NR_clock_nanosleep
:
6644 target_to_host_timespec(&ts
, arg3
);
6645 ret
= get_errno(clock_nanosleep(arg1
, arg2
, &ts
, arg4
? &ts
: NULL
));
6647 host_to_target_timespec(arg4
, &ts
);
6652 #if defined(TARGET_NR_set_tid_address) && defined(__NR_set_tid_address)
6653 case TARGET_NR_set_tid_address
:
6654 ret
= get_errno(set_tid_address((int *)g2h(arg1
)));
6658 #if defined(TARGET_NR_tkill) && defined(__NR_tkill)
6659 case TARGET_NR_tkill
:
6660 ret
= get_errno(sys_tkill((int)arg1
, target_to_host_signal(arg2
)));
6664 #if defined(TARGET_NR_tgkill) && defined(__NR_tgkill)
6665 case TARGET_NR_tgkill
:
6666 ret
= get_errno(sys_tgkill((int)arg1
, (int)arg2
,
6667 target_to_host_signal(arg3
)));
6671 #ifdef TARGET_NR_set_robust_list
6672 case TARGET_NR_set_robust_list
:
6673 goto unimplemented_nowarn
;
6676 #if defined(TARGET_NR_utimensat) && defined(__NR_utimensat)
6677 case TARGET_NR_utimensat
:
6679 struct timespec
*tsp
, ts
[2];
6683 target_to_host_timespec(ts
, arg3
);
6684 target_to_host_timespec(ts
+1, arg3
+sizeof(struct target_timespec
));
6688 ret
= get_errno(sys_utimensat(arg1
, NULL
, tsp
, arg4
));
6690 if (!(p
= lock_user_string(arg2
))) {
6691 ret
= -TARGET_EFAULT
;
6694 ret
= get_errno(sys_utimensat(arg1
, path(p
), tsp
, arg4
));
6695 unlock_user(p
, arg2
, 0);
6700 #if defined(USE_NPTL)
6701 case TARGET_NR_futex
:
6702 ret
= do_futex(arg1
, arg2
, arg3
, arg4
, arg5
, arg6
);
6705 #if defined(TARGET_NR_inotify_init) && defined(__NR_inotify_init)
6706 case TARGET_NR_inotify_init
:
6707 ret
= get_errno(sys_inotify_init());
6710 #if defined(TARGET_NR_inotify_add_watch) && defined(__NR_inotify_add_watch)
6711 case TARGET_NR_inotify_add_watch
:
6712 p
= lock_user_string(arg2
);
6713 ret
= get_errno(sys_inotify_add_watch(arg1
, path(p
), arg3
));
6714 unlock_user(p
, arg2
, 0);
6717 #if defined(TARGET_NR_inotify_rm_watch) && defined(__NR_inotify_rm_watch)
6718 case TARGET_NR_inotify_rm_watch
:
6719 ret
= get_errno(sys_inotify_rm_watch(arg1
, arg2
));
6723 #ifdef TARGET_NR_mq_open
6724 case TARGET_NR_mq_open
:
6726 struct mq_attr posix_mq_attr
;
6728 p
= lock_user_string(arg1
- 1);
6730 copy_from_user_mq_attr (&posix_mq_attr
, arg4
);
6731 ret
= get_errno(mq_open(p
, arg2
, arg3
, &posix_mq_attr
));
6732 unlock_user (p
, arg1
, 0);
6736 case TARGET_NR_mq_unlink
:
6737 p
= lock_user_string(arg1
- 1);
6738 ret
= get_errno(mq_unlink(p
));
6739 unlock_user (p
, arg1
, 0);
6742 case TARGET_NR_mq_timedsend
:
6746 p
= lock_user (VERIFY_READ
, arg2
, arg3
, 1);
6748 target_to_host_timespec(&ts
, arg5
);
6749 ret
= get_errno(mq_timedsend(arg1
, p
, arg3
, arg4
, &ts
));
6750 host_to_target_timespec(arg5
, &ts
);
6753 ret
= get_errno(mq_send(arg1
, p
, arg3
, arg4
));
6754 unlock_user (p
, arg2
, arg3
);
6758 case TARGET_NR_mq_timedreceive
:
6763 p
= lock_user (VERIFY_READ
, arg2
, arg3
, 1);
6765 target_to_host_timespec(&ts
, arg5
);
6766 ret
= get_errno(mq_timedreceive(arg1
, p
, arg3
, &prio
, &ts
));
6767 host_to_target_timespec(arg5
, &ts
);
6770 ret
= get_errno(mq_receive(arg1
, p
, arg3
, &prio
));
6771 unlock_user (p
, arg2
, arg3
);
6773 put_user_u32(prio
, arg4
);
6777 /* Not implemented for now... */
6778 /* case TARGET_NR_mq_notify: */
6781 case TARGET_NR_mq_getsetattr
:
6783 struct mq_attr posix_mq_attr_in
, posix_mq_attr_out
;
6786 ret
= mq_getattr(arg1
, &posix_mq_attr_out
);
6787 copy_to_user_mq_attr(arg3
, &posix_mq_attr_out
);
6790 copy_from_user_mq_attr(&posix_mq_attr_in
, arg2
);
6791 ret
|= mq_setattr(arg1
, &posix_mq_attr_in
, &posix_mq_attr_out
);
6800 gemu_log("qemu: Unsupported syscall: %d\n", num
);
6801 #if defined(TARGET_NR_setxattr) || defined(TARGET_NR_get_thread_area) || defined(TARGET_NR_getdomainname) || defined(TARGET_NR_set_robust_list)
6802 unimplemented_nowarn
:
6804 ret
= -TARGET_ENOSYS
;
6809 gemu_log(" = %ld\n", ret
);
6812 print_syscall_ret(num
, ret
);
6815 ret
= -TARGET_EFAULT
;