Annotation of qemu/linux-user/syscall.c, revision 1.1.1.14

1.1       root        1: /*
                      2:  *  Linux syscalls
1.1.1.6   root        3:  *
1.1       root        4:  *  Copyright (c) 2003 Fabrice Bellard
                      5:  *
                      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.
                     10:  *
                     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.
                     15:  *
                     16:  *  You should have received a copy of the GNU General Public License
1.1.1.8   root       17:  *  along with this program; if not, see <http://www.gnu.org/licenses/>.
1.1       root       18:  */
1.1.1.8   root       19: #define _ATFILE_SOURCE
1.1       root       20: #include <stdlib.h>
                     21: #include <stdio.h>
                     22: #include <stdarg.h>
                     23: #include <string.h>
                     24: #include <elf.h>
                     25: #include <endian.h>
                     26: #include <errno.h>
                     27: #include <unistd.h>
                     28: #include <fcntl.h>
                     29: #include <time.h>
1.1.1.7   root       30: #include <limits.h>
1.1       root       31: #include <sys/types.h>
1.1.1.6   root       32: #include <sys/ipc.h>
                     33: #include <sys/msg.h>
1.1       root       34: #include <sys/wait.h>
                     35: #include <sys/time.h>
                     36: #include <sys/stat.h>
                     37: #include <sys/mount.h>
1.1.1.6   root       38: #include <sys/prctl.h>
1.1       root       39: #include <sys/resource.h>
                     40: #include <sys/mman.h>
                     41: #include <sys/swap.h>
                     42: #include <signal.h>
                     43: #include <sched.h>
1.1.1.10  root       44: #ifdef __ia64__
                     45: int __clone2(int (*fn)(void *), void *child_stack_base,
                     46:              size_t stack_size, int flags, void *arg, ...);
                     47: #endif
1.1       root       48: #include <sys/socket.h>
1.1.1.8   root       49: #include <sys/un.h>
1.1       root       50: #include <sys/uio.h>
                     51: #include <sys/poll.h>
                     52: #include <sys/times.h>
                     53: #include <sys/shm.h>
1.1.1.5   root       54: #include <sys/sem.h>
1.1.1.2   root       55: #include <sys/statfs.h>
1.1       root       56: #include <utime.h>
                     57: #include <sys/sysinfo.h>
1.1.1.8   root       58: #include <sys/utsname.h>
1.1       root       59: //#include <sys/user.h>
                     60: #include <netinet/ip.h>
                     61: #include <netinet/tcp.h>
1.1.1.12  root       62: #include <linux/wireless.h>
1.1.1.13  root       63: #include "qemu-common.h"
1.1.1.9   root       64: #ifdef TARGET_GPROF
1.1.1.7   root       65: #include <sys/gmon.h>
                     66: #endif
1.1.1.9   root       67: #ifdef CONFIG_EVENTFD
                     68: #include <sys/eventfd.h>
                     69: #endif
1.1.1.12  root       70: #ifdef CONFIG_EPOLL
                     71: #include <sys/epoll.h>
                     72: #endif
1.1.1.13  root       73: #ifdef CONFIG_ATTR
                     74: #include "qemu-xattr.h"
                     75: #endif
1.1       root       76: 
                     77: #define termios host_termios
                     78: #define winsize host_winsize
                     79: #define termio host_termio
                     80: #define sgttyb host_sgttyb /* same as target */
                     81: #define tchars host_tchars /* same as target */
                     82: #define ltchars host_ltchars /* same as target */
                     83: 
                     84: #include <linux/termios.h>
                     85: #include <linux/unistd.h>
                     86: #include <linux/utsname.h>
                     87: #include <linux/cdrom.h>
                     88: #include <linux/hdreg.h>
                     89: #include <linux/soundcard.h>
                     90: #include <linux/kd.h>
1.1.1.7   root       91: #include <linux/mtio.h>
1.1.1.8   root       92: #include <linux/fs.h>
1.1.1.11  root       93: #if defined(CONFIG_FIEMAP)
                     94: #include <linux/fiemap.h>
                     95: #endif
1.1.1.9   root       96: #include <linux/fb.h>
                     97: #include <linux/vt.h>
1.1.1.14! root       98: #include <linux/dm-ioctl.h>
1.1.1.7   root       99: #include "linux_loop.h"
1.1.1.10  root      100: #include "cpu-uname.h"
1.1       root      101: 
                    102: #include "qemu.h"
1.1.1.7   root      103: 
1.1.1.9   root      104: #if defined(CONFIG_USE_NPTL)
1.1.1.7   root      105: #define CLONE_NPTL_FLAGS2 (CLONE_SETTLS | \
                    106:     CLONE_PARENT_SETTID | CLONE_CHILD_SETTID | CLONE_CHILD_CLEARTID)
                    107: #else
                    108: /* XXX: Hardcode the above values.  */
                    109: #define CLONE_NPTL_FLAGS2 0
                    110: #endif
1.1       root      111: 
                    112: //#define DEBUG
                    113: 
                    114: //#include <linux/msdos_fs.h>
1.1.1.7   root      115: #define        VFAT_IOCTL_READDIR_BOTH         _IOR('r', 1, struct linux_dirent [2])
                    116: #define        VFAT_IOCTL_READDIR_SHORT        _IOR('r', 2, struct linux_dirent [2])
1.1       root      117: 
                    118: 
                    119: #undef _syscall0
                    120: #undef _syscall1
                    121: #undef _syscall2
                    122: #undef _syscall3
                    123: #undef _syscall4
                    124: #undef _syscall5
1.1.1.4   root      125: #undef _syscall6
1.1       root      126: 
1.1.1.4   root      127: #define _syscall0(type,name)           \
1.1.1.7   root      128: static type name (void)                        \
1.1.1.4   root      129: {                                      \
                    130:        return syscall(__NR_##name);    \
                    131: }
                    132: 
                    133: #define _syscall1(type,name,type1,arg1)                \
1.1.1.7   root      134: static type name (type1 arg1)                  \
1.1.1.4   root      135: {                                              \
                    136:        return syscall(__NR_##name, arg1);      \
                    137: }
                    138: 
                    139: #define _syscall2(type,name,type1,arg1,type2,arg2)     \
1.1.1.7   root      140: static type name (type1 arg1,type2 arg2)               \
1.1.1.4   root      141: {                                                      \
                    142:        return syscall(__NR_##name, arg1, arg2);        \
                    143: }
                    144: 
                    145: #define _syscall3(type,name,type1,arg1,type2,arg2,type3,arg3)  \
1.1.1.7   root      146: static type name (type1 arg1,type2 arg2,type3 arg3)            \
1.1.1.4   root      147: {                                                              \
                    148:        return syscall(__NR_##name, arg1, arg2, arg3);          \
                    149: }
                    150: 
                    151: #define _syscall4(type,name,type1,arg1,type2,arg2,type3,arg3,type4,arg4)       \
1.1.1.7   root      152: static type name (type1 arg1,type2 arg2,type3 arg3,type4 arg4)                 \
1.1.1.4   root      153: {                                                                              \
                    154:        return syscall(__NR_##name, arg1, arg2, arg3, arg4);                    \
1.1       root      155: }
1.1.1.4   root      156: 
                    157: #define _syscall5(type,name,type1,arg1,type2,arg2,type3,arg3,type4,arg4,       \
                    158:                  type5,arg5)                                                   \
1.1.1.7   root      159: static type name (type1 arg1,type2 arg2,type3 arg3,type4 arg4,type5 arg5)      \
1.1.1.4   root      160: {                                                                              \
                    161:        return syscall(__NR_##name, arg1, arg2, arg3, arg4, arg5);              \
                    162: }
                    163: 
                    164: 
                    165: #define _syscall6(type,name,type1,arg1,type2,arg2,type3,arg3,type4,arg4,       \
                    166:                  type5,arg5,type6,arg6)                                        \
1.1.1.7   root      167: static type name (type1 arg1,type2 arg2,type3 arg3,type4 arg4,type5 arg5,      \
                    168:                   type6 arg6)                                                  \
1.1.1.4   root      169: {                                                                              \
                    170:        return syscall(__NR_##name, arg1, arg2, arg3, arg4, arg5, arg6);        \
                    171: }
                    172: 
1.1       root      173: 
                    174: #define __NR_sys_uname __NR_uname
1.1.1.6   root      175: #define __NR_sys_faccessat __NR_faccessat
                    176: #define __NR_sys_fchmodat __NR_fchmodat
                    177: #define __NR_sys_fchownat __NR_fchownat
1.1.1.7   root      178: #define __NR_sys_fstatat64 __NR_fstatat64
                    179: #define __NR_sys_futimesat __NR_futimesat
1.1       root      180: #define __NR_sys_getcwd1 __NR_getcwd
                    181: #define __NR_sys_getdents __NR_getdents
                    182: #define __NR_sys_getdents64 __NR_getdents64
1.1.1.6   root      183: #define __NR_sys_getpriority __NR_getpriority
                    184: #define __NR_sys_linkat __NR_linkat
                    185: #define __NR_sys_mkdirat __NR_mkdirat
                    186: #define __NR_sys_mknodat __NR_mknodat
1.1.1.8   root      187: #define __NR_sys_newfstatat __NR_newfstatat
1.1.1.6   root      188: #define __NR_sys_openat __NR_openat
                    189: #define __NR_sys_readlinkat __NR_readlinkat
                    190: #define __NR_sys_renameat __NR_renameat
1.1       root      191: #define __NR_sys_rt_sigqueueinfo __NR_rt_sigqueueinfo
1.1.1.6   root      192: #define __NR_sys_symlinkat __NR_symlinkat
                    193: #define __NR_sys_syslog __NR_syslog
                    194: #define __NR_sys_tgkill __NR_tgkill
                    195: #define __NR_sys_tkill __NR_tkill
                    196: #define __NR_sys_unlinkat __NR_unlinkat
                    197: #define __NR_sys_utimensat __NR_utimensat
1.1.1.7   root      198: #define __NR_sys_futex __NR_futex
                    199: #define __NR_sys_inotify_init __NR_inotify_init
                    200: #define __NR_sys_inotify_add_watch __NR_inotify_add_watch
                    201: #define __NR_sys_inotify_rm_watch __NR_inotify_rm_watch
1.1       root      202: 
1.1.1.12  root      203: #if defined(__alpha__) || defined (__ia64__) || defined(__x86_64__) || \
                    204:     defined(__s390x__)
1.1       root      205: #define __NR__llseek __NR_lseek
                    206: #endif
                    207: 
                    208: #ifdef __NR_gettid
                    209: _syscall0(int, gettid)
                    210: #else
1.1.1.6   root      211: /* This is a replacement for the host gettid() and must return a host
                    212:    errno. */
1.1       root      213: static int gettid(void) {
                    214:     return -ENOSYS;
                    215: }
                    216: #endif
1.1.1.8   root      217: _syscall3(int, sys_getdents, uint, fd, struct linux_dirent *, dirp, uint, count);
                    218: #if defined(TARGET_NR_getdents64) && defined(__NR_getdents64)
                    219: _syscall3(int, sys_getdents64, uint, fd, struct linux_dirent64 *, dirp, uint, count);
                    220: #endif
                    221: _syscall2(int, sys_getpriority, int, which, int, who);
1.1.1.10  root      222: #if defined(TARGET_NR__llseek) && defined(__NR_llseek)
1.1.1.8   root      223: _syscall5(int, _llseek,  uint,  fd, ulong, hi, ulong, lo,
                    224:           loff_t *, res, uint, wh);
                    225: #endif
                    226: _syscall3(int,sys_rt_sigqueueinfo,int,pid,int,sig,siginfo_t *,uinfo)
                    227: _syscall3(int,sys_syslog,int,type,char*,bufp,int,len)
                    228: #if defined(TARGET_NR_tgkill) && defined(__NR_tgkill)
                    229: _syscall3(int,sys_tgkill,int,tgid,int,pid,int,sig)
                    230: #endif
                    231: #if defined(TARGET_NR_tkill) && defined(__NR_tkill)
                    232: _syscall2(int,sys_tkill,int,tid,int,sig)
                    233: #endif
                    234: #ifdef __NR_exit_group
                    235: _syscall1(int,exit_group,int,error_code)
                    236: #endif
                    237: #if defined(TARGET_NR_set_tid_address) && defined(__NR_set_tid_address)
                    238: _syscall1(int,set_tid_address,int *,tidptr)
                    239: #endif
1.1.1.9   root      240: #if defined(CONFIG_USE_NPTL)
1.1.1.8   root      241: #if defined(TARGET_NR_futex) && defined(__NR_futex)
                    242: _syscall6(int,sys_futex,int *,uaddr,int,op,int,val,
                    243:           const struct timespec *,timeout,int *,uaddr2,int,val3)
                    244: #endif
                    245: #endif
1.1.1.12  root      246: #define __NR_sys_sched_getaffinity __NR_sched_getaffinity
                    247: _syscall3(int, sys_sched_getaffinity, pid_t, pid, unsigned int, len,
                    248:           unsigned long *, user_mask_ptr);
                    249: #define __NR_sys_sched_setaffinity __NR_sched_setaffinity
                    250: _syscall3(int, sys_sched_setaffinity, pid_t, pid, unsigned int, len,
                    251:           unsigned long *, user_mask_ptr);
1.1.1.13  root      252: _syscall4(int, reboot, int, magic1, int, magic2, unsigned int, cmd,
                    253:           void *, arg);
1.1.1.8   root      254: 
                    255: static bitmask_transtbl fcntl_flags_tbl[] = {
                    256:   { TARGET_O_ACCMODE,   TARGET_O_WRONLY,    O_ACCMODE,   O_WRONLY,    },
                    257:   { TARGET_O_ACCMODE,   TARGET_O_RDWR,      O_ACCMODE,   O_RDWR,      },
                    258:   { TARGET_O_CREAT,     TARGET_O_CREAT,     O_CREAT,     O_CREAT,     },
                    259:   { TARGET_O_EXCL,      TARGET_O_EXCL,      O_EXCL,      O_EXCL,      },
                    260:   { TARGET_O_NOCTTY,    TARGET_O_NOCTTY,    O_NOCTTY,    O_NOCTTY,    },
                    261:   { TARGET_O_TRUNC,     TARGET_O_TRUNC,     O_TRUNC,     O_TRUNC,     },
                    262:   { TARGET_O_APPEND,    TARGET_O_APPEND,    O_APPEND,    O_APPEND,    },
                    263:   { TARGET_O_NONBLOCK,  TARGET_O_NONBLOCK,  O_NONBLOCK,  O_NONBLOCK,  },
                    264:   { TARGET_O_SYNC,      TARGET_O_SYNC,      O_SYNC,      O_SYNC,      },
                    265:   { TARGET_FASYNC,      TARGET_FASYNC,      FASYNC,      FASYNC,      },
                    266:   { TARGET_O_DIRECTORY, TARGET_O_DIRECTORY, O_DIRECTORY, O_DIRECTORY, },
                    267:   { TARGET_O_NOFOLLOW,  TARGET_O_NOFOLLOW,  O_NOFOLLOW,  O_NOFOLLOW,  },
                    268:   { TARGET_O_LARGEFILE, TARGET_O_LARGEFILE, O_LARGEFILE, O_LARGEFILE, },
                    269: #if defined(O_DIRECT)
                    270:   { TARGET_O_DIRECT,    TARGET_O_DIRECT,    O_DIRECT,    O_DIRECT,    },
                    271: #endif
                    272:   { 0, 0, 0, 0 }
                    273: };
                    274: 
                    275: #define COPY_UTSNAME_FIELD(dest, src) \
                    276:   do { \
                    277:       /* __NEW_UTS_LEN doesn't include terminating null */ \
                    278:       (void) strncpy((dest), (src), __NEW_UTS_LEN); \
                    279:       (dest)[__NEW_UTS_LEN] = '\0'; \
                    280:   } while (0)
                    281: 
                    282: static int sys_uname(struct new_utsname *buf)
                    283: {
                    284:   struct utsname uts_buf;
                    285: 
                    286:   if (uname(&uts_buf) < 0)
                    287:       return (-1);
                    288: 
                    289:   /*
                    290:    * Just in case these have some differences, we
                    291:    * translate utsname to new_utsname (which is the
                    292:    * struct linux kernel uses).
                    293:    */
                    294: 
1.1.1.12  root      295:   memset(buf, 0, sizeof(*buf));
1.1.1.8   root      296:   COPY_UTSNAME_FIELD(buf->sysname, uts_buf.sysname);
                    297:   COPY_UTSNAME_FIELD(buf->nodename, uts_buf.nodename);
                    298:   COPY_UTSNAME_FIELD(buf->release, uts_buf.release);
                    299:   COPY_UTSNAME_FIELD(buf->version, uts_buf.version);
                    300:   COPY_UTSNAME_FIELD(buf->machine, uts_buf.machine);
                    301: #ifdef _GNU_SOURCE
                    302:   COPY_UTSNAME_FIELD(buf->domainname, uts_buf.domainname);
                    303: #endif
                    304:   return (0);
                    305: 
                    306: #undef COPY_UTSNAME_FIELD
                    307: }
                    308: 
                    309: static int sys_getcwd1(char *buf, size_t size)
                    310: {
                    311:   if (getcwd(buf, size) == NULL) {
                    312:       /* getcwd() sets errno */
                    313:       return (-1);
                    314:   }
                    315:   return strlen(buf)+1;
                    316: }
                    317: 
                    318: #ifdef CONFIG_ATFILE
                    319: /*
                    320:  * Host system seems to have atfile syscall stubs available.  We
                    321:  * now enable them one by one as specified by target syscall_nr.h.
                    322:  */
                    323: 
                    324: #ifdef TARGET_NR_faccessat
                    325: static int sys_faccessat(int dirfd, const char *pathname, int mode)
                    326: {
                    327:   return (faccessat(dirfd, pathname, mode, 0));
                    328: }
                    329: #endif
                    330: #ifdef TARGET_NR_fchmodat
                    331: static int sys_fchmodat(int dirfd, const char *pathname, mode_t mode)
                    332: {
                    333:   return (fchmodat(dirfd, pathname, mode, 0));
                    334: }
                    335: #endif
1.1.1.12  root      336: #if defined(TARGET_NR_fchownat)
1.1.1.8   root      337: static int sys_fchownat(int dirfd, const char *pathname, uid_t owner,
                    338:     gid_t group, int flags)
                    339: {
                    340:   return (fchownat(dirfd, pathname, owner, group, flags));
                    341: }
                    342: #endif
                    343: #ifdef __NR_fstatat64
                    344: static int sys_fstatat64(int dirfd, const char *pathname, struct stat *buf,
                    345:     int flags)
                    346: {
                    347:   return (fstatat(dirfd, pathname, buf, flags));
                    348: }
                    349: #endif
                    350: #ifdef __NR_newfstatat
                    351: static int sys_newfstatat(int dirfd, const char *pathname, struct stat *buf,
                    352:     int flags)
                    353: {
                    354:   return (fstatat(dirfd, pathname, buf, flags));
                    355: }
                    356: #endif
                    357: #ifdef TARGET_NR_futimesat
                    358: static int sys_futimesat(int dirfd, const char *pathname,
                    359:     const struct timeval times[2])
                    360: {
                    361:   return (futimesat(dirfd, pathname, times));
                    362: }
                    363: #endif
                    364: #ifdef TARGET_NR_linkat
                    365: static int sys_linkat(int olddirfd, const char *oldpath,
                    366:     int newdirfd, const char *newpath, int flags)
                    367: {
                    368:   return (linkat(olddirfd, oldpath, newdirfd, newpath, flags));
                    369: }
                    370: #endif
                    371: #ifdef TARGET_NR_mkdirat
                    372: static int sys_mkdirat(int dirfd, const char *pathname, mode_t mode)
                    373: {
                    374:   return (mkdirat(dirfd, pathname, mode));
                    375: }
                    376: #endif
                    377: #ifdef TARGET_NR_mknodat
                    378: static int sys_mknodat(int dirfd, const char *pathname, mode_t mode,
                    379:     dev_t dev)
                    380: {
                    381:   return (mknodat(dirfd, pathname, mode, dev));
                    382: }
                    383: #endif
                    384: #ifdef TARGET_NR_openat
1.1.1.13  root      385: static int sys_openat(int dirfd, const char *pathname, int flags, mode_t mode)
1.1.1.8   root      386: {
                    387:   /*
                    388:    * open(2) has extra parameter 'mode' when called with
                    389:    * flag O_CREAT.
                    390:    */
                    391:   if ((flags & O_CREAT) != 0) {
                    392:       return (openat(dirfd, pathname, flags, mode));
                    393:   }
                    394:   return (openat(dirfd, pathname, flags));
                    395: }
                    396: #endif
                    397: #ifdef TARGET_NR_readlinkat
                    398: static int sys_readlinkat(int dirfd, const char *pathname, char *buf, size_t bufsiz)
                    399: {
                    400:   return (readlinkat(dirfd, pathname, buf, bufsiz));
                    401: }
                    402: #endif
                    403: #ifdef TARGET_NR_renameat
                    404: static int sys_renameat(int olddirfd, const char *oldpath,
                    405:     int newdirfd, const char *newpath)
                    406: {
                    407:   return (renameat(olddirfd, oldpath, newdirfd, newpath));
                    408: }
                    409: #endif
                    410: #ifdef TARGET_NR_symlinkat
                    411: static int sys_symlinkat(const char *oldpath, int newdirfd, const char *newpath)
                    412: {
                    413:   return (symlinkat(oldpath, newdirfd, newpath));
                    414: }
                    415: #endif
                    416: #ifdef TARGET_NR_unlinkat
                    417: static int sys_unlinkat(int dirfd, const char *pathname, int flags)
                    418: {
                    419:   return (unlinkat(dirfd, pathname, flags));
                    420: }
                    421: #endif
                    422: #else /* !CONFIG_ATFILE */
                    423: 
                    424: /*
                    425:  * Try direct syscalls instead
                    426:  */
1.1.1.6   root      427: #if defined(TARGET_NR_faccessat) && defined(__NR_faccessat)
1.1.1.8   root      428: _syscall3(int,sys_faccessat,int,dirfd,const char *,pathname,int,mode)
1.1.1.6   root      429: #endif
                    430: #if defined(TARGET_NR_fchmodat) && defined(__NR_fchmodat)
1.1.1.8   root      431: _syscall3(int,sys_fchmodat,int,dirfd,const char *,pathname, mode_t,mode)
1.1.1.6   root      432: #endif
1.1.1.12  root      433: #if defined(TARGET_NR_fchownat) && defined(__NR_fchownat)
1.1.1.6   root      434: _syscall5(int,sys_fchownat,int,dirfd,const char *,pathname,
                    435:           uid_t,owner,gid_t,group,int,flags)
                    436: #endif
1.1.1.8   root      437: #if (defined(TARGET_NR_fstatat64) || defined(TARGET_NR_newfstatat)) && \
                    438:         defined(__NR_fstatat64)
1.1.1.7   root      439: _syscall4(int,sys_fstatat64,int,dirfd,const char *,pathname,
                    440:           struct stat *,buf,int,flags)
                    441: #endif
                    442: #if defined(TARGET_NR_futimesat) && defined(__NR_futimesat)
                    443: _syscall3(int,sys_futimesat,int,dirfd,const char *,pathname,
                    444:          const struct timeval *,times)
                    445: #endif
1.1.1.8   root      446: #if (defined(TARGET_NR_newfstatat) || defined(TARGET_NR_fstatat64) ) && \
                    447:         defined(__NR_newfstatat)
                    448: _syscall4(int,sys_newfstatat,int,dirfd,const char *,pathname,
                    449:           struct stat *,buf,int,flags)
1.1.1.7   root      450: #endif
1.1.1.6   root      451: #if defined(TARGET_NR_linkat) && defined(__NR_linkat)
                    452: _syscall5(int,sys_linkat,int,olddirfd,const char *,oldpath,
1.1.1.8   root      453:       int,newdirfd,const char *,newpath,int,flags)
1.1.1.6   root      454: #endif
                    455: #if defined(TARGET_NR_mkdirat) && defined(__NR_mkdirat)
                    456: _syscall3(int,sys_mkdirat,int,dirfd,const char *,pathname,mode_t,mode)
                    457: #endif
                    458: #if defined(TARGET_NR_mknodat) && defined(__NR_mknodat)
                    459: _syscall4(int,sys_mknodat,int,dirfd,const char *,pathname,
                    460:           mode_t,mode,dev_t,dev)
                    461: #endif
                    462: #if defined(TARGET_NR_openat) && defined(__NR_openat)
                    463: _syscall4(int,sys_openat,int,dirfd,const char *,pathname,int,flags,mode_t,mode)
                    464: #endif
                    465: #if defined(TARGET_NR_readlinkat) && defined(__NR_readlinkat)
                    466: _syscall4(int,sys_readlinkat,int,dirfd,const char *,pathname,
                    467:           char *,buf,size_t,bufsize)
                    468: #endif
                    469: #if defined(TARGET_NR_renameat) && defined(__NR_renameat)
                    470: _syscall4(int,sys_renameat,int,olddirfd,const char *,oldpath,
                    471:           int,newdirfd,const char *,newpath)
                    472: #endif
                    473: #if defined(TARGET_NR_symlinkat) && defined(__NR_symlinkat)
                    474: _syscall3(int,sys_symlinkat,const char *,oldpath,
                    475:           int,newdirfd,const char *,newpath)
                    476: #endif
                    477: #if defined(TARGET_NR_unlinkat) && defined(__NR_unlinkat)
                    478: _syscall3(int,sys_unlinkat,int,dirfd,const char *,pathname,int,flags)
                    479: #endif
1.1.1.8   root      480: 
                    481: #endif /* CONFIG_ATFILE */
                    482: 
                    483: #ifdef CONFIG_UTIMENSAT
                    484: static int sys_utimensat(int dirfd, const char *pathname,
                    485:     const struct timespec times[2], int flags)
                    486: {
                    487:     if (pathname == NULL)
                    488:         return futimens(dirfd, times);
                    489:     else
                    490:         return utimensat(dirfd, pathname, times, flags);
                    491: }
                    492: #else
1.1.1.6   root      493: #if defined(TARGET_NR_utimensat) && defined(__NR_utimensat)
                    494: _syscall4(int,sys_utimensat,int,dirfd,const char *,pathname,
                    495:           const struct timespec *,tsp,int,flags)
                    496: #endif
1.1.1.8   root      497: #endif /* CONFIG_UTIMENSAT  */
                    498: 
                    499: #ifdef CONFIG_INOTIFY
                    500: #include <sys/inotify.h>
                    501: 
1.1.1.7   root      502: #if defined(TARGET_NR_inotify_init) && defined(__NR_inotify_init)
1.1.1.8   root      503: static int sys_inotify_init(void)
                    504: {
                    505:   return (inotify_init());
                    506: }
1.1.1.7   root      507: #endif
                    508: #if defined(TARGET_NR_inotify_add_watch) && defined(__NR_inotify_add_watch)
1.1.1.8   root      509: static int sys_inotify_add_watch(int fd,const char *pathname, int32_t mask)
                    510: {
                    511:   return (inotify_add_watch(fd, pathname, mask));
                    512: }
1.1.1.7   root      513: #endif
                    514: #if defined(TARGET_NR_inotify_rm_watch) && defined(__NR_inotify_rm_watch)
1.1.1.8   root      515: static int sys_inotify_rm_watch(int fd, int32_t wd)
                    516: {
                    517:   return (inotify_rm_watch(fd, wd));
                    518: }
1.1.1.7   root      519: #endif
1.1.1.10  root      520: #ifdef CONFIG_INOTIFY1
                    521: #if defined(TARGET_NR_inotify_init1) && defined(__NR_inotify_init1)
                    522: static int sys_inotify_init1(int flags)
                    523: {
                    524:   return (inotify_init1(flags));
                    525: }
                    526: #endif
                    527: #endif
1.1.1.8   root      528: #else
                    529: /* Userspace can usually survive runtime without inotify */
                    530: #undef TARGET_NR_inotify_init
1.1.1.10  root      531: #undef TARGET_NR_inotify_init1
1.1.1.8   root      532: #undef TARGET_NR_inotify_add_watch
                    533: #undef TARGET_NR_inotify_rm_watch
                    534: #endif /* CONFIG_INOTIFY  */
                    535: 
1.1.1.12  root      536: #if defined(TARGET_NR_ppoll)
                    537: #ifndef __NR_ppoll
                    538: # define __NR_ppoll -1
                    539: #endif
                    540: #define __NR_sys_ppoll __NR_ppoll
                    541: _syscall5(int, sys_ppoll, struct pollfd *, fds, nfds_t, nfds,
                    542:           struct timespec *, timeout, const __sigset_t *, sigmask,
                    543:           size_t, sigsetsize)
                    544: #endif
                    545: 
                    546: #if defined(TARGET_NR_pselect6)
                    547: #ifndef __NR_pselect6
                    548: # define __NR_pselect6 -1
                    549: #endif
                    550: #define __NR_sys_pselect6 __NR_pselect6
                    551: _syscall6(int, sys_pselect6, int, nfds, fd_set *, readfds, fd_set *, writefds,
                    552:           fd_set *, exceptfds, struct timespec *, timeout, void *, sig);
                    553: #endif
                    554: 
                    555: #if defined(TARGET_NR_prlimit64)
                    556: #ifndef __NR_prlimit64
                    557: # define __NR_prlimit64 -1
                    558: #endif
                    559: #define __NR_sys_prlimit64 __NR_prlimit64
                    560: /* The glibc rlimit structure may not be that used by the underlying syscall */
                    561: struct host_rlimit64 {
                    562:     uint64_t rlim_cur;
                    563:     uint64_t rlim_max;
                    564: };
                    565: _syscall4(int, sys_prlimit64, pid_t, pid, int, resource,
                    566:           const struct host_rlimit64 *, new_limit,
                    567:           struct host_rlimit64 *, old_limit)
                    568: #endif
1.1       root      569: 
                    570: extern int personality(int);
                    571: extern int flock(int, int);
                    572: extern int setfsuid(int);
                    573: extern int setfsgid(int);
                    574: extern int setgroups(int, gid_t *);
                    575: 
1.1.1.12  root      576: /* ARM EABI and MIPS expect 64bit types aligned even on pairs or registers */
                    577: #ifdef TARGET_ARM 
                    578: static inline int regpairs_aligned(void *cpu_env) {
                    579:     return ((((CPUARMState *)cpu_env)->eabi) == 1) ;
                    580: }
                    581: #elif defined(TARGET_MIPS)
                    582: static inline int regpairs_aligned(void *cpu_env) { return 1; }
                    583: #else
                    584: static inline int regpairs_aligned(void *cpu_env) { return 0; }
                    585: #endif
                    586: 
1.1.1.6   root      587: #define ERRNO_TABLE_SIZE 1200
                    588: 
                    589: /* target_to_host_errno_table[] is initialized from
                    590:  * host_to_target_errno_table[] in syscall_init(). */
                    591: static uint16_t target_to_host_errno_table[ERRNO_TABLE_SIZE] = {
                    592: };
                    593: 
                    594: /*
                    595:  * This list is the union of errno values overridden in asm-<arch>/errno.h
                    596:  * minus the errnos that are not actually generic to all archs.
                    597:  */
                    598: static uint16_t host_to_target_errno_table[ERRNO_TABLE_SIZE] = {
                    599:     [EIDRM]            = TARGET_EIDRM,
                    600:     [ECHRNG]           = TARGET_ECHRNG,
                    601:     [EL2NSYNC]         = TARGET_EL2NSYNC,
                    602:     [EL3HLT]           = TARGET_EL3HLT,
                    603:     [EL3RST]           = TARGET_EL3RST,
                    604:     [ELNRNG]           = TARGET_ELNRNG,
                    605:     [EUNATCH]          = TARGET_EUNATCH,
                    606:     [ENOCSI]           = TARGET_ENOCSI,
                    607:     [EL2HLT]           = TARGET_EL2HLT,
                    608:     [EDEADLK]          = TARGET_EDEADLK,
                    609:     [ENOLCK]           = TARGET_ENOLCK,
                    610:     [EBADE]            = TARGET_EBADE,
                    611:     [EBADR]            = TARGET_EBADR,
                    612:     [EXFULL]           = TARGET_EXFULL,
                    613:     [ENOANO]           = TARGET_ENOANO,
                    614:     [EBADRQC]          = TARGET_EBADRQC,
                    615:     [EBADSLT]          = TARGET_EBADSLT,
                    616:     [EBFONT]           = TARGET_EBFONT,
                    617:     [ENOSTR]           = TARGET_ENOSTR,
                    618:     [ENODATA]          = TARGET_ENODATA,
                    619:     [ETIME]            = TARGET_ETIME,
                    620:     [ENOSR]            = TARGET_ENOSR,
                    621:     [ENONET]           = TARGET_ENONET,
                    622:     [ENOPKG]           = TARGET_ENOPKG,
                    623:     [EREMOTE]          = TARGET_EREMOTE,
                    624:     [ENOLINK]          = TARGET_ENOLINK,
                    625:     [EADV]             = TARGET_EADV,
                    626:     [ESRMNT]           = TARGET_ESRMNT,
                    627:     [ECOMM]            = TARGET_ECOMM,
                    628:     [EPROTO]           = TARGET_EPROTO,
                    629:     [EDOTDOT]          = TARGET_EDOTDOT,
                    630:     [EMULTIHOP]                = TARGET_EMULTIHOP,
                    631:     [EBADMSG]          = TARGET_EBADMSG,
                    632:     [ENAMETOOLONG]     = TARGET_ENAMETOOLONG,
                    633:     [EOVERFLOW]                = TARGET_EOVERFLOW,
                    634:     [ENOTUNIQ]         = TARGET_ENOTUNIQ,
                    635:     [EBADFD]           = TARGET_EBADFD,
                    636:     [EREMCHG]          = TARGET_EREMCHG,
                    637:     [ELIBACC]          = TARGET_ELIBACC,
                    638:     [ELIBBAD]          = TARGET_ELIBBAD,
                    639:     [ELIBSCN]          = TARGET_ELIBSCN,
                    640:     [ELIBMAX]          = TARGET_ELIBMAX,
                    641:     [ELIBEXEC]         = TARGET_ELIBEXEC,
                    642:     [EILSEQ]           = TARGET_EILSEQ,
                    643:     [ENOSYS]           = TARGET_ENOSYS,
                    644:     [ELOOP]            = TARGET_ELOOP,
                    645:     [ERESTART]         = TARGET_ERESTART,
                    646:     [ESTRPIPE]         = TARGET_ESTRPIPE,
                    647:     [ENOTEMPTY]                = TARGET_ENOTEMPTY,
                    648:     [EUSERS]           = TARGET_EUSERS,
                    649:     [ENOTSOCK]         = TARGET_ENOTSOCK,
                    650:     [EDESTADDRREQ]     = TARGET_EDESTADDRREQ,
                    651:     [EMSGSIZE]         = TARGET_EMSGSIZE,
                    652:     [EPROTOTYPE]       = TARGET_EPROTOTYPE,
                    653:     [ENOPROTOOPT]      = TARGET_ENOPROTOOPT,
                    654:     [EPROTONOSUPPORT]  = TARGET_EPROTONOSUPPORT,
                    655:     [ESOCKTNOSUPPORT]  = TARGET_ESOCKTNOSUPPORT,
                    656:     [EOPNOTSUPP]       = TARGET_EOPNOTSUPP,
                    657:     [EPFNOSUPPORT]     = TARGET_EPFNOSUPPORT,
                    658:     [EAFNOSUPPORT]     = TARGET_EAFNOSUPPORT,
                    659:     [EADDRINUSE]       = TARGET_EADDRINUSE,
                    660:     [EADDRNOTAVAIL]    = TARGET_EADDRNOTAVAIL,
                    661:     [ENETDOWN]         = TARGET_ENETDOWN,
                    662:     [ENETUNREACH]      = TARGET_ENETUNREACH,
                    663:     [ENETRESET]                = TARGET_ENETRESET,
                    664:     [ECONNABORTED]     = TARGET_ECONNABORTED,
                    665:     [ECONNRESET]       = TARGET_ECONNRESET,
                    666:     [ENOBUFS]          = TARGET_ENOBUFS,
                    667:     [EISCONN]          = TARGET_EISCONN,
                    668:     [ENOTCONN]         = TARGET_ENOTCONN,
                    669:     [EUCLEAN]          = TARGET_EUCLEAN,
                    670:     [ENOTNAM]          = TARGET_ENOTNAM,
                    671:     [ENAVAIL]          = TARGET_ENAVAIL,
                    672:     [EISNAM]           = TARGET_EISNAM,
                    673:     [EREMOTEIO]                = TARGET_EREMOTEIO,
                    674:     [ESHUTDOWN]                = TARGET_ESHUTDOWN,
                    675:     [ETOOMANYREFS]     = TARGET_ETOOMANYREFS,
                    676:     [ETIMEDOUT]                = TARGET_ETIMEDOUT,
                    677:     [ECONNREFUSED]     = TARGET_ECONNREFUSED,
                    678:     [EHOSTDOWN]                = TARGET_EHOSTDOWN,
                    679:     [EHOSTUNREACH]     = TARGET_EHOSTUNREACH,
                    680:     [EALREADY]         = TARGET_EALREADY,
                    681:     [EINPROGRESS]      = TARGET_EINPROGRESS,
                    682:     [ESTALE]           = TARGET_ESTALE,
                    683:     [ECANCELED]                = TARGET_ECANCELED,
                    684:     [ENOMEDIUM]                = TARGET_ENOMEDIUM,
                    685:     [EMEDIUMTYPE]      = TARGET_EMEDIUMTYPE,
                    686: #ifdef ENOKEY
                    687:     [ENOKEY]           = TARGET_ENOKEY,
                    688: #endif
                    689: #ifdef EKEYEXPIRED
                    690:     [EKEYEXPIRED]      = TARGET_EKEYEXPIRED,
                    691: #endif
                    692: #ifdef EKEYREVOKED
                    693:     [EKEYREVOKED]      = TARGET_EKEYREVOKED,
                    694: #endif
                    695: #ifdef EKEYREJECTED
                    696:     [EKEYREJECTED]     = TARGET_EKEYREJECTED,
                    697: #endif
                    698: #ifdef EOWNERDEAD
                    699:     [EOWNERDEAD]       = TARGET_EOWNERDEAD,
                    700: #endif
                    701: #ifdef ENOTRECOVERABLE
                    702:     [ENOTRECOVERABLE]  = TARGET_ENOTRECOVERABLE,
                    703: #endif
                    704: };
                    705: 
                    706: static inline int host_to_target_errno(int err)
                    707: {
                    708:     if(host_to_target_errno_table[err])
                    709:         return host_to_target_errno_table[err];
                    710:     return err;
                    711: }
                    712: 
                    713: static inline int target_to_host_errno(int err)
                    714: {
                    715:     if (target_to_host_errno_table[err])
                    716:         return target_to_host_errno_table[err];
                    717:     return err;
                    718: }
                    719: 
                    720: static inline abi_long get_errno(abi_long ret)
1.1       root      721: {
                    722:     if (ret == -1)
1.1.1.6   root      723:         return -host_to_target_errno(errno);
1.1       root      724:     else
                    725:         return ret;
                    726: }
                    727: 
1.1.1.6   root      728: static inline int is_error(abi_long ret)
                    729: {
                    730:     return (abi_ulong)ret >= (abi_ulong)(-4096);
                    731: }
                    732: 
                    733: char *target_strerror(int err)
1.1       root      734: {
1.1.1.14! root      735:     if ((err >= ERRNO_TABLE_SIZE) || (err < 0)) {
        !           736:         return NULL;
        !           737:     }
1.1.1.6   root      738:     return strerror(target_to_host_errno(err));
1.1       root      739: }
                    740: 
1.1.1.6   root      741: static abi_ulong target_brk;
                    742: static abi_ulong target_original_brk;
1.1.1.12  root      743: static abi_ulong brk_page;
1.1       root      744: 
1.1.1.6   root      745: void target_set_brk(abi_ulong new_brk)
1.1       root      746: {
1.1.1.6   root      747:     target_original_brk = target_brk = HOST_PAGE_ALIGN(new_brk);
1.1.1.12  root      748:     brk_page = HOST_PAGE_ALIGN(target_brk);
1.1       root      749: }
                    750: 
1.1.1.12  root      751: //#define DEBUGF_BRK(message, args...) do { fprintf(stderr, (message), ## args); } while (0)
                    752: #define DEBUGF_BRK(message, args...)
                    753: 
1.1.1.6   root      754: /* do_brk() must return target values and target errnos. */
                    755: abi_long do_brk(abi_ulong new_brk)
1.1       root      756: {
1.1.1.6   root      757:     abi_long mapped_addr;
1.1       root      758:     int        new_alloc_size;
                    759: 
1.1.1.14! root      760:     DEBUGF_BRK("do_brk(" TARGET_ABI_FMT_lx ") -> ", new_brk);
1.1.1.12  root      761: 
                    762:     if (!new_brk) {
1.1.1.14! root      763:         DEBUGF_BRK(TARGET_ABI_FMT_lx " (!new_brk)\n", target_brk);
1.1.1.3   root      764:         return target_brk;
1.1.1.12  root      765:     }
                    766:     if (new_brk < target_original_brk) {
1.1.1.14! root      767:         DEBUGF_BRK(TARGET_ABI_FMT_lx " (new_brk < target_original_brk)\n",
        !           768:                    target_brk);
1.1.1.7   root      769:         return target_brk;
1.1.1.12  root      770:     }
1.1.1.6   root      771: 
1.1.1.12  root      772:     /* If the new brk is less than the highest page reserved to the
                    773:      * target heap allocation, set it and we're almost done...  */
                    774:     if (new_brk <= brk_page) {
                    775:         /* Heap contents are initialized to zero, as for anonymous
                    776:          * mapped pages.  */
                    777:         if (new_brk > target_brk) {
                    778:             memset(g2h(target_brk), 0, new_brk - target_brk);
                    779:         }
1.1       root      780:        target_brk = new_brk;
1.1.1.14! root      781:         DEBUGF_BRK(TARGET_ABI_FMT_lx " (new_brk <= brk_page)\n", target_brk);
1.1.1.3   root      782:        return target_brk;
1.1       root      783:     }
                    784: 
1.1.1.12  root      785:     /* We need to allocate more memory after the brk... Note that
                    786:      * we don't use MAP_FIXED because that will map over the top of
                    787:      * any existing mapping (like the one with the host libc or qemu
                    788:      * itself); instead we treat "mapped but at wrong address" as
                    789:      * a failure and unmap again.
                    790:      */
                    791:     new_alloc_size = HOST_PAGE_ALIGN(new_brk - brk_page);
1.1.1.6   root      792:     mapped_addr = get_errno(target_mmap(brk_page, new_alloc_size,
1.1       root      793:                                         PROT_READ|PROT_WRITE,
1.1.1.12  root      794:                                         MAP_ANON|MAP_PRIVATE, 0, 0));
                    795: 
                    796:     if (mapped_addr == brk_page) {
1.1.1.13  root      797:         /* Heap contents are initialized to zero, as for anonymous
                    798:          * mapped pages.  Technically the new pages are already
                    799:          * initialized to zero since they *are* anonymous mapped
                    800:          * pages, however we have to take care with the contents that
                    801:          * come from the remaining part of the previous page: it may
                    802:          * contains garbage data due to a previous heap usage (grown
                    803:          * then shrunken).  */
                    804:         memset(g2h(target_brk), 0, brk_page - target_brk);
                    805: 
1.1.1.12  root      806:         target_brk = new_brk;
                    807:         brk_page = HOST_PAGE_ALIGN(target_brk);
1.1.1.14! root      808:         DEBUGF_BRK(TARGET_ABI_FMT_lx " (mapped_addr == brk_page)\n",
        !           809:             target_brk);
1.1.1.12  root      810:         return target_brk;
                    811:     } else if (mapped_addr != -1) {
                    812:         /* Mapped but at wrong address, meaning there wasn't actually
                    813:          * enough space for this brk.
                    814:          */
                    815:         target_munmap(mapped_addr, new_alloc_size);
                    816:         mapped_addr = -1;
1.1.1.14! root      817:         DEBUGF_BRK(TARGET_ABI_FMT_lx " (mapped_addr != -1)\n", target_brk);
1.1.1.12  root      818:     }
                    819:     else {
1.1.1.14! root      820:         DEBUGF_BRK(TARGET_ABI_FMT_lx " (otherwise)\n", target_brk);
1.1.1.12  root      821:     }
1.1.1.7   root      822: 
1.1.1.10  root      823: #if defined(TARGET_ALPHA)
                    824:     /* We (partially) emulate OSF/1 on Alpha, which requires we
                    825:        return a proper errno, not an unchanged brk value.  */
1.1.1.12  root      826:     return -TARGET_ENOMEM;
1.1.1.10  root      827: #endif
1.1.1.12  root      828:     /* For everything else, return the previous break. */
1.1.1.7   root      829:     return target_brk;
1.1       root      830: }
                    831: 
1.1.1.6   root      832: static inline abi_long copy_from_user_fdset(fd_set *fds,
                    833:                                             abi_ulong target_fds_addr,
                    834:                                             int n)
1.1       root      835: {
1.1.1.6   root      836:     int i, nw, j, k;
                    837:     abi_ulong b, *target_fds;
                    838: 
                    839:     nw = (n + TARGET_ABI_BITS - 1) / TARGET_ABI_BITS;
                    840:     if (!(target_fds = lock_user(VERIFY_READ,
                    841:                                  target_fds_addr,
                    842:                                  sizeof(abi_ulong) * nw,
                    843:                                  1)))
                    844:         return -TARGET_EFAULT;
                    845: 
                    846:     FD_ZERO(fds);
                    847:     k = 0;
                    848:     for (i = 0; i < nw; i++) {
                    849:         /* grab the abi_ulong */
                    850:         __get_user(b, &target_fds[i]);
                    851:         for (j = 0; j < TARGET_ABI_BITS; j++) {
                    852:             /* check the bit inside the abi_ulong */
                    853:             if ((b >> j) & 1)
                    854:                 FD_SET(k, fds);
                    855:             k++;
1.1       root      856:         }
                    857:     }
1.1.1.6   root      858: 
                    859:     unlock_user(target_fds, target_fds_addr, 0);
                    860: 
                    861:     return 0;
1.1       root      862: }
                    863: 
1.1.1.12  root      864: static inline abi_ulong copy_from_user_fdset_ptr(fd_set *fds, fd_set **fds_ptr,
                    865:                                                  abi_ulong target_fds_addr,
                    866:                                                  int n)
                    867: {
                    868:     if (target_fds_addr) {
                    869:         if (copy_from_user_fdset(fds, target_fds_addr, n))
                    870:             return -TARGET_EFAULT;
                    871:         *fds_ptr = fds;
                    872:     } else {
                    873:         *fds_ptr = NULL;
                    874:     }
                    875:     return 0;
                    876: }
                    877: 
1.1.1.6   root      878: static inline abi_long copy_to_user_fdset(abi_ulong target_fds_addr,
                    879:                                           const fd_set *fds,
                    880:                                           int n)
1.1       root      881: {
                    882:     int i, nw, j, k;
1.1.1.6   root      883:     abi_long v;
                    884:     abi_ulong *target_fds;
1.1       root      885: 
1.1.1.6   root      886:     nw = (n + TARGET_ABI_BITS - 1) / TARGET_ABI_BITS;
                    887:     if (!(target_fds = lock_user(VERIFY_WRITE,
                    888:                                  target_fds_addr,
                    889:                                  sizeof(abi_ulong) * nw,
                    890:                                  0)))
                    891:         return -TARGET_EFAULT;
                    892: 
                    893:     k = 0;
                    894:     for (i = 0; i < nw; i++) {
                    895:         v = 0;
                    896:         for (j = 0; j < TARGET_ABI_BITS; j++) {
                    897:             v |= ((FD_ISSET(k, fds) != 0) << j);
                    898:             k++;
1.1       root      899:         }
1.1.1.6   root      900:         __put_user(v, &target_fds[i]);
1.1       root      901:     }
1.1.1.6   root      902: 
                    903:     unlock_user(target_fds, target_fds_addr, sizeof(abi_ulong) * nw);
                    904: 
                    905:     return 0;
1.1       root      906: }
                    907: 
                    908: #if defined(__alpha__)
                    909: #define HOST_HZ 1024
                    910: #else
                    911: #define HOST_HZ 100
                    912: #endif
                    913: 
1.1.1.6   root      914: static inline abi_long host_to_target_clock_t(long ticks)
1.1       root      915: {
                    916: #if HOST_HZ == TARGET_HZ
                    917:     return ticks;
                    918: #else
                    919:     return ((int64_t)ticks * TARGET_HZ) / HOST_HZ;
                    920: #endif
                    921: }
                    922: 
1.1.1.6   root      923: static inline abi_long host_to_target_rusage(abi_ulong target_addr,
                    924:                                              const struct rusage *rusage)
1.1       root      925: {
1.1.1.3   root      926:     struct target_rusage *target_rusage;
                    927: 
1.1.1.6   root      928:     if (!lock_user_struct(VERIFY_WRITE, target_rusage, target_addr, 0))
                    929:         return -TARGET_EFAULT;
1.1.1.13  root      930:     target_rusage->ru_utime.tv_sec = tswapal(rusage->ru_utime.tv_sec);
                    931:     target_rusage->ru_utime.tv_usec = tswapal(rusage->ru_utime.tv_usec);
                    932:     target_rusage->ru_stime.tv_sec = tswapal(rusage->ru_stime.tv_sec);
                    933:     target_rusage->ru_stime.tv_usec = tswapal(rusage->ru_stime.tv_usec);
                    934:     target_rusage->ru_maxrss = tswapal(rusage->ru_maxrss);
                    935:     target_rusage->ru_ixrss = tswapal(rusage->ru_ixrss);
                    936:     target_rusage->ru_idrss = tswapal(rusage->ru_idrss);
                    937:     target_rusage->ru_isrss = tswapal(rusage->ru_isrss);
                    938:     target_rusage->ru_minflt = tswapal(rusage->ru_minflt);
                    939:     target_rusage->ru_majflt = tswapal(rusage->ru_majflt);
                    940:     target_rusage->ru_nswap = tswapal(rusage->ru_nswap);
                    941:     target_rusage->ru_inblock = tswapal(rusage->ru_inblock);
                    942:     target_rusage->ru_oublock = tswapal(rusage->ru_oublock);
                    943:     target_rusage->ru_msgsnd = tswapal(rusage->ru_msgsnd);
                    944:     target_rusage->ru_msgrcv = tswapal(rusage->ru_msgrcv);
                    945:     target_rusage->ru_nsignals = tswapal(rusage->ru_nsignals);
                    946:     target_rusage->ru_nvcsw = tswapal(rusage->ru_nvcsw);
                    947:     target_rusage->ru_nivcsw = tswapal(rusage->ru_nivcsw);
1.1.1.3   root      948:     unlock_user_struct(target_rusage, target_addr, 1);
1.1.1.6   root      949: 
                    950:     return 0;
1.1       root      951: }
                    952: 
1.1.1.13  root      953: static inline rlim_t target_to_host_rlim(abi_ulong target_rlim)
1.1.1.10  root      954: {
1.1.1.13  root      955:     abi_ulong target_rlim_swap;
1.1.1.12  root      956:     rlim_t result;
                    957:     
1.1.1.13  root      958:     target_rlim_swap = tswapal(target_rlim);
                    959:     if (target_rlim_swap == TARGET_RLIM_INFINITY)
                    960:         return RLIM_INFINITY;
                    961: 
                    962:     result = target_rlim_swap;
                    963:     if (target_rlim_swap != (rlim_t)result)
                    964:         return RLIM_INFINITY;
1.1.1.12  root      965:     
                    966:     return result;
1.1.1.10  root      967: }
                    968: 
1.1.1.13  root      969: static inline abi_ulong host_to_target_rlim(rlim_t rlim)
1.1.1.10  root      970: {
1.1.1.13  root      971:     abi_ulong target_rlim_swap;
                    972:     abi_ulong result;
1.1.1.12  root      973:     
1.1.1.13  root      974:     if (rlim == RLIM_INFINITY || rlim != (abi_long)rlim)
1.1.1.12  root      975:         target_rlim_swap = TARGET_RLIM_INFINITY;
1.1.1.10  root      976:     else
1.1.1.12  root      977:         target_rlim_swap = rlim;
1.1.1.13  root      978:     result = tswapal(target_rlim_swap);
1.1.1.12  root      979:     
                    980:     return result;
                    981: }
                    982: 
                    983: static inline int target_to_host_resource(int code)
                    984: {
                    985:     switch (code) {
                    986:     case TARGET_RLIMIT_AS:
                    987:         return RLIMIT_AS;
                    988:     case TARGET_RLIMIT_CORE:
                    989:         return RLIMIT_CORE;
                    990:     case TARGET_RLIMIT_CPU:
                    991:         return RLIMIT_CPU;
                    992:     case TARGET_RLIMIT_DATA:
                    993:         return RLIMIT_DATA;
                    994:     case TARGET_RLIMIT_FSIZE:
                    995:         return RLIMIT_FSIZE;
                    996:     case TARGET_RLIMIT_LOCKS:
                    997:         return RLIMIT_LOCKS;
                    998:     case TARGET_RLIMIT_MEMLOCK:
                    999:         return RLIMIT_MEMLOCK;
                   1000:     case TARGET_RLIMIT_MSGQUEUE:
                   1001:         return RLIMIT_MSGQUEUE;
                   1002:     case TARGET_RLIMIT_NICE:
                   1003:         return RLIMIT_NICE;
                   1004:     case TARGET_RLIMIT_NOFILE:
                   1005:         return RLIMIT_NOFILE;
                   1006:     case TARGET_RLIMIT_NPROC:
                   1007:         return RLIMIT_NPROC;
                   1008:     case TARGET_RLIMIT_RSS:
                   1009:         return RLIMIT_RSS;
                   1010:     case TARGET_RLIMIT_RTPRIO:
                   1011:         return RLIMIT_RTPRIO;
                   1012:     case TARGET_RLIMIT_SIGPENDING:
                   1013:         return RLIMIT_SIGPENDING;
                   1014:     case TARGET_RLIMIT_STACK:
                   1015:         return RLIMIT_STACK;
                   1016:     default:
                   1017:         return code;
                   1018:     }
1.1.1.10  root     1019: }
                   1020: 
1.1.1.6   root     1021: static inline abi_long copy_from_user_timeval(struct timeval *tv,
                   1022:                                               abi_ulong target_tv_addr)
1.1       root     1023: {
1.1.1.3   root     1024:     struct target_timeval *target_tv;
                   1025: 
1.1.1.6   root     1026:     if (!lock_user_struct(VERIFY_READ, target_tv, target_tv_addr, 1))
                   1027:         return -TARGET_EFAULT;
                   1028: 
                   1029:     __get_user(tv->tv_sec, &target_tv->tv_sec);
                   1030:     __get_user(tv->tv_usec, &target_tv->tv_usec);
                   1031: 
                   1032:     unlock_user_struct(target_tv, target_tv_addr, 0);
                   1033: 
                   1034:     return 0;
1.1       root     1035: }
                   1036: 
1.1.1.6   root     1037: static inline abi_long copy_to_user_timeval(abi_ulong target_tv_addr,
                   1038:                                             const struct timeval *tv)
1.1       root     1039: {
1.1.1.3   root     1040:     struct target_timeval *target_tv;
                   1041: 
1.1.1.6   root     1042:     if (!lock_user_struct(VERIFY_WRITE, target_tv, target_tv_addr, 0))
                   1043:         return -TARGET_EFAULT;
                   1044: 
                   1045:     __put_user(tv->tv_sec, &target_tv->tv_sec);
                   1046:     __put_user(tv->tv_usec, &target_tv->tv_usec);
                   1047: 
                   1048:     unlock_user_struct(target_tv, target_tv_addr, 1);
                   1049: 
                   1050:     return 0;
1.1       root     1051: }
                   1052: 
1.1.1.9   root     1053: #if defined(TARGET_NR_mq_open) && defined(__NR_mq_open)
                   1054: #include <mqueue.h>
                   1055: 
1.1.1.8   root     1056: static inline abi_long copy_from_user_mq_attr(struct mq_attr *attr,
                   1057:                                               abi_ulong target_mq_attr_addr)
                   1058: {
                   1059:     struct target_mq_attr *target_mq_attr;
                   1060: 
                   1061:     if (!lock_user_struct(VERIFY_READ, target_mq_attr,
                   1062:                           target_mq_attr_addr, 1))
                   1063:         return -TARGET_EFAULT;
                   1064: 
                   1065:     __get_user(attr->mq_flags, &target_mq_attr->mq_flags);
                   1066:     __get_user(attr->mq_maxmsg, &target_mq_attr->mq_maxmsg);
                   1067:     __get_user(attr->mq_msgsize, &target_mq_attr->mq_msgsize);
                   1068:     __get_user(attr->mq_curmsgs, &target_mq_attr->mq_curmsgs);
                   1069: 
                   1070:     unlock_user_struct(target_mq_attr, target_mq_attr_addr, 0);
                   1071: 
                   1072:     return 0;
                   1073: }
                   1074: 
                   1075: static inline abi_long copy_to_user_mq_attr(abi_ulong target_mq_attr_addr,
                   1076:                                             const struct mq_attr *attr)
                   1077: {
                   1078:     struct target_mq_attr *target_mq_attr;
                   1079: 
                   1080:     if (!lock_user_struct(VERIFY_WRITE, target_mq_attr,
                   1081:                           target_mq_attr_addr, 0))
                   1082:         return -TARGET_EFAULT;
                   1083: 
                   1084:     __put_user(attr->mq_flags, &target_mq_attr->mq_flags);
                   1085:     __put_user(attr->mq_maxmsg, &target_mq_attr->mq_maxmsg);
                   1086:     __put_user(attr->mq_msgsize, &target_mq_attr->mq_msgsize);
                   1087:     __put_user(attr->mq_curmsgs, &target_mq_attr->mq_curmsgs);
                   1088: 
                   1089:     unlock_user_struct(target_mq_attr, target_mq_attr_addr, 1);
                   1090: 
                   1091:     return 0;
                   1092: }
1.1.1.9   root     1093: #endif
1.1       root     1094: 
1.1.1.12  root     1095: #if defined(TARGET_NR_select) || defined(TARGET_NR__newselect)
1.1.1.6   root     1096: /* do_select() must return target values and target errnos. */
                   1097: static abi_long do_select(int n,
                   1098:                           abi_ulong rfd_addr, abi_ulong wfd_addr,
                   1099:                           abi_ulong efd_addr, abi_ulong target_tv_addr)
1.1       root     1100: {
                   1101:     fd_set rfds, wfds, efds;
                   1102:     fd_set *rfds_ptr, *wfds_ptr, *efds_ptr;
                   1103:     struct timeval tv, *tv_ptr;
1.1.1.6   root     1104:     abi_long ret;
1.1       root     1105: 
1.1.1.12  root     1106:     ret = copy_from_user_fdset_ptr(&rfds, &rfds_ptr, rfd_addr, n);
                   1107:     if (ret) {
                   1108:         return ret;
1.1.1.3   root     1109:     }
1.1.1.12  root     1110:     ret = copy_from_user_fdset_ptr(&wfds, &wfds_ptr, wfd_addr, n);
                   1111:     if (ret) {
                   1112:         return ret;
1.1.1.3   root     1113:     }
1.1.1.12  root     1114:     ret = copy_from_user_fdset_ptr(&efds, &efds_ptr, efd_addr, n);
                   1115:     if (ret) {
                   1116:         return ret;
1.1.1.3   root     1117:     }
1.1.1.6   root     1118: 
                   1119:     if (target_tv_addr) {
                   1120:         if (copy_from_user_timeval(&tv, target_tv_addr))
                   1121:             return -TARGET_EFAULT;
1.1       root     1122:         tv_ptr = &tv;
                   1123:     } else {
                   1124:         tv_ptr = NULL;
                   1125:     }
1.1.1.6   root     1126: 
1.1       root     1127:     ret = get_errno(select(n, rfds_ptr, wfds_ptr, efds_ptr, tv_ptr));
1.1.1.3   root     1128: 
1.1.1.6   root     1129:     if (!is_error(ret)) {
                   1130:         if (rfd_addr && copy_to_user_fdset(rfd_addr, &rfds, n))
                   1131:             return -TARGET_EFAULT;
                   1132:         if (wfd_addr && copy_to_user_fdset(wfd_addr, &wfds, n))
                   1133:             return -TARGET_EFAULT;
                   1134:         if (efd_addr && copy_to_user_fdset(efd_addr, &efds, n))
                   1135:             return -TARGET_EFAULT;
1.1       root     1136: 
1.1.1.6   root     1137:         if (target_tv_addr && copy_to_user_timeval(target_tv_addr, &tv))
                   1138:             return -TARGET_EFAULT;
1.1       root     1139:     }
1.1.1.3   root     1140: 
1.1       root     1141:     return ret;
                   1142: }
1.1.1.12  root     1143: #endif
1.1       root     1144: 
1.1.1.8   root     1145: static abi_long do_pipe2(int host_pipe[], int flags)
                   1146: {
                   1147: #ifdef CONFIG_PIPE2
                   1148:     return pipe2(host_pipe, flags);
                   1149: #else
                   1150:     return -ENOSYS;
                   1151: #endif
                   1152: }
                   1153: 
1.1.1.10  root     1154: static abi_long do_pipe(void *cpu_env, abi_ulong pipedes,
                   1155:                         int flags, int is_pipe2)
1.1.1.8   root     1156: {
                   1157:     int host_pipe[2];
                   1158:     abi_long ret;
                   1159:     ret = flags ? do_pipe2(host_pipe, flags) : pipe(host_pipe);
                   1160: 
                   1161:     if (is_error(ret))
                   1162:         return get_errno(ret);
1.1.1.10  root     1163: 
                   1164:     /* Several targets have special calling conventions for the original
                   1165:        pipe syscall, but didn't replicate this into the pipe2 syscall.  */
                   1166:     if (!is_pipe2) {
                   1167: #if defined(TARGET_ALPHA)
                   1168:         ((CPUAlphaState *)cpu_env)->ir[IR_A4] = host_pipe[1];
                   1169:         return host_pipe[0];
                   1170: #elif defined(TARGET_MIPS)
                   1171:         ((CPUMIPSState*)cpu_env)->active_tc.gpr[3] = host_pipe[1];
                   1172:         return host_pipe[0];
1.1.1.8   root     1173: #elif defined(TARGET_SH4)
1.1.1.10  root     1174:         ((CPUSH4State*)cpu_env)->gregs[1] = host_pipe[1];
                   1175:         return host_pipe[0];
                   1176: #endif
                   1177:     }
                   1178: 
1.1.1.8   root     1179:     if (put_user_s32(host_pipe[0], pipedes)
                   1180:         || put_user_s32(host_pipe[1], pipedes + sizeof(host_pipe[0])))
                   1181:         return -TARGET_EFAULT;
                   1182:     return get_errno(ret);
                   1183: }
                   1184: 
                   1185: static inline abi_long target_to_host_ip_mreq(struct ip_mreqn *mreqn,
                   1186:                                               abi_ulong target_addr,
                   1187:                                               socklen_t len)
                   1188: {
                   1189:     struct target_ip_mreqn *target_smreqn;
                   1190: 
                   1191:     target_smreqn = lock_user(VERIFY_READ, target_addr, len, 1);
                   1192:     if (!target_smreqn)
                   1193:         return -TARGET_EFAULT;
                   1194:     mreqn->imr_multiaddr.s_addr = target_smreqn->imr_multiaddr.s_addr;
                   1195:     mreqn->imr_address.s_addr = target_smreqn->imr_address.s_addr;
                   1196:     if (len == sizeof(struct target_ip_mreqn))
1.1.1.13  root     1197:         mreqn->imr_ifindex = tswapal(target_smreqn->imr_ifindex);
1.1.1.8   root     1198:     unlock_user(target_smreqn, target_addr, 0);
                   1199: 
                   1200:     return 0;
                   1201: }
                   1202: 
1.1.1.6   root     1203: static inline abi_long target_to_host_sockaddr(struct sockaddr *addr,
                   1204:                                                abi_ulong target_addr,
                   1205:                                                socklen_t len)
1.1       root     1206: {
1.1.1.8   root     1207:     const socklen_t unix_maxlen = sizeof (struct sockaddr_un);
                   1208:     sa_family_t sa_family;
1.1.1.3   root     1209:     struct target_sockaddr *target_saddr;
                   1210: 
1.1.1.6   root     1211:     target_saddr = lock_user(VERIFY_READ, target_addr, len, 1);
                   1212:     if (!target_saddr)
                   1213:         return -TARGET_EFAULT;
1.1.1.8   root     1214: 
                   1215:     sa_family = tswap16(target_saddr->sa_family);
                   1216: 
                   1217:     /* Oops. The caller might send a incomplete sun_path; sun_path
                   1218:      * must be terminated by \0 (see the manual page), but
                   1219:      * unfortunately it is quite common to specify sockaddr_un
                   1220:      * length as "strlen(x->sun_path)" while it should be
                   1221:      * "strlen(...) + 1". We'll fix that here if needed.
                   1222:      * Linux kernel has a similar feature.
                   1223:      */
                   1224: 
                   1225:     if (sa_family == AF_UNIX) {
                   1226:         if (len < unix_maxlen && len > 0) {
                   1227:             char *cp = (char*)target_saddr;
                   1228: 
                   1229:             if ( cp[len-1] && !cp[len] )
                   1230:                 len++;
                   1231:         }
                   1232:         if (len > unix_maxlen)
                   1233:             len = unix_maxlen;
                   1234:     }
                   1235: 
1.1.1.3   root     1236:     memcpy(addr, target_saddr, len);
1.1.1.8   root     1237:     addr->sa_family = sa_family;
1.1.1.3   root     1238:     unlock_user(target_saddr, target_addr, 0);
1.1.1.6   root     1239: 
                   1240:     return 0;
1.1       root     1241: }
                   1242: 
1.1.1.6   root     1243: static inline abi_long host_to_target_sockaddr(abi_ulong target_addr,
                   1244:                                                struct sockaddr *addr,
                   1245:                                                socklen_t len)
1.1       root     1246: {
1.1.1.3   root     1247:     struct target_sockaddr *target_saddr;
                   1248: 
1.1.1.6   root     1249:     target_saddr = lock_user(VERIFY_WRITE, target_addr, len, 0);
                   1250:     if (!target_saddr)
                   1251:         return -TARGET_EFAULT;
1.1.1.3   root     1252:     memcpy(target_saddr, addr, len);
                   1253:     target_saddr->sa_family = tswap16(addr->sa_family);
                   1254:     unlock_user(target_saddr, target_addr, len);
1.1.1.6   root     1255: 
                   1256:     return 0;
1.1       root     1257: }
                   1258: 
1.1.1.3   root     1259: /* ??? Should this also swap msgh->name?  */
1.1.1.6   root     1260: static inline abi_long target_to_host_cmsg(struct msghdr *msgh,
                   1261:                                            struct target_msghdr *target_msgh)
1.1       root     1262: {
                   1263:     struct cmsghdr *cmsg = CMSG_FIRSTHDR(msgh);
1.1.1.6   root     1264:     abi_long msg_controllen;
                   1265:     abi_ulong target_cmsg_addr;
                   1266:     struct target_cmsghdr *target_cmsg;
1.1       root     1267:     socklen_t space = 0;
1.1.1.6   root     1268:     
1.1.1.13  root     1269:     msg_controllen = tswapal(target_msgh->msg_controllen);
1.1.1.6   root     1270:     if (msg_controllen < sizeof (struct target_cmsghdr)) 
                   1271:         goto the_end;
1.1.1.13  root     1272:     target_cmsg_addr = tswapal(target_msgh->msg_control);
1.1.1.6   root     1273:     target_cmsg = lock_user(VERIFY_READ, target_cmsg_addr, msg_controllen, 1);
                   1274:     if (!target_cmsg)
                   1275:         return -TARGET_EFAULT;
1.1       root     1276: 
                   1277:     while (cmsg && target_cmsg) {
                   1278:         void *data = CMSG_DATA(cmsg);
                   1279:         void *target_data = TARGET_CMSG_DATA(target_cmsg);
                   1280: 
1.1.1.13  root     1281:         int len = tswapal(target_cmsg->cmsg_len)
1.1       root     1282:                   - TARGET_CMSG_ALIGN(sizeof (struct target_cmsghdr));
                   1283: 
                   1284:         space += CMSG_SPACE(len);
                   1285:         if (space > msgh->msg_controllen) {
                   1286:             space -= CMSG_SPACE(len);
1.1.1.2   root     1287:             gemu_log("Host cmsg overflow\n");
1.1       root     1288:             break;
                   1289:         }
                   1290: 
                   1291:         cmsg->cmsg_level = tswap32(target_cmsg->cmsg_level);
                   1292:         cmsg->cmsg_type = tswap32(target_cmsg->cmsg_type);
                   1293:         cmsg->cmsg_len = CMSG_LEN(len);
                   1294: 
1.1.1.4   root     1295:         if (cmsg->cmsg_level != TARGET_SOL_SOCKET || cmsg->cmsg_type != SCM_RIGHTS) {
1.1       root     1296:             gemu_log("Unsupported ancillary data: %d/%d\n", cmsg->cmsg_level, cmsg->cmsg_type);
                   1297:             memcpy(data, target_data, len);
                   1298:         } else {
                   1299:             int *fd = (int *)data;
                   1300:             int *target_fd = (int *)target_data;
                   1301:             int i, numfds = len / sizeof(int);
                   1302: 
                   1303:             for (i = 0; i < numfds; i++)
                   1304:                 fd[i] = tswap32(target_fd[i]);
                   1305:         }
                   1306: 
                   1307:         cmsg = CMSG_NXTHDR(msgh, cmsg);
                   1308:         target_cmsg = TARGET_CMSG_NXTHDR(target_msgh, target_cmsg);
                   1309:     }
1.1.1.6   root     1310:     unlock_user(target_cmsg, target_cmsg_addr, 0);
                   1311:  the_end:
1.1       root     1312:     msgh->msg_controllen = space;
1.1.1.6   root     1313:     return 0;
1.1       root     1314: }
                   1315: 
1.1.1.3   root     1316: /* ??? Should this also swap msgh->name?  */
1.1.1.6   root     1317: static inline abi_long host_to_target_cmsg(struct target_msghdr *target_msgh,
                   1318:                                            struct msghdr *msgh)
1.1       root     1319: {
                   1320:     struct cmsghdr *cmsg = CMSG_FIRSTHDR(msgh);
1.1.1.6   root     1321:     abi_long msg_controllen;
                   1322:     abi_ulong target_cmsg_addr;
                   1323:     struct target_cmsghdr *target_cmsg;
1.1       root     1324:     socklen_t space = 0;
                   1325: 
1.1.1.13  root     1326:     msg_controllen = tswapal(target_msgh->msg_controllen);
1.1.1.6   root     1327:     if (msg_controllen < sizeof (struct target_cmsghdr)) 
                   1328:         goto the_end;
1.1.1.13  root     1329:     target_cmsg_addr = tswapal(target_msgh->msg_control);
1.1.1.6   root     1330:     target_cmsg = lock_user(VERIFY_WRITE, target_cmsg_addr, msg_controllen, 0);
                   1331:     if (!target_cmsg)
                   1332:         return -TARGET_EFAULT;
                   1333: 
1.1       root     1334:     while (cmsg && target_cmsg) {
                   1335:         void *data = CMSG_DATA(cmsg);
                   1336:         void *target_data = TARGET_CMSG_DATA(target_cmsg);
                   1337: 
                   1338:         int len = cmsg->cmsg_len - CMSG_ALIGN(sizeof (struct cmsghdr));
                   1339: 
                   1340:         space += TARGET_CMSG_SPACE(len);
1.1.1.6   root     1341:         if (space > msg_controllen) {
1.1       root     1342:             space -= TARGET_CMSG_SPACE(len);
1.1.1.2   root     1343:             gemu_log("Target cmsg overflow\n");
1.1       root     1344:             break;
                   1345:         }
                   1346: 
                   1347:         target_cmsg->cmsg_level = tswap32(cmsg->cmsg_level);
                   1348:         target_cmsg->cmsg_type = tswap32(cmsg->cmsg_type);
1.1.1.13  root     1349:         target_cmsg->cmsg_len = tswapal(TARGET_CMSG_LEN(len));
1.1       root     1350: 
1.1.1.4   root     1351:         if (cmsg->cmsg_level != TARGET_SOL_SOCKET || cmsg->cmsg_type != SCM_RIGHTS) {
1.1       root     1352:             gemu_log("Unsupported ancillary data: %d/%d\n", cmsg->cmsg_level, cmsg->cmsg_type);
                   1353:             memcpy(target_data, data, len);
                   1354:         } else {
                   1355:             int *fd = (int *)data;
                   1356:             int *target_fd = (int *)target_data;
                   1357:             int i, numfds = len / sizeof(int);
                   1358: 
                   1359:             for (i = 0; i < numfds; i++)
                   1360:                 target_fd[i] = tswap32(fd[i]);
                   1361:         }
                   1362: 
                   1363:         cmsg = CMSG_NXTHDR(msgh, cmsg);
                   1364:         target_cmsg = TARGET_CMSG_NXTHDR(target_msgh, target_cmsg);
                   1365:     }
1.1.1.6   root     1366:     unlock_user(target_cmsg, target_cmsg_addr, space);
                   1367:  the_end:
1.1.1.13  root     1368:     target_msgh->msg_controllen = tswapal(space);
1.1.1.6   root     1369:     return 0;
1.1       root     1370: }
                   1371: 
1.1.1.6   root     1372: /* do_setsockopt() Must return target values and target errnos. */
                   1373: static abi_long do_setsockopt(int sockfd, int level, int optname,
                   1374:                               abi_ulong optval_addr, socklen_t optlen)
1.1       root     1375: {
1.1.1.6   root     1376:     abi_long ret;
                   1377:     int val;
1.1.1.8   root     1378:     struct ip_mreqn *ip_mreq;
                   1379:     struct ip_mreq_source *ip_mreq_source;
1.1.1.6   root     1380: 
1.1       root     1381:     switch(level) {
                   1382:     case SOL_TCP:
                   1383:         /* TCP options all take an 'int' value.  */
                   1384:         if (optlen < sizeof(uint32_t))
1.1.1.6   root     1385:             return -TARGET_EINVAL;
                   1386: 
                   1387:         if (get_user_u32(val, optval_addr))
                   1388:             return -TARGET_EFAULT;
1.1       root     1389:         ret = get_errno(setsockopt(sockfd, level, optname, &val, sizeof(val)));
                   1390:         break;
                   1391:     case SOL_IP:
                   1392:         switch(optname) {
                   1393:         case IP_TOS:
                   1394:         case IP_TTL:
                   1395:         case IP_HDRINCL:
                   1396:         case IP_ROUTER_ALERT:
                   1397:         case IP_RECVOPTS:
                   1398:         case IP_RETOPTS:
                   1399:         case IP_PKTINFO:
                   1400:         case IP_MTU_DISCOVER:
                   1401:         case IP_RECVERR:
                   1402:         case IP_RECVTOS:
                   1403: #ifdef IP_FREEBIND
                   1404:         case IP_FREEBIND:
                   1405: #endif
                   1406:         case IP_MULTICAST_TTL:
                   1407:         case IP_MULTICAST_LOOP:
                   1408:             val = 0;
                   1409:             if (optlen >= sizeof(uint32_t)) {
1.1.1.6   root     1410:                 if (get_user_u32(val, optval_addr))
                   1411:                     return -TARGET_EFAULT;
1.1       root     1412:             } else if (optlen >= 1) {
1.1.1.6   root     1413:                 if (get_user_u8(val, optval_addr))
                   1414:                     return -TARGET_EFAULT;
1.1       root     1415:             }
                   1416:             ret = get_errno(setsockopt(sockfd, level, optname, &val, sizeof(val)));
                   1417:             break;
1.1.1.8   root     1418:         case IP_ADD_MEMBERSHIP:
                   1419:         case IP_DROP_MEMBERSHIP:
                   1420:             if (optlen < sizeof (struct target_ip_mreq) ||
                   1421:                 optlen > sizeof (struct target_ip_mreqn))
                   1422:                 return -TARGET_EINVAL;
                   1423: 
                   1424:             ip_mreq = (struct ip_mreqn *) alloca(optlen);
                   1425:             target_to_host_ip_mreq(ip_mreq, optval_addr, optlen);
                   1426:             ret = get_errno(setsockopt(sockfd, level, optname, ip_mreq, optlen));
                   1427:             break;
                   1428: 
                   1429:         case IP_BLOCK_SOURCE:
                   1430:         case IP_UNBLOCK_SOURCE:
                   1431:         case IP_ADD_SOURCE_MEMBERSHIP:
                   1432:         case IP_DROP_SOURCE_MEMBERSHIP:
                   1433:             if (optlen != sizeof (struct target_ip_mreq_source))
                   1434:                 return -TARGET_EINVAL;
                   1435: 
                   1436:             ip_mreq_source = lock_user(VERIFY_READ, optval_addr, optlen, 1);
                   1437:             ret = get_errno(setsockopt(sockfd, level, optname, ip_mreq_source, optlen));
                   1438:             unlock_user (ip_mreq_source, optval_addr, 0);
                   1439:             break;
                   1440: 
1.1       root     1441:         default:
                   1442:             goto unimplemented;
                   1443:         }
                   1444:         break;
1.1.1.4   root     1445:     case TARGET_SOL_SOCKET:
1.1       root     1446:         switch (optname) {
                   1447:             /* Options with 'int' argument.  */
1.1.1.4   root     1448:         case TARGET_SO_DEBUG:
                   1449:                optname = SO_DEBUG;
                   1450:                break;
                   1451:         case TARGET_SO_REUSEADDR:
                   1452:                optname = SO_REUSEADDR;
                   1453:                break;
                   1454:         case TARGET_SO_TYPE:
                   1455:                optname = SO_TYPE;
                   1456:                break;
                   1457:         case TARGET_SO_ERROR:
                   1458:                optname = SO_ERROR;
                   1459:                break;
                   1460:         case TARGET_SO_DONTROUTE:
                   1461:                optname = SO_DONTROUTE;
                   1462:                break;
                   1463:         case TARGET_SO_BROADCAST:
                   1464:                optname = SO_BROADCAST;
                   1465:                break;
                   1466:         case TARGET_SO_SNDBUF:
                   1467:                optname = SO_SNDBUF;
                   1468:                break;
                   1469:         case TARGET_SO_RCVBUF:
                   1470:                optname = SO_RCVBUF;
                   1471:                break;
                   1472:         case TARGET_SO_KEEPALIVE:
                   1473:                optname = SO_KEEPALIVE;
                   1474:                break;
                   1475:         case TARGET_SO_OOBINLINE:
                   1476:                optname = SO_OOBINLINE;
                   1477:                break;
                   1478:         case TARGET_SO_NO_CHECK:
                   1479:                optname = SO_NO_CHECK;
                   1480:                break;
                   1481:         case TARGET_SO_PRIORITY:
                   1482:                optname = SO_PRIORITY;
                   1483:                break;
1.1       root     1484: #ifdef SO_BSDCOMPAT
1.1.1.4   root     1485:         case TARGET_SO_BSDCOMPAT:
                   1486:                optname = SO_BSDCOMPAT;
                   1487:                break;
1.1       root     1488: #endif
1.1.1.4   root     1489:         case TARGET_SO_PASSCRED:
                   1490:                optname = SO_PASSCRED;
                   1491:                break;
                   1492:         case TARGET_SO_TIMESTAMP:
                   1493:                optname = SO_TIMESTAMP;
                   1494:                break;
                   1495:         case TARGET_SO_RCVLOWAT:
                   1496:                optname = SO_RCVLOWAT;
                   1497:                break;
                   1498:         case TARGET_SO_RCVTIMEO:
                   1499:                optname = SO_RCVTIMEO;
                   1500:                break;
                   1501:         case TARGET_SO_SNDTIMEO:
                   1502:                optname = SO_SNDTIMEO;
                   1503:                break;
1.1       root     1504:             break;
                   1505:         default:
                   1506:             goto unimplemented;
                   1507:         }
1.1.1.4   root     1508:        if (optlen < sizeof(uint32_t))
1.1.1.6   root     1509:             return -TARGET_EINVAL;
1.1.1.4   root     1510: 
1.1.1.6   root     1511:        if (get_user_u32(val, optval_addr))
                   1512:             return -TARGET_EFAULT;
1.1.1.4   root     1513:        ret = get_errno(setsockopt(sockfd, SOL_SOCKET, optname, &val, sizeof(val)));
1.1       root     1514:         break;
                   1515:     default:
                   1516:     unimplemented:
1.1.1.13  root     1517:         gemu_log("Unsupported setsockopt level=%d optname=%d\n", level, optname);
1.1.1.6   root     1518:         ret = -TARGET_ENOPROTOOPT;
1.1       root     1519:     }
                   1520:     return ret;
                   1521: }
                   1522: 
1.1.1.6   root     1523: /* do_getsockopt() Must return target values and target errnos. */
                   1524: static abi_long do_getsockopt(int sockfd, int level, int optname,
                   1525:                               abi_ulong optval_addr, abi_ulong optlen)
1.1       root     1526: {
1.1.1.6   root     1527:     abi_long ret;
1.1.1.7   root     1528:     int len, val;
                   1529:     socklen_t lv;
1.1       root     1530: 
                   1531:     switch(level) {
1.1.1.4   root     1532:     case TARGET_SOL_SOCKET:
1.1.1.11  root     1533:         level = SOL_SOCKET;
                   1534:         switch (optname) {
                   1535:         /* These don't just return a single integer */
                   1536:         case TARGET_SO_LINGER:
                   1537:         case TARGET_SO_RCVTIMEO:
                   1538:         case TARGET_SO_SNDTIMEO:
                   1539:         case TARGET_SO_PEERNAME:
                   1540:             goto unimplemented;
1.1.1.14! root     1541:         case TARGET_SO_PEERCRED: {
        !          1542:             struct ucred cr;
        !          1543:             socklen_t crlen;
        !          1544:             struct target_ucred *tcr;
        !          1545: 
        !          1546:             if (get_user_u32(len, optlen)) {
        !          1547:                 return -TARGET_EFAULT;
        !          1548:             }
        !          1549:             if (len < 0) {
        !          1550:                 return -TARGET_EINVAL;
        !          1551:             }
        !          1552: 
        !          1553:             crlen = sizeof(cr);
        !          1554:             ret = get_errno(getsockopt(sockfd, level, SO_PEERCRED,
        !          1555:                                        &cr, &crlen));
        !          1556:             if (ret < 0) {
        !          1557:                 return ret;
        !          1558:             }
        !          1559:             if (len > crlen) {
        !          1560:                 len = crlen;
        !          1561:             }
        !          1562:             if (!lock_user_struct(VERIFY_WRITE, tcr, optval_addr, 0)) {
        !          1563:                 return -TARGET_EFAULT;
        !          1564:             }
        !          1565:             __put_user(cr.pid, &tcr->pid);
        !          1566:             __put_user(cr.uid, &tcr->uid);
        !          1567:             __put_user(cr.gid, &tcr->gid);
        !          1568:             unlock_user_struct(tcr, optval_addr, 1);
        !          1569:             if (put_user_u32(len, optlen)) {
        !          1570:                 return -TARGET_EFAULT;
        !          1571:             }
        !          1572:             break;
        !          1573:         }
1.1.1.11  root     1574:         /* Options with 'int' argument.  */
                   1575:         case TARGET_SO_DEBUG:
                   1576:             optname = SO_DEBUG;
                   1577:             goto int_case;
                   1578:         case TARGET_SO_REUSEADDR:
                   1579:             optname = SO_REUSEADDR;
                   1580:             goto int_case;
                   1581:         case TARGET_SO_TYPE:
                   1582:             optname = SO_TYPE;
                   1583:             goto int_case;
                   1584:         case TARGET_SO_ERROR:
                   1585:             optname = SO_ERROR;
                   1586:             goto int_case;
                   1587:         case TARGET_SO_DONTROUTE:
                   1588:             optname = SO_DONTROUTE;
                   1589:             goto int_case;
                   1590:         case TARGET_SO_BROADCAST:
                   1591:             optname = SO_BROADCAST;
                   1592:             goto int_case;
                   1593:         case TARGET_SO_SNDBUF:
                   1594:             optname = SO_SNDBUF;
                   1595:             goto int_case;
                   1596:         case TARGET_SO_RCVBUF:
                   1597:             optname = SO_RCVBUF;
                   1598:             goto int_case;
                   1599:         case TARGET_SO_KEEPALIVE:
                   1600:             optname = SO_KEEPALIVE;
                   1601:             goto int_case;
                   1602:         case TARGET_SO_OOBINLINE:
                   1603:             optname = SO_OOBINLINE;
                   1604:             goto int_case;
                   1605:         case TARGET_SO_NO_CHECK:
                   1606:             optname = SO_NO_CHECK;
                   1607:             goto int_case;
                   1608:         case TARGET_SO_PRIORITY:
                   1609:             optname = SO_PRIORITY;
                   1610:             goto int_case;
                   1611: #ifdef SO_BSDCOMPAT
                   1612:         case TARGET_SO_BSDCOMPAT:
                   1613:             optname = SO_BSDCOMPAT;
                   1614:             goto int_case;
                   1615: #endif
                   1616:         case TARGET_SO_PASSCRED:
                   1617:             optname = SO_PASSCRED;
                   1618:             goto int_case;
                   1619:         case TARGET_SO_TIMESTAMP:
                   1620:             optname = SO_TIMESTAMP;
                   1621:             goto int_case;
                   1622:         case TARGET_SO_RCVLOWAT:
                   1623:             optname = SO_RCVLOWAT;
                   1624:             goto int_case;
1.1       root     1625:         default:
                   1626:             goto int_case;
                   1627:         }
                   1628:         break;
                   1629:     case SOL_TCP:
                   1630:         /* TCP options all take an 'int' value.  */
                   1631:     int_case:
1.1.1.6   root     1632:         if (get_user_u32(len, optlen))
                   1633:             return -TARGET_EFAULT;
1.1       root     1634:         if (len < 0)
1.1.1.6   root     1635:             return -TARGET_EINVAL;
1.1.1.12  root     1636:         lv = sizeof(lv);
1.1       root     1637:         ret = get_errno(getsockopt(sockfd, level, optname, &val, &lv));
                   1638:         if (ret < 0)
                   1639:             return ret;
                   1640:         if (len > lv)
                   1641:             len = lv;
1.1.1.6   root     1642:         if (len == 4) {
                   1643:             if (put_user_u32(val, optval_addr))
                   1644:                 return -TARGET_EFAULT;
                   1645:         } else {
                   1646:             if (put_user_u8(val, optval_addr))
                   1647:                 return -TARGET_EFAULT;
1.1.1.11  root     1648:         }
1.1.1.6   root     1649:         if (put_user_u32(len, optlen))
                   1650:             return -TARGET_EFAULT;
1.1       root     1651:         break;
                   1652:     case SOL_IP:
                   1653:         switch(optname) {
                   1654:         case IP_TOS:
                   1655:         case IP_TTL:
                   1656:         case IP_HDRINCL:
                   1657:         case IP_ROUTER_ALERT:
                   1658:         case IP_RECVOPTS:
                   1659:         case IP_RETOPTS:
                   1660:         case IP_PKTINFO:
                   1661:         case IP_MTU_DISCOVER:
                   1662:         case IP_RECVERR:
                   1663:         case IP_RECVTOS:
                   1664: #ifdef IP_FREEBIND
                   1665:         case IP_FREEBIND:
                   1666: #endif
                   1667:         case IP_MULTICAST_TTL:
                   1668:         case IP_MULTICAST_LOOP:
1.1.1.6   root     1669:             if (get_user_u32(len, optlen))
                   1670:                 return -TARGET_EFAULT;
1.1       root     1671:             if (len < 0)
1.1.1.6   root     1672:                 return -TARGET_EINVAL;
1.1.1.12  root     1673:             lv = sizeof(lv);
1.1       root     1674:             ret = get_errno(getsockopt(sockfd, level, optname, &val, &lv));
                   1675:             if (ret < 0)
                   1676:                 return ret;
                   1677:             if (len < sizeof(int) && len > 0 && val >= 0 && val < 255) {
                   1678:                 len = 1;
1.1.1.6   root     1679:                 if (put_user_u32(len, optlen)
                   1680:                     || put_user_u8(val, optval_addr))
                   1681:                     return -TARGET_EFAULT;
1.1       root     1682:             } else {
                   1683:                 if (len > sizeof(int))
                   1684:                     len = sizeof(int);
1.1.1.6   root     1685:                 if (put_user_u32(len, optlen)
                   1686:                     || put_user_u32(val, optval_addr))
                   1687:                     return -TARGET_EFAULT;
1.1       root     1688:             }
                   1689:             break;
                   1690:         default:
1.1.1.6   root     1691:             ret = -TARGET_ENOPROTOOPT;
                   1692:             break;
1.1       root     1693:         }
                   1694:         break;
                   1695:     default:
                   1696:     unimplemented:
                   1697:         gemu_log("getsockopt level=%d optname=%d not yet supported\n",
                   1698:                  level, optname);
1.1.1.6   root     1699:         ret = -TARGET_EOPNOTSUPP;
1.1       root     1700:         break;
                   1701:     }
                   1702:     return ret;
                   1703: }
                   1704: 
1.1.1.6   root     1705: /* FIXME
                   1706:  * lock_iovec()/unlock_iovec() have a return code of 0 for success where
                   1707:  * other lock functions have a return code of 0 for failure.
                   1708:  */
                   1709: static abi_long lock_iovec(int type, struct iovec *vec, abi_ulong target_addr,
                   1710:                            int count, int copy)
1.1.1.3   root     1711: {
                   1712:     struct target_iovec *target_vec;
1.1.1.6   root     1713:     abi_ulong base;
1.1.1.7   root     1714:     int i;
1.1.1.3   root     1715: 
1.1.1.6   root     1716:     target_vec = lock_user(VERIFY_READ, target_addr, count * sizeof(struct target_iovec), 1);
                   1717:     if (!target_vec)
                   1718:         return -TARGET_EFAULT;
1.1.1.3   root     1719:     for(i = 0;i < count; i++) {
1.1.1.13  root     1720:         base = tswapal(target_vec[i].iov_base);
                   1721:         vec[i].iov_len = tswapal(target_vec[i].iov_len);
1.1.1.7   root     1722:         if (vec[i].iov_len != 0) {
                   1723:             vec[i].iov_base = lock_user(type, base, vec[i].iov_len, copy);
                   1724:             /* Don't check lock_user return value. We must call writev even
                   1725:                if a element has invalid base address. */
                   1726:         } else {
                   1727:             /* zero length pointer is ignored */
                   1728:             vec[i].iov_base = NULL;
                   1729:         }
1.1.1.6   root     1730:     }
                   1731:     unlock_user (target_vec, target_addr, 0);
                   1732:     return 0;
1.1.1.3   root     1733: }
                   1734: 
1.1.1.6   root     1735: static abi_long unlock_iovec(struct iovec *vec, abi_ulong target_addr,
                   1736:                              int count, int copy)
1.1.1.3   root     1737: {
                   1738:     struct target_iovec *target_vec;
1.1.1.6   root     1739:     abi_ulong base;
1.1.1.3   root     1740:     int i;
                   1741: 
1.1.1.6   root     1742:     target_vec = lock_user(VERIFY_READ, target_addr, count * sizeof(struct target_iovec), 1);
                   1743:     if (!target_vec)
                   1744:         return -TARGET_EFAULT;
1.1.1.3   root     1745:     for(i = 0;i < count; i++) {
1.1.1.7   root     1746:         if (target_vec[i].iov_base) {
1.1.1.13  root     1747:             base = tswapal(target_vec[i].iov_base);
1.1.1.7   root     1748:             unlock_user(vec[i].iov_base, base, copy ? vec[i].iov_len : 0);
                   1749:         }
1.1.1.3   root     1750:     }
                   1751:     unlock_user (target_vec, target_addr, 0);
1.1.1.6   root     1752: 
                   1753:     return 0;
1.1.1.3   root     1754: }
                   1755: 
1.1.1.6   root     1756: /* do_socket() Must return target values and target errnos. */
                   1757: static abi_long do_socket(int domain, int type, int protocol)
1.1.1.4   root     1758: {
                   1759: #if defined(TARGET_MIPS)
                   1760:     switch(type) {
                   1761:     case TARGET_SOCK_DGRAM:
                   1762:         type = SOCK_DGRAM;
                   1763:         break;
                   1764:     case TARGET_SOCK_STREAM:
                   1765:         type = SOCK_STREAM;
                   1766:         break;
                   1767:     case TARGET_SOCK_RAW:
                   1768:         type = SOCK_RAW;
                   1769:         break;
                   1770:     case TARGET_SOCK_RDM:
                   1771:         type = SOCK_RDM;
                   1772:         break;
                   1773:     case TARGET_SOCK_SEQPACKET:
                   1774:         type = SOCK_SEQPACKET;
                   1775:         break;
                   1776:     case TARGET_SOCK_PACKET:
                   1777:         type = SOCK_PACKET;
                   1778:         break;
                   1779:     }
                   1780: #endif
1.1.1.6   root     1781:     if (domain == PF_NETLINK)
                   1782:         return -EAFNOSUPPORT; /* do not NETLINK socket connections possible */
1.1.1.4   root     1783:     return get_errno(socket(domain, type, protocol));
                   1784: }
                   1785: 
1.1.1.6   root     1786: /* do_bind() Must return target values and target errnos. */
                   1787: static abi_long do_bind(int sockfd, abi_ulong target_addr,
                   1788:                         socklen_t addrlen)
1.1.1.4   root     1789: {
1.1.1.7   root     1790:     void *addr;
1.1.1.8   root     1791:     abi_long ret;
1.1.1.7   root     1792: 
1.1.1.11  root     1793:     if ((int)addrlen < 0) {
1.1.1.7   root     1794:         return -TARGET_EINVAL;
1.1.1.11  root     1795:     }
1.1.1.7   root     1796: 
1.1.1.8   root     1797:     addr = alloca(addrlen+1);
                   1798: 
                   1799:     ret = target_to_host_sockaddr(addr, target_addr, addrlen);
                   1800:     if (ret)
                   1801:         return ret;
1.1.1.6   root     1802: 
1.1.1.4   root     1803:     return get_errno(bind(sockfd, addr, addrlen));
                   1804: }
                   1805: 
1.1.1.6   root     1806: /* do_connect() Must return target values and target errnos. */
                   1807: static abi_long do_connect(int sockfd, abi_ulong target_addr,
                   1808:                            socklen_t addrlen)
1.1.1.4   root     1809: {
1.1.1.7   root     1810:     void *addr;
1.1.1.8   root     1811:     abi_long ret;
1.1.1.7   root     1812: 
1.1.1.11  root     1813:     if ((int)addrlen < 0) {
1.1.1.7   root     1814:         return -TARGET_EINVAL;
1.1.1.11  root     1815:     }
1.1.1.7   root     1816: 
                   1817:     addr = alloca(addrlen);
1.1.1.6   root     1818: 
1.1.1.8   root     1819:     ret = target_to_host_sockaddr(addr, target_addr, addrlen);
                   1820:     if (ret)
                   1821:         return ret;
                   1822: 
1.1.1.4   root     1823:     return get_errno(connect(sockfd, addr, addrlen));
                   1824: }
                   1825: 
1.1.1.6   root     1826: /* do_sendrecvmsg() Must return target values and target errnos. */
                   1827: static abi_long do_sendrecvmsg(int fd, abi_ulong target_msg,
                   1828:                                int flags, int send)
1.1.1.4   root     1829: {
1.1.1.7   root     1830:     abi_long ret, len;
1.1.1.4   root     1831:     struct target_msghdr *msgp;
                   1832:     struct msghdr msg;
                   1833:     int count;
                   1834:     struct iovec *vec;
1.1.1.6   root     1835:     abi_ulong target_vec;
1.1.1.4   root     1836: 
1.1.1.6   root     1837:     /* FIXME */
                   1838:     if (!lock_user_struct(send ? VERIFY_READ : VERIFY_WRITE,
                   1839:                           msgp,
                   1840:                           target_msg,
                   1841:                           send ? 1 : 0))
                   1842:         return -TARGET_EFAULT;
1.1.1.4   root     1843:     if (msgp->msg_name) {
                   1844:         msg.msg_namelen = tswap32(msgp->msg_namelen);
                   1845:         msg.msg_name = alloca(msg.msg_namelen);
1.1.1.13  root     1846:         ret = target_to_host_sockaddr(msg.msg_name, tswapal(msgp->msg_name),
1.1.1.4   root     1847:                                 msg.msg_namelen);
1.1.1.8   root     1848:         if (ret) {
                   1849:             unlock_user_struct(msgp, target_msg, send ? 0 : 1);
                   1850:             return ret;
                   1851:         }
1.1.1.4   root     1852:     } else {
                   1853:         msg.msg_name = NULL;
                   1854:         msg.msg_namelen = 0;
                   1855:     }
1.1.1.13  root     1856:     msg.msg_controllen = 2 * tswapal(msgp->msg_controllen);
1.1.1.4   root     1857:     msg.msg_control = alloca(msg.msg_controllen);
                   1858:     msg.msg_flags = tswap32(msgp->msg_flags);
1.1.1.6   root     1859: 
1.1.1.13  root     1860:     count = tswapal(msgp->msg_iovlen);
1.1.1.4   root     1861:     vec = alloca(count * sizeof(struct iovec));
1.1.1.13  root     1862:     target_vec = tswapal(msgp->msg_iov);
1.1.1.6   root     1863:     lock_iovec(send ? VERIFY_READ : VERIFY_WRITE, vec, target_vec, count, send);
1.1.1.4   root     1864:     msg.msg_iovlen = count;
                   1865:     msg.msg_iov = vec;
1.1.1.6   root     1866: 
1.1.1.4   root     1867:     if (send) {
1.1.1.6   root     1868:         ret = target_to_host_cmsg(&msg, msgp);
                   1869:         if (ret == 0)
                   1870:             ret = get_errno(sendmsg(fd, &msg, flags));
1.1.1.4   root     1871:     } else {
                   1872:         ret = get_errno(recvmsg(fd, &msg, flags));
1.1.1.7   root     1873:         if (!is_error(ret)) {
                   1874:             len = ret;
1.1.1.6   root     1875:             ret = host_to_target_cmsg(msgp, &msg);
1.1.1.7   root     1876:             if (!is_error(ret))
                   1877:                 ret = len;
                   1878:         }
1.1.1.4   root     1879:     }
                   1880:     unlock_iovec(vec, target_vec, count, !send);
1.1.1.6   root     1881:     unlock_user_struct(msgp, target_msg, send ? 0 : 1);
1.1.1.4   root     1882:     return ret;
                   1883: }
                   1884: 
1.1.1.6   root     1885: /* do_accept() Must return target values and target errnos. */
                   1886: static abi_long do_accept(int fd, abi_ulong target_addr,
                   1887:                           abi_ulong target_addrlen_addr)
1.1.1.5   root     1888: {
1.1.1.6   root     1889:     socklen_t addrlen;
                   1890:     void *addr;
                   1891:     abi_long ret;
                   1892: 
1.1.1.8   root     1893:     if (target_addr == 0)
                   1894:        return get_errno(accept(fd, NULL, NULL));
                   1895: 
                   1896:     /* linux returns EINVAL if addrlen pointer is invalid */
1.1.1.6   root     1897:     if (get_user_u32(addrlen, target_addrlen_addr))
1.1.1.8   root     1898:         return -TARGET_EINVAL;
                   1899: 
1.1.1.11  root     1900:     if ((int)addrlen < 0) {
1.1.1.8   root     1901:         return -TARGET_EINVAL;
1.1.1.11  root     1902:     }
1.1.1.6   root     1903: 
1.1.1.8   root     1904:     if (!access_ok(VERIFY_WRITE, target_addr, addrlen))
1.1.1.7   root     1905:         return -TARGET_EINVAL;
                   1906: 
1.1.1.6   root     1907:     addr = alloca(addrlen);
1.1.1.5   root     1908: 
                   1909:     ret = get_errno(accept(fd, addr, &addrlen));
                   1910:     if (!is_error(ret)) {
                   1911:         host_to_target_sockaddr(target_addr, addr, addrlen);
1.1.1.6   root     1912:         if (put_user_u32(addrlen, target_addrlen_addr))
                   1913:             ret = -TARGET_EFAULT;
1.1.1.5   root     1914:     }
                   1915:     return ret;
                   1916: }
                   1917: 
1.1.1.6   root     1918: /* do_getpeername() Must return target values and target errnos. */
                   1919: static abi_long do_getpeername(int fd, abi_ulong target_addr,
                   1920:                                abi_ulong target_addrlen_addr)
1.1.1.5   root     1921: {
1.1.1.6   root     1922:     socklen_t addrlen;
                   1923:     void *addr;
                   1924:     abi_long ret;
                   1925: 
                   1926:     if (get_user_u32(addrlen, target_addrlen_addr))
                   1927:         return -TARGET_EFAULT;
                   1928: 
1.1.1.11  root     1929:     if ((int)addrlen < 0) {
1.1.1.7   root     1930:         return -TARGET_EINVAL;
1.1.1.11  root     1931:     }
1.1.1.7   root     1932: 
1.1.1.8   root     1933:     if (!access_ok(VERIFY_WRITE, target_addr, addrlen))
                   1934:         return -TARGET_EFAULT;
                   1935: 
1.1.1.6   root     1936:     addr = alloca(addrlen);
1.1.1.5   root     1937: 
                   1938:     ret = get_errno(getpeername(fd, addr, &addrlen));
                   1939:     if (!is_error(ret)) {
                   1940:         host_to_target_sockaddr(target_addr, addr, addrlen);
1.1.1.6   root     1941:         if (put_user_u32(addrlen, target_addrlen_addr))
                   1942:             ret = -TARGET_EFAULT;
1.1.1.5   root     1943:     }
                   1944:     return ret;
                   1945: }
                   1946: 
1.1.1.6   root     1947: /* do_getsockname() Must return target values and target errnos. */
                   1948: static abi_long do_getsockname(int fd, abi_ulong target_addr,
                   1949:                                abi_ulong target_addrlen_addr)
1.1.1.5   root     1950: {
1.1.1.6   root     1951:     socklen_t addrlen;
                   1952:     void *addr;
                   1953:     abi_long ret;
                   1954: 
                   1955:     if (get_user_u32(addrlen, target_addrlen_addr))
                   1956:         return -TARGET_EFAULT;
                   1957: 
1.1.1.11  root     1958:     if ((int)addrlen < 0) {
1.1.1.7   root     1959:         return -TARGET_EINVAL;
1.1.1.11  root     1960:     }
1.1.1.7   root     1961: 
1.1.1.8   root     1962:     if (!access_ok(VERIFY_WRITE, target_addr, addrlen))
                   1963:         return -TARGET_EFAULT;
                   1964: 
1.1.1.6   root     1965:     addr = alloca(addrlen);
1.1.1.5   root     1966: 
                   1967:     ret = get_errno(getsockname(fd, addr, &addrlen));
                   1968:     if (!is_error(ret)) {
                   1969:         host_to_target_sockaddr(target_addr, addr, addrlen);
1.1.1.6   root     1970:         if (put_user_u32(addrlen, target_addrlen_addr))
                   1971:             ret = -TARGET_EFAULT;
1.1.1.5   root     1972:     }
                   1973:     return ret;
                   1974: }
                   1975: 
1.1.1.6   root     1976: /* do_socketpair() Must return target values and target errnos. */
                   1977: static abi_long do_socketpair(int domain, int type, int protocol,
                   1978:                               abi_ulong target_tab_addr)
1.1.1.5   root     1979: {
                   1980:     int tab[2];
1.1.1.6   root     1981:     abi_long ret;
1.1.1.5   root     1982: 
                   1983:     ret = get_errno(socketpair(domain, type, protocol, tab));
                   1984:     if (!is_error(ret)) {
1.1.1.6   root     1985:         if (put_user_s32(tab[0], target_tab_addr)
                   1986:             || put_user_s32(tab[1], target_tab_addr + sizeof(tab[0])))
                   1987:             ret = -TARGET_EFAULT;
1.1.1.5   root     1988:     }
                   1989:     return ret;
                   1990: }
                   1991: 
1.1.1.6   root     1992: /* do_sendto() Must return target values and target errnos. */
                   1993: static abi_long do_sendto(int fd, abi_ulong msg, size_t len, int flags,
                   1994:                           abi_ulong target_addr, socklen_t addrlen)
1.1.1.5   root     1995: {
                   1996:     void *addr;
                   1997:     void *host_msg;
1.1.1.6   root     1998:     abi_long ret;
1.1.1.5   root     1999: 
1.1.1.11  root     2000:     if ((int)addrlen < 0) {
1.1.1.7   root     2001:         return -TARGET_EINVAL;
1.1.1.11  root     2002:     }
1.1.1.7   root     2003: 
1.1.1.6   root     2004:     host_msg = lock_user(VERIFY_READ, msg, len, 1);
                   2005:     if (!host_msg)
                   2006:         return -TARGET_EFAULT;
1.1.1.5   root     2007:     if (target_addr) {
                   2008:         addr = alloca(addrlen);
1.1.1.8   root     2009:         ret = target_to_host_sockaddr(addr, target_addr, addrlen);
                   2010:         if (ret) {
                   2011:             unlock_user(host_msg, msg, 0);
                   2012:             return ret;
                   2013:         }
1.1.1.5   root     2014:         ret = get_errno(sendto(fd, host_msg, len, flags, addr, addrlen));
                   2015:     } else {
                   2016:         ret = get_errno(send(fd, host_msg, len, flags));
                   2017:     }
                   2018:     unlock_user(host_msg, msg, 0);
                   2019:     return ret;
                   2020: }
                   2021: 
1.1.1.6   root     2022: /* do_recvfrom() Must return target values and target errnos. */
                   2023: static abi_long do_recvfrom(int fd, abi_ulong msg, size_t len, int flags,
                   2024:                             abi_ulong target_addr,
                   2025:                             abi_ulong target_addrlen)
1.1.1.5   root     2026: {
                   2027:     socklen_t addrlen;
                   2028:     void *addr;
                   2029:     void *host_msg;
1.1.1.6   root     2030:     abi_long ret;
1.1.1.5   root     2031: 
1.1.1.6   root     2032:     host_msg = lock_user(VERIFY_WRITE, msg, len, 0);
                   2033:     if (!host_msg)
                   2034:         return -TARGET_EFAULT;
1.1.1.5   root     2035:     if (target_addr) {
1.1.1.6   root     2036:         if (get_user_u32(addrlen, target_addrlen)) {
                   2037:             ret = -TARGET_EFAULT;
                   2038:             goto fail;
                   2039:         }
1.1.1.11  root     2040:         if ((int)addrlen < 0) {
1.1.1.7   root     2041:             ret = -TARGET_EINVAL;
                   2042:             goto fail;
                   2043:         }
1.1.1.5   root     2044:         addr = alloca(addrlen);
                   2045:         ret = get_errno(recvfrom(fd, host_msg, len, flags, addr, &addrlen));
                   2046:     } else {
                   2047:         addr = NULL; /* To keep compiler quiet.  */
1.1.1.12  root     2048:         ret = get_errno(qemu_recv(fd, host_msg, len, flags));
1.1.1.5   root     2049:     }
                   2050:     if (!is_error(ret)) {
                   2051:         if (target_addr) {
                   2052:             host_to_target_sockaddr(target_addr, addr, addrlen);
1.1.1.6   root     2053:             if (put_user_u32(addrlen, target_addrlen)) {
                   2054:                 ret = -TARGET_EFAULT;
                   2055:                 goto fail;
                   2056:             }
1.1.1.5   root     2057:         }
                   2058:         unlock_user(host_msg, msg, len);
                   2059:     } else {
1.1.1.6   root     2060: fail:
1.1.1.5   root     2061:         unlock_user(host_msg, msg, 0);
                   2062:     }
                   2063:     return ret;
                   2064: }
                   2065: 
1.1.1.6   root     2066: #ifdef TARGET_NR_socketcall
                   2067: /* do_socketcall() Must return target values and target errnos. */
                   2068: static abi_long do_socketcall(int num, abi_ulong vptr)
1.1       root     2069: {
1.1.1.6   root     2070:     abi_long ret;
                   2071:     const int n = sizeof(abi_ulong);
1.1       root     2072: 
                   2073:     switch(num) {
                   2074:     case SOCKOP_socket:
                   2075:        {
1.1.1.8   root     2076:             abi_ulong domain, type, protocol;
1.1.1.6   root     2077: 
1.1.1.8   root     2078:             if (get_user_ual(domain, vptr)
                   2079:                 || get_user_ual(type, vptr + n)
                   2080:                 || get_user_ual(protocol, vptr + 2 * n))
1.1.1.6   root     2081:                 return -TARGET_EFAULT;
                   2082: 
1.1.1.4   root     2083:             ret = do_socket(domain, type, protocol);
1.1       root     2084:        }
                   2085:         break;
                   2086:     case SOCKOP_bind:
                   2087:        {
1.1.1.8   root     2088:             abi_ulong sockfd;
1.1.1.6   root     2089:             abi_ulong target_addr;
                   2090:             socklen_t addrlen;
                   2091: 
1.1.1.8   root     2092:             if (get_user_ual(sockfd, vptr)
1.1.1.6   root     2093:                 || get_user_ual(target_addr, vptr + n)
1.1.1.8   root     2094:                 || get_user_ual(addrlen, vptr + 2 * n))
1.1.1.6   root     2095:                 return -TARGET_EFAULT;
                   2096: 
1.1.1.4   root     2097:             ret = do_bind(sockfd, target_addr, addrlen);
1.1       root     2098:         }
                   2099:         break;
                   2100:     case SOCKOP_connect:
                   2101:         {
1.1.1.8   root     2102:             abi_ulong sockfd;
1.1.1.6   root     2103:             abi_ulong target_addr;
                   2104:             socklen_t addrlen;
                   2105: 
1.1.1.8   root     2106:             if (get_user_ual(sockfd, vptr)
1.1.1.6   root     2107:                 || get_user_ual(target_addr, vptr + n)
1.1.1.8   root     2108:                 || get_user_ual(addrlen, vptr + 2 * n))
1.1.1.6   root     2109:                 return -TARGET_EFAULT;
                   2110: 
1.1.1.4   root     2111:             ret = do_connect(sockfd, target_addr, addrlen);
1.1       root     2112:         }
                   2113:         break;
                   2114:     case SOCKOP_listen:
                   2115:         {
1.1.1.8   root     2116:             abi_ulong sockfd, backlog;
1.1.1.6   root     2117: 
1.1.1.8   root     2118:             if (get_user_ual(sockfd, vptr)
                   2119:                 || get_user_ual(backlog, vptr + n))
1.1.1.6   root     2120:                 return -TARGET_EFAULT;
                   2121: 
1.1       root     2122:             ret = get_errno(listen(sockfd, backlog));
                   2123:         }
                   2124:         break;
                   2125:     case SOCKOP_accept:
                   2126:         {
1.1.1.8   root     2127:             abi_ulong sockfd;
1.1.1.6   root     2128:             abi_ulong target_addr, target_addrlen;
                   2129: 
1.1.1.8   root     2130:             if (get_user_ual(sockfd, vptr)
1.1.1.6   root     2131:                 || get_user_ual(target_addr, vptr + n)
1.1.1.8   root     2132:                 || get_user_ual(target_addrlen, vptr + 2 * n))
1.1.1.6   root     2133:                 return -TARGET_EFAULT;
                   2134: 
1.1.1.5   root     2135:             ret = do_accept(sockfd, target_addr, target_addrlen);
1.1       root     2136:         }
                   2137:         break;
                   2138:     case SOCKOP_getsockname:
                   2139:         {
1.1.1.8   root     2140:             abi_ulong sockfd;
1.1.1.6   root     2141:             abi_ulong target_addr, target_addrlen;
                   2142: 
1.1.1.8   root     2143:             if (get_user_ual(sockfd, vptr)
1.1.1.6   root     2144:                 || get_user_ual(target_addr, vptr + n)
1.1.1.8   root     2145:                 || get_user_ual(target_addrlen, vptr + 2 * n))
1.1.1.6   root     2146:                 return -TARGET_EFAULT;
                   2147: 
1.1.1.5   root     2148:             ret = do_getsockname(sockfd, target_addr, target_addrlen);
1.1       root     2149:         }
                   2150:         break;
                   2151:     case SOCKOP_getpeername:
                   2152:         {
1.1.1.8   root     2153:             abi_ulong sockfd;
1.1.1.6   root     2154:             abi_ulong target_addr, target_addrlen;
                   2155: 
1.1.1.8   root     2156:             if (get_user_ual(sockfd, vptr)
1.1.1.6   root     2157:                 || get_user_ual(target_addr, vptr + n)
1.1.1.8   root     2158:                 || get_user_ual(target_addrlen, vptr + 2 * n))
1.1.1.6   root     2159:                 return -TARGET_EFAULT;
                   2160: 
1.1.1.5   root     2161:             ret = do_getpeername(sockfd, target_addr, target_addrlen);
1.1       root     2162:         }
                   2163:         break;
                   2164:     case SOCKOP_socketpair:
                   2165:         {
1.1.1.8   root     2166:             abi_ulong domain, type, protocol;
1.1.1.6   root     2167:             abi_ulong tab;
                   2168: 
1.1.1.8   root     2169:             if (get_user_ual(domain, vptr)
                   2170:                 || get_user_ual(type, vptr + n)
                   2171:                 || get_user_ual(protocol, vptr + 2 * n)
1.1.1.6   root     2172:                 || get_user_ual(tab, vptr + 3 * n))
                   2173:                 return -TARGET_EFAULT;
                   2174: 
1.1.1.5   root     2175:             ret = do_socketpair(domain, type, protocol, tab);
1.1       root     2176:         }
                   2177:         break;
                   2178:     case SOCKOP_send:
                   2179:         {
1.1.1.8   root     2180:             abi_ulong sockfd;
1.1.1.6   root     2181:             abi_ulong msg;
                   2182:             size_t len;
1.1.1.8   root     2183:             abi_ulong flags;
1.1.1.6   root     2184: 
1.1.1.8   root     2185:             if (get_user_ual(sockfd, vptr)
1.1.1.6   root     2186:                 || get_user_ual(msg, vptr + n)
                   2187:                 || get_user_ual(len, vptr + 2 * n)
1.1.1.8   root     2188:                 || get_user_ual(flags, vptr + 3 * n))
1.1.1.6   root     2189:                 return -TARGET_EFAULT;
                   2190: 
1.1.1.5   root     2191:             ret = do_sendto(sockfd, msg, len, flags, 0, 0);
1.1       root     2192:         }
                   2193:         break;
                   2194:     case SOCKOP_recv:
                   2195:         {
1.1.1.8   root     2196:             abi_ulong sockfd;
1.1.1.6   root     2197:             abi_ulong msg;
                   2198:             size_t len;
1.1.1.8   root     2199:             abi_ulong flags;
1.1.1.6   root     2200: 
1.1.1.8   root     2201:             if (get_user_ual(sockfd, vptr)
1.1.1.6   root     2202:                 || get_user_ual(msg, vptr + n)
                   2203:                 || get_user_ual(len, vptr + 2 * n)
1.1.1.8   root     2204:                 || get_user_ual(flags, vptr + 3 * n))
1.1.1.6   root     2205:                 return -TARGET_EFAULT;
                   2206: 
1.1.1.5   root     2207:             ret = do_recvfrom(sockfd, msg, len, flags, 0, 0);
1.1       root     2208:         }
                   2209:         break;
                   2210:     case SOCKOP_sendto:
                   2211:         {
1.1.1.8   root     2212:             abi_ulong sockfd;
1.1.1.6   root     2213:             abi_ulong msg;
                   2214:             size_t len;
1.1.1.8   root     2215:             abi_ulong flags;
1.1.1.6   root     2216:             abi_ulong addr;
                   2217:             socklen_t addrlen;
                   2218: 
1.1.1.8   root     2219:             if (get_user_ual(sockfd, vptr)
1.1.1.6   root     2220:                 || get_user_ual(msg, vptr + n)
                   2221:                 || get_user_ual(len, vptr + 2 * n)
1.1.1.8   root     2222:                 || get_user_ual(flags, vptr + 3 * n)
1.1.1.6   root     2223:                 || get_user_ual(addr, vptr + 4 * n)
1.1.1.8   root     2224:                 || get_user_ual(addrlen, vptr + 5 * n))
1.1.1.6   root     2225:                 return -TARGET_EFAULT;
                   2226: 
1.1.1.5   root     2227:             ret = do_sendto(sockfd, msg, len, flags, addr, addrlen);
1.1       root     2228:         }
                   2229:         break;
                   2230:     case SOCKOP_recvfrom:
                   2231:         {
1.1.1.8   root     2232:             abi_ulong sockfd;
1.1.1.6   root     2233:             abi_ulong msg;
                   2234:             size_t len;
1.1.1.8   root     2235:             abi_ulong flags;
1.1.1.6   root     2236:             abi_ulong addr;
                   2237:             socklen_t addrlen;
                   2238: 
1.1.1.8   root     2239:             if (get_user_ual(sockfd, vptr)
1.1.1.6   root     2240:                 || get_user_ual(msg, vptr + n)
                   2241:                 || get_user_ual(len, vptr + 2 * n)
1.1.1.8   root     2242:                 || get_user_ual(flags, vptr + 3 * n)
1.1.1.6   root     2243:                 || get_user_ual(addr, vptr + 4 * n)
1.1.1.8   root     2244:                 || get_user_ual(addrlen, vptr + 5 * n))
1.1.1.6   root     2245:                 return -TARGET_EFAULT;
                   2246: 
1.1.1.5   root     2247:             ret = do_recvfrom(sockfd, msg, len, flags, addr, addrlen);
1.1       root     2248:         }
                   2249:         break;
                   2250:     case SOCKOP_shutdown:
                   2251:         {
1.1.1.8   root     2252:             abi_ulong sockfd, how;
1.1.1.6   root     2253: 
1.1.1.8   root     2254:             if (get_user_ual(sockfd, vptr)
                   2255:                 || get_user_ual(how, vptr + n))
1.1.1.6   root     2256:                 return -TARGET_EFAULT;
1.1       root     2257: 
                   2258:             ret = get_errno(shutdown(sockfd, how));
                   2259:         }
                   2260:         break;
                   2261:     case SOCKOP_sendmsg:
                   2262:     case SOCKOP_recvmsg:
                   2263:         {
1.1.1.8   root     2264:             abi_ulong fd;
1.1.1.6   root     2265:             abi_ulong target_msg;
1.1.1.8   root     2266:             abi_ulong flags;
1.1       root     2267: 
1.1.1.8   root     2268:             if (get_user_ual(fd, vptr)
1.1.1.6   root     2269:                 || get_user_ual(target_msg, vptr + n)
1.1.1.8   root     2270:                 || get_user_ual(flags, vptr + 2 * n))
1.1.1.6   root     2271:                 return -TARGET_EFAULT;
1.1.1.4   root     2272: 
1.1.1.6   root     2273:             ret = do_sendrecvmsg(fd, target_msg, flags,
1.1.1.4   root     2274:                                  (num == SOCKOP_sendmsg));
1.1       root     2275:         }
                   2276:         break;
                   2277:     case SOCKOP_setsockopt:
                   2278:         {
1.1.1.8   root     2279:             abi_ulong sockfd;
                   2280:             abi_ulong level;
                   2281:             abi_ulong optname;
1.1.1.6   root     2282:             abi_ulong optval;
                   2283:             socklen_t optlen;
                   2284: 
1.1.1.8   root     2285:             if (get_user_ual(sockfd, vptr)
                   2286:                 || get_user_ual(level, vptr + n)
                   2287:                 || get_user_ual(optname, vptr + 2 * n)
1.1.1.6   root     2288:                 || get_user_ual(optval, vptr + 3 * n)
1.1.1.8   root     2289:                 || get_user_ual(optlen, vptr + 4 * n))
1.1.1.6   root     2290:                 return -TARGET_EFAULT;
1.1       root     2291: 
                   2292:             ret = do_setsockopt(sockfd, level, optname, optval, optlen);
                   2293:         }
                   2294:         break;
                   2295:     case SOCKOP_getsockopt:
                   2296:         {
1.1.1.8   root     2297:             abi_ulong sockfd;
                   2298:             abi_ulong level;
                   2299:             abi_ulong optname;
1.1.1.6   root     2300:             abi_ulong optval;
                   2301:             socklen_t optlen;
                   2302: 
1.1.1.8   root     2303:             if (get_user_ual(sockfd, vptr)
                   2304:                 || get_user_ual(level, vptr + n)
                   2305:                 || get_user_ual(optname, vptr + 2 * n)
1.1.1.6   root     2306:                 || get_user_ual(optval, vptr + 3 * n)
1.1.1.8   root     2307:                 || get_user_ual(optlen, vptr + 4 * n))
1.1.1.6   root     2308:                 return -TARGET_EFAULT;
1.1       root     2309: 
1.1.1.6   root     2310:             ret = do_getsockopt(sockfd, level, optname, optval, optlen);
1.1       root     2311:         }
                   2312:         break;
                   2313:     default:
                   2314:         gemu_log("Unsupported socketcall: %d\n", num);
1.1.1.6   root     2315:         ret = -TARGET_ENOSYS;
1.1       root     2316:         break;
                   2317:     }
                   2318:     return ret;
                   2319: }
1.1.1.6   root     2320: #endif
1.1       root     2321: 
                   2322: #define N_SHM_REGIONS  32
                   2323: 
                   2324: static struct shm_region {
1.1.1.6   root     2325:     abi_ulong  start;
                   2326:     abi_ulong  size;
1.1       root     2327: } shm_regions[N_SHM_REGIONS];
                   2328: 
1.1.1.6   root     2329: struct target_ipc_perm
                   2330: {
                   2331:     abi_long __key;
                   2332:     abi_ulong uid;
                   2333:     abi_ulong gid;
                   2334:     abi_ulong cuid;
                   2335:     abi_ulong cgid;
                   2336:     unsigned short int mode;
                   2337:     unsigned short int __pad1;
                   2338:     unsigned short int __seq;
                   2339:     unsigned short int __pad2;
                   2340:     abi_ulong __unused1;
                   2341:     abi_ulong __unused2;
                   2342: };
                   2343: 
                   2344: struct target_semid_ds
                   2345: {
                   2346:   struct target_ipc_perm sem_perm;
                   2347:   abi_ulong sem_otime;
                   2348:   abi_ulong __unused1;
                   2349:   abi_ulong sem_ctime;
                   2350:   abi_ulong __unused2;
                   2351:   abi_ulong sem_nsems;
                   2352:   abi_ulong __unused3;
                   2353:   abi_ulong __unused4;
                   2354: };
                   2355: 
                   2356: static inline abi_long target_to_host_ipc_perm(struct ipc_perm *host_ip,
                   2357:                                                abi_ulong target_addr)
                   2358: {
                   2359:     struct target_ipc_perm *target_ip;
                   2360:     struct target_semid_ds *target_sd;
                   2361: 
                   2362:     if (!lock_user_struct(VERIFY_READ, target_sd, target_addr, 1))
                   2363:         return -TARGET_EFAULT;
1.1.1.9   root     2364:     target_ip = &(target_sd->sem_perm);
1.1.1.13  root     2365:     host_ip->__key = tswapal(target_ip->__key);
                   2366:     host_ip->uid = tswapal(target_ip->uid);
                   2367:     host_ip->gid = tswapal(target_ip->gid);
                   2368:     host_ip->cuid = tswapal(target_ip->cuid);
                   2369:     host_ip->cgid = tswapal(target_ip->cgid);
                   2370:     host_ip->mode = tswap16(target_ip->mode);
1.1.1.6   root     2371:     unlock_user_struct(target_sd, target_addr, 0);
                   2372:     return 0;
                   2373: }
                   2374: 
                   2375: static inline abi_long host_to_target_ipc_perm(abi_ulong target_addr,
                   2376:                                                struct ipc_perm *host_ip)
                   2377: {
                   2378:     struct target_ipc_perm *target_ip;
                   2379:     struct target_semid_ds *target_sd;
                   2380: 
                   2381:     if (!lock_user_struct(VERIFY_WRITE, target_sd, target_addr, 0))
                   2382:         return -TARGET_EFAULT;
                   2383:     target_ip = &(target_sd->sem_perm);
1.1.1.13  root     2384:     target_ip->__key = tswapal(host_ip->__key);
                   2385:     target_ip->uid = tswapal(host_ip->uid);
                   2386:     target_ip->gid = tswapal(host_ip->gid);
                   2387:     target_ip->cuid = tswapal(host_ip->cuid);
                   2388:     target_ip->cgid = tswapal(host_ip->cgid);
                   2389:     target_ip->mode = tswap16(host_ip->mode);
1.1.1.6   root     2390:     unlock_user_struct(target_sd, target_addr, 1);
                   2391:     return 0;
                   2392: }
                   2393: 
                   2394: static inline abi_long target_to_host_semid_ds(struct semid_ds *host_sd,
                   2395:                                                abi_ulong target_addr)
                   2396: {
                   2397:     struct target_semid_ds *target_sd;
                   2398: 
                   2399:     if (!lock_user_struct(VERIFY_READ, target_sd, target_addr, 1))
                   2400:         return -TARGET_EFAULT;
1.1.1.8   root     2401:     if (target_to_host_ipc_perm(&(host_sd->sem_perm),target_addr))
                   2402:         return -TARGET_EFAULT;
1.1.1.13  root     2403:     host_sd->sem_nsems = tswapal(target_sd->sem_nsems);
                   2404:     host_sd->sem_otime = tswapal(target_sd->sem_otime);
                   2405:     host_sd->sem_ctime = tswapal(target_sd->sem_ctime);
1.1.1.6   root     2406:     unlock_user_struct(target_sd, target_addr, 0);
                   2407:     return 0;
                   2408: }
                   2409: 
                   2410: static inline abi_long host_to_target_semid_ds(abi_ulong target_addr,
                   2411:                                                struct semid_ds *host_sd)
                   2412: {
                   2413:     struct target_semid_ds *target_sd;
                   2414: 
                   2415:     if (!lock_user_struct(VERIFY_WRITE, target_sd, target_addr, 0))
                   2416:         return -TARGET_EFAULT;
1.1.1.8   root     2417:     if (host_to_target_ipc_perm(target_addr,&(host_sd->sem_perm)))
1.1.1.14! root     2418:         return -TARGET_EFAULT;
1.1.1.13  root     2419:     target_sd->sem_nsems = tswapal(host_sd->sem_nsems);
                   2420:     target_sd->sem_otime = tswapal(host_sd->sem_otime);
                   2421:     target_sd->sem_ctime = tswapal(host_sd->sem_ctime);
1.1.1.6   root     2422:     unlock_user_struct(target_sd, target_addr, 1);
                   2423:     return 0;
                   2424: }
                   2425: 
1.1.1.8   root     2426: struct target_seminfo {
                   2427:     int semmap;
                   2428:     int semmni;
                   2429:     int semmns;
                   2430:     int semmnu;
                   2431:     int semmsl;
                   2432:     int semopm;
                   2433:     int semume;
                   2434:     int semusz;
                   2435:     int semvmx;
                   2436:     int semaem;
                   2437: };
                   2438: 
                   2439: static inline abi_long host_to_target_seminfo(abi_ulong target_addr,
                   2440:                                               struct seminfo *host_seminfo)
                   2441: {
                   2442:     struct target_seminfo *target_seminfo;
                   2443:     if (!lock_user_struct(VERIFY_WRITE, target_seminfo, target_addr, 0))
                   2444:         return -TARGET_EFAULT;
                   2445:     __put_user(host_seminfo->semmap, &target_seminfo->semmap);
                   2446:     __put_user(host_seminfo->semmni, &target_seminfo->semmni);
                   2447:     __put_user(host_seminfo->semmns, &target_seminfo->semmns);
                   2448:     __put_user(host_seminfo->semmnu, &target_seminfo->semmnu);
                   2449:     __put_user(host_seminfo->semmsl, &target_seminfo->semmsl);
                   2450:     __put_user(host_seminfo->semopm, &target_seminfo->semopm);
                   2451:     __put_user(host_seminfo->semume, &target_seminfo->semume);
                   2452:     __put_user(host_seminfo->semusz, &target_seminfo->semusz);
                   2453:     __put_user(host_seminfo->semvmx, &target_seminfo->semvmx);
                   2454:     __put_user(host_seminfo->semaem, &target_seminfo->semaem);
                   2455:     unlock_user_struct(target_seminfo, target_addr, 1);
                   2456:     return 0;
                   2457: }
                   2458: 
1.1.1.5   root     2459: union semun {
                   2460:        int val;
1.1.1.6   root     2461:        struct semid_ds *buf;
1.1.1.5   root     2462:        unsigned short *array;
1.1.1.8   root     2463:        struct seminfo *__buf;
1.1.1.5   root     2464: };
                   2465: 
1.1.1.6   root     2466: union target_semun {
                   2467:        int val;
1.1.1.8   root     2468:        abi_ulong buf;
                   2469:        abi_ulong array;
                   2470:        abi_ulong __buf;
1.1.1.6   root     2471: };
                   2472: 
1.1.1.8   root     2473: static inline abi_long target_to_host_semarray(int semid, unsigned short **host_array,
                   2474:                                                abi_ulong target_addr)
1.1.1.6   root     2475: {
1.1.1.8   root     2476:     int nsems;
                   2477:     unsigned short *array;
                   2478:     union semun semun;
                   2479:     struct semid_ds semid_ds;
                   2480:     int i, ret;
1.1.1.6   root     2481: 
1.1.1.8   root     2482:     semun.buf = &semid_ds;
                   2483: 
                   2484:     ret = semctl(semid, 0, IPC_STAT, semun);
                   2485:     if (ret == -1)
                   2486:         return get_errno(ret);
                   2487: 
                   2488:     nsems = semid_ds.sem_nsems;
                   2489: 
                   2490:     *host_array = malloc(nsems*sizeof(unsigned short));
                   2491:     array = lock_user(VERIFY_READ, target_addr,
                   2492:                       nsems*sizeof(unsigned short), 1);
                   2493:     if (!array)
                   2494:         return -TARGET_EFAULT;
                   2495: 
                   2496:     for(i=0; i<nsems; i++) {
                   2497:         __get_user((*host_array)[i], &array[i]);
1.1.1.6   root     2498:     }
1.1.1.8   root     2499:     unlock_user(array, target_addr, 0);
                   2500: 
1.1.1.6   root     2501:     return 0;
                   2502: }
                   2503: 
1.1.1.8   root     2504: static inline abi_long host_to_target_semarray(int semid, abi_ulong target_addr,
                   2505:                                                unsigned short **host_array)
1.1.1.6   root     2506: {
1.1.1.8   root     2507:     int nsems;
                   2508:     unsigned short *array;
                   2509:     union semun semun;
                   2510:     struct semid_ds semid_ds;
                   2511:     int i, ret;
1.1.1.6   root     2512: 
1.1.1.8   root     2513:     semun.buf = &semid_ds;
                   2514: 
                   2515:     ret = semctl(semid, 0, IPC_STAT, semun);
                   2516:     if (ret == -1)
                   2517:         return get_errno(ret);
                   2518: 
                   2519:     nsems = semid_ds.sem_nsems;
                   2520: 
                   2521:     array = lock_user(VERIFY_WRITE, target_addr,
                   2522:                       nsems*sizeof(unsigned short), 0);
                   2523:     if (!array)
                   2524:         return -TARGET_EFAULT;
                   2525: 
                   2526:     for(i=0; i<nsems; i++) {
                   2527:         __put_user((*host_array)[i], &array[i]);
1.1.1.6   root     2528:     }
1.1.1.8   root     2529:     free(*host_array);
                   2530:     unlock_user(array, target_addr, 1);
                   2531: 
1.1.1.6   root     2532:     return 0;
                   2533: }
                   2534: 
1.1.1.8   root     2535: static inline abi_long do_semctl(int semid, int semnum, int cmd,
                   2536:                                  union target_semun target_su)
1.1.1.6   root     2537: {
                   2538:     union semun arg;
                   2539:     struct semid_ds dsarg;
1.1.1.8   root     2540:     unsigned short *array = NULL;
                   2541:     struct seminfo seminfo;
                   2542:     abi_long ret = -TARGET_EINVAL;
                   2543:     abi_long err;
                   2544:     cmd &= 0xff;
1.1.1.6   root     2545: 
                   2546:     switch( cmd ) {
                   2547:        case GETVAL:
                   2548:        case SETVAL:
1.1.1.13  root     2549:             arg.val = tswap32(target_su.val);
1.1.1.8   root     2550:             ret = get_errno(semctl(semid, semnum, cmd, arg));
1.1.1.13  root     2551:             target_su.val = tswap32(arg.val);
1.1.1.6   root     2552:             break;
                   2553:        case GETALL:
                   2554:        case SETALL:
1.1.1.8   root     2555:             err = target_to_host_semarray(semid, &array, target_su.array);
                   2556:             if (err)
                   2557:                 return err;
                   2558:             arg.array = array;
                   2559:             ret = get_errno(semctl(semid, semnum, cmd, arg));
                   2560:             err = host_to_target_semarray(semid, target_su.array, &array);
                   2561:             if (err)
                   2562:                 return err;
1.1.1.6   root     2563:             break;
                   2564:        case IPC_STAT:
                   2565:        case IPC_SET:
1.1.1.8   root     2566:        case SEM_STAT:
                   2567:             err = target_to_host_semid_ds(&dsarg, target_su.buf);
                   2568:             if (err)
                   2569:                 return err;
                   2570:             arg.buf = &dsarg;
                   2571:             ret = get_errno(semctl(semid, semnum, cmd, arg));
                   2572:             err = host_to_target_semid_ds(target_su.buf, &dsarg);
                   2573:             if (err)
                   2574:                 return err;
                   2575:             break;
                   2576:        case IPC_INFO:
                   2577:        case SEM_INFO:
                   2578:             arg.__buf = &seminfo;
                   2579:             ret = get_errno(semctl(semid, semnum, cmd, arg));
                   2580:             err = host_to_target_seminfo(target_su.__buf, &seminfo);
                   2581:             if (err)
                   2582:                 return err;
                   2583:             break;
                   2584:        case IPC_RMID:
                   2585:        case GETPID:
                   2586:        case GETNCNT:
                   2587:        case GETZCNT:
                   2588:             ret = get_errno(semctl(semid, semnum, cmd, NULL));
1.1.1.6   root     2589:             break;
                   2590:     }
                   2591: 
                   2592:     return ret;
                   2593: }
                   2594: 
1.1.1.8   root     2595: struct target_sembuf {
                   2596:     unsigned short sem_num;
                   2597:     short sem_op;
                   2598:     short sem_flg;
                   2599: };
                   2600: 
                   2601: static inline abi_long target_to_host_sembuf(struct sembuf *host_sembuf,
                   2602:                                              abi_ulong target_addr,
                   2603:                                              unsigned nsops)
                   2604: {
                   2605:     struct target_sembuf *target_sembuf;
                   2606:     int i;
                   2607: 
                   2608:     target_sembuf = lock_user(VERIFY_READ, target_addr,
                   2609:                               nsops*sizeof(struct target_sembuf), 1);
                   2610:     if (!target_sembuf)
                   2611:         return -TARGET_EFAULT;
                   2612: 
                   2613:     for(i=0; i<nsops; i++) {
                   2614:         __get_user(host_sembuf[i].sem_num, &target_sembuf[i].sem_num);
                   2615:         __get_user(host_sembuf[i].sem_op, &target_sembuf[i].sem_op);
                   2616:         __get_user(host_sembuf[i].sem_flg, &target_sembuf[i].sem_flg);
                   2617:     }
                   2618: 
                   2619:     unlock_user(target_sembuf, target_addr, 0);
                   2620: 
                   2621:     return 0;
                   2622: }
                   2623: 
                   2624: static inline abi_long do_semop(int semid, abi_long ptr, unsigned nsops)
                   2625: {
                   2626:     struct sembuf sops[nsops];
                   2627: 
                   2628:     if (target_to_host_sembuf(sops, ptr, nsops))
                   2629:         return -TARGET_EFAULT;
                   2630: 
                   2631:     return semop(semid, sops, nsops);
                   2632: }
                   2633: 
1.1.1.6   root     2634: struct target_msqid_ds
                   2635: {
1.1.1.7   root     2636:     struct target_ipc_perm msg_perm;
                   2637:     abi_ulong msg_stime;
                   2638: #if TARGET_ABI_BITS == 32
                   2639:     abi_ulong __unused1;
                   2640: #endif
                   2641:     abi_ulong msg_rtime;
                   2642: #if TARGET_ABI_BITS == 32
                   2643:     abi_ulong __unused2;
                   2644: #endif
                   2645:     abi_ulong msg_ctime;
                   2646: #if TARGET_ABI_BITS == 32
                   2647:     abi_ulong __unused3;
                   2648: #endif
                   2649:     abi_ulong __msg_cbytes;
                   2650:     abi_ulong msg_qnum;
                   2651:     abi_ulong msg_qbytes;
                   2652:     abi_ulong msg_lspid;
                   2653:     abi_ulong msg_lrpid;
                   2654:     abi_ulong __unused4;
                   2655:     abi_ulong __unused5;
1.1.1.6   root     2656: };
                   2657: 
                   2658: static inline abi_long target_to_host_msqid_ds(struct msqid_ds *host_md,
                   2659:                                                abi_ulong target_addr)
                   2660: {
                   2661:     struct target_msqid_ds *target_md;
                   2662: 
                   2663:     if (!lock_user_struct(VERIFY_READ, target_md, target_addr, 1))
                   2664:         return -TARGET_EFAULT;
1.1.1.7   root     2665:     if (target_to_host_ipc_perm(&(host_md->msg_perm),target_addr))
                   2666:         return -TARGET_EFAULT;
1.1.1.13  root     2667:     host_md->msg_stime = tswapal(target_md->msg_stime);
                   2668:     host_md->msg_rtime = tswapal(target_md->msg_rtime);
                   2669:     host_md->msg_ctime = tswapal(target_md->msg_ctime);
                   2670:     host_md->__msg_cbytes = tswapal(target_md->__msg_cbytes);
                   2671:     host_md->msg_qnum = tswapal(target_md->msg_qnum);
                   2672:     host_md->msg_qbytes = tswapal(target_md->msg_qbytes);
                   2673:     host_md->msg_lspid = tswapal(target_md->msg_lspid);
                   2674:     host_md->msg_lrpid = tswapal(target_md->msg_lrpid);
1.1.1.6   root     2675:     unlock_user_struct(target_md, target_addr, 0);
                   2676:     return 0;
                   2677: }
                   2678: 
                   2679: static inline abi_long host_to_target_msqid_ds(abi_ulong target_addr,
                   2680:                                                struct msqid_ds *host_md)
                   2681: {
                   2682:     struct target_msqid_ds *target_md;
                   2683: 
                   2684:     if (!lock_user_struct(VERIFY_WRITE, target_md, target_addr, 0))
                   2685:         return -TARGET_EFAULT;
1.1.1.7   root     2686:     if (host_to_target_ipc_perm(target_addr,&(host_md->msg_perm)))
                   2687:         return -TARGET_EFAULT;
1.1.1.13  root     2688:     target_md->msg_stime = tswapal(host_md->msg_stime);
                   2689:     target_md->msg_rtime = tswapal(host_md->msg_rtime);
                   2690:     target_md->msg_ctime = tswapal(host_md->msg_ctime);
                   2691:     target_md->__msg_cbytes = tswapal(host_md->__msg_cbytes);
                   2692:     target_md->msg_qnum = tswapal(host_md->msg_qnum);
                   2693:     target_md->msg_qbytes = tswapal(host_md->msg_qbytes);
                   2694:     target_md->msg_lspid = tswapal(host_md->msg_lspid);
                   2695:     target_md->msg_lrpid = tswapal(host_md->msg_lrpid);
1.1.1.6   root     2696:     unlock_user_struct(target_md, target_addr, 1);
                   2697:     return 0;
                   2698: }
                   2699: 
1.1.1.7   root     2700: struct target_msginfo {
                   2701:     int msgpool;
                   2702:     int msgmap;
                   2703:     int msgmax;
                   2704:     int msgmnb;
                   2705:     int msgmni;
                   2706:     int msgssz;
                   2707:     int msgtql;
                   2708:     unsigned short int msgseg;
                   2709: };
                   2710: 
1.1.1.8   root     2711: static inline abi_long host_to_target_msginfo(abi_ulong target_addr,
                   2712:                                               struct msginfo *host_msginfo)
                   2713: {
                   2714:     struct target_msginfo *target_msginfo;
                   2715:     if (!lock_user_struct(VERIFY_WRITE, target_msginfo, target_addr, 0))
                   2716:         return -TARGET_EFAULT;
                   2717:     __put_user(host_msginfo->msgpool, &target_msginfo->msgpool);
                   2718:     __put_user(host_msginfo->msgmap, &target_msginfo->msgmap);
                   2719:     __put_user(host_msginfo->msgmax, &target_msginfo->msgmax);
                   2720:     __put_user(host_msginfo->msgmnb, &target_msginfo->msgmnb);
                   2721:     __put_user(host_msginfo->msgmni, &target_msginfo->msgmni);
                   2722:     __put_user(host_msginfo->msgssz, &target_msginfo->msgssz);
                   2723:     __put_user(host_msginfo->msgtql, &target_msginfo->msgtql);
                   2724:     __put_user(host_msginfo->msgseg, &target_msginfo->msgseg);
                   2725:     unlock_user_struct(target_msginfo, target_addr, 1);
                   2726:     return 0;
                   2727: }
                   2728: 
                   2729: static inline abi_long do_msgctl(int msgid, int cmd, abi_long ptr)
                   2730: {
                   2731:     struct msqid_ds dsarg;
                   2732:     struct msginfo msginfo;
                   2733:     abi_long ret = -TARGET_EINVAL;
                   2734: 
                   2735:     cmd &= 0xff;
                   2736: 
                   2737:     switch (cmd) {
                   2738:     case IPC_STAT:
                   2739:     case IPC_SET:
                   2740:     case MSG_STAT:
                   2741:         if (target_to_host_msqid_ds(&dsarg,ptr))
                   2742:             return -TARGET_EFAULT;
                   2743:         ret = get_errno(msgctl(msgid, cmd, &dsarg));
                   2744:         if (host_to_target_msqid_ds(ptr,&dsarg))
                   2745:             return -TARGET_EFAULT;
                   2746:         break;
                   2747:     case IPC_RMID:
                   2748:         ret = get_errno(msgctl(msgid, cmd, NULL));
                   2749:         break;
                   2750:     case IPC_INFO:
                   2751:     case MSG_INFO:
                   2752:         ret = get_errno(msgctl(msgid, cmd, (struct msqid_ds *)&msginfo));
                   2753:         if (host_to_target_msginfo(ptr, &msginfo))
                   2754:             return -TARGET_EFAULT;
                   2755:         break;
                   2756:     }
                   2757: 
                   2758:     return ret;
                   2759: }
                   2760: 
                   2761: struct target_msgbuf {
                   2762:     abi_long mtype;
                   2763:     char       mtext[1];
                   2764: };
                   2765: 
                   2766: static inline abi_long do_msgsnd(int msqid, abi_long msgp,
                   2767:                                  unsigned int msgsz, int msgflg)
                   2768: {
                   2769:     struct target_msgbuf *target_mb;
                   2770:     struct msgbuf *host_mb;
                   2771:     abi_long ret = 0;
                   2772: 
                   2773:     if (!lock_user_struct(VERIFY_READ, target_mb, msgp, 0))
                   2774:         return -TARGET_EFAULT;
                   2775:     host_mb = malloc(msgsz+sizeof(long));
1.1.1.13  root     2776:     host_mb->mtype = (abi_long) tswapal(target_mb->mtype);
1.1.1.8   root     2777:     memcpy(host_mb->mtext, target_mb->mtext, msgsz);
                   2778:     ret = get_errno(msgsnd(msqid, host_mb, msgsz, msgflg));
                   2779:     free(host_mb);
                   2780:     unlock_user_struct(target_mb, msgp, 0);
                   2781: 
                   2782:     return ret;
                   2783: }
                   2784: 
                   2785: static inline abi_long do_msgrcv(int msqid, abi_long msgp,
                   2786:                                  unsigned int msgsz, abi_long msgtyp,
                   2787:                                  int msgflg)
                   2788: {
                   2789:     struct target_msgbuf *target_mb;
                   2790:     char *target_mtext;
                   2791:     struct msgbuf *host_mb;
                   2792:     abi_long ret = 0;
                   2793: 
                   2794:     if (!lock_user_struct(VERIFY_WRITE, target_mb, msgp, 0))
                   2795:         return -TARGET_EFAULT;
                   2796: 
                   2797:     host_mb = malloc(msgsz+sizeof(long));
1.1.1.13  root     2798:     ret = get_errno(msgrcv(msqid, host_mb, msgsz, tswapal(msgtyp), msgflg));
1.1.1.8   root     2799: 
                   2800:     if (ret > 0) {
                   2801:         abi_ulong target_mtext_addr = msgp + sizeof(abi_ulong);
                   2802:         target_mtext = lock_user(VERIFY_WRITE, target_mtext_addr, ret, 0);
                   2803:         if (!target_mtext) {
                   2804:             ret = -TARGET_EFAULT;
                   2805:             goto end;
                   2806:         }
                   2807:         memcpy(target_mb->mtext, host_mb->mtext, ret);
                   2808:         unlock_user(target_mtext, target_mtext_addr, ret);
                   2809:     }
                   2810: 
1.1.1.13  root     2811:     target_mb->mtype = tswapal(host_mb->mtype);
1.1.1.8   root     2812:     free(host_mb);
                   2813: 
                   2814: end:
                   2815:     if (target_mb)
                   2816:         unlock_user_struct(target_mb, msgp, 1);
                   2817:     return ret;
                   2818: }
                   2819: 
                   2820: struct target_shmid_ds
                   2821: {
                   2822:     struct target_ipc_perm shm_perm;
                   2823:     abi_ulong shm_segsz;
                   2824:     abi_ulong shm_atime;
                   2825: #if TARGET_ABI_BITS == 32
                   2826:     abi_ulong __unused1;
                   2827: #endif
                   2828:     abi_ulong shm_dtime;
                   2829: #if TARGET_ABI_BITS == 32
                   2830:     abi_ulong __unused2;
                   2831: #endif
                   2832:     abi_ulong shm_ctime;
                   2833: #if TARGET_ABI_BITS == 32
                   2834:     abi_ulong __unused3;
                   2835: #endif
                   2836:     int shm_cpid;
                   2837:     int shm_lpid;
                   2838:     abi_ulong shm_nattch;
                   2839:     unsigned long int __unused4;
                   2840:     unsigned long int __unused5;
                   2841: };
                   2842: 
                   2843: static inline abi_long target_to_host_shmid_ds(struct shmid_ds *host_sd,
                   2844:                                                abi_ulong target_addr)
                   2845: {
                   2846:     struct target_shmid_ds *target_sd;
                   2847: 
                   2848:     if (!lock_user_struct(VERIFY_READ, target_sd, target_addr, 1))
                   2849:         return -TARGET_EFAULT;
                   2850:     if (target_to_host_ipc_perm(&(host_sd->shm_perm), target_addr))
                   2851:         return -TARGET_EFAULT;
                   2852:     __get_user(host_sd->shm_segsz, &target_sd->shm_segsz);
                   2853:     __get_user(host_sd->shm_atime, &target_sd->shm_atime);
                   2854:     __get_user(host_sd->shm_dtime, &target_sd->shm_dtime);
                   2855:     __get_user(host_sd->shm_ctime, &target_sd->shm_ctime);
                   2856:     __get_user(host_sd->shm_cpid, &target_sd->shm_cpid);
                   2857:     __get_user(host_sd->shm_lpid, &target_sd->shm_lpid);
                   2858:     __get_user(host_sd->shm_nattch, &target_sd->shm_nattch);
                   2859:     unlock_user_struct(target_sd, target_addr, 0);
                   2860:     return 0;
                   2861: }
                   2862: 
                   2863: static inline abi_long host_to_target_shmid_ds(abi_ulong target_addr,
                   2864:                                                struct shmid_ds *host_sd)
                   2865: {
                   2866:     struct target_shmid_ds *target_sd;
                   2867: 
                   2868:     if (!lock_user_struct(VERIFY_WRITE, target_sd, target_addr, 0))
                   2869:         return -TARGET_EFAULT;
                   2870:     if (host_to_target_ipc_perm(target_addr, &(host_sd->shm_perm)))
                   2871:         return -TARGET_EFAULT;
                   2872:     __put_user(host_sd->shm_segsz, &target_sd->shm_segsz);
                   2873:     __put_user(host_sd->shm_atime, &target_sd->shm_atime);
                   2874:     __put_user(host_sd->shm_dtime, &target_sd->shm_dtime);
                   2875:     __put_user(host_sd->shm_ctime, &target_sd->shm_ctime);
                   2876:     __put_user(host_sd->shm_cpid, &target_sd->shm_cpid);
                   2877:     __put_user(host_sd->shm_lpid, &target_sd->shm_lpid);
                   2878:     __put_user(host_sd->shm_nattch, &target_sd->shm_nattch);
                   2879:     unlock_user_struct(target_sd, target_addr, 1);
                   2880:     return 0;
                   2881: }
                   2882: 
                   2883: struct  target_shminfo {
                   2884:     abi_ulong shmmax;
                   2885:     abi_ulong shmmin;
                   2886:     abi_ulong shmmni;
                   2887:     abi_ulong shmseg;
                   2888:     abi_ulong shmall;
                   2889: };
                   2890: 
                   2891: static inline abi_long host_to_target_shminfo(abi_ulong target_addr,
                   2892:                                               struct shminfo *host_shminfo)
                   2893: {
                   2894:     struct target_shminfo *target_shminfo;
                   2895:     if (!lock_user_struct(VERIFY_WRITE, target_shminfo, target_addr, 0))
                   2896:         return -TARGET_EFAULT;
                   2897:     __put_user(host_shminfo->shmmax, &target_shminfo->shmmax);
                   2898:     __put_user(host_shminfo->shmmin, &target_shminfo->shmmin);
                   2899:     __put_user(host_shminfo->shmmni, &target_shminfo->shmmni);
                   2900:     __put_user(host_shminfo->shmseg, &target_shminfo->shmseg);
                   2901:     __put_user(host_shminfo->shmall, &target_shminfo->shmall);
                   2902:     unlock_user_struct(target_shminfo, target_addr, 1);
                   2903:     return 0;
                   2904: }
                   2905: 
                   2906: struct target_shm_info {
                   2907:     int used_ids;
                   2908:     abi_ulong shm_tot;
                   2909:     abi_ulong shm_rss;
                   2910:     abi_ulong shm_swp;
                   2911:     abi_ulong swap_attempts;
                   2912:     abi_ulong swap_successes;
                   2913: };
                   2914: 
                   2915: static inline abi_long host_to_target_shm_info(abi_ulong target_addr,
                   2916:                                                struct shm_info *host_shm_info)
1.1.1.7   root     2917: {
1.1.1.8   root     2918:     struct target_shm_info *target_shm_info;
                   2919:     if (!lock_user_struct(VERIFY_WRITE, target_shm_info, target_addr, 0))
1.1.1.7   root     2920:         return -TARGET_EFAULT;
1.1.1.8   root     2921:     __put_user(host_shm_info->used_ids, &target_shm_info->used_ids);
                   2922:     __put_user(host_shm_info->shm_tot, &target_shm_info->shm_tot);
                   2923:     __put_user(host_shm_info->shm_rss, &target_shm_info->shm_rss);
                   2924:     __put_user(host_shm_info->shm_swp, &target_shm_info->shm_swp);
                   2925:     __put_user(host_shm_info->swap_attempts, &target_shm_info->swap_attempts);
                   2926:     __put_user(host_shm_info->swap_successes, &target_shm_info->swap_successes);
                   2927:     unlock_user_struct(target_shm_info, target_addr, 1);
1.1.1.7   root     2928:     return 0;
                   2929: }
                   2930: 
1.1.1.8   root     2931: static inline abi_long do_shmctl(int shmid, int cmd, abi_long buf)
1.1.1.6   root     2932: {
1.1.1.8   root     2933:     struct shmid_ds dsarg;
                   2934:     struct shminfo shminfo;
                   2935:     struct shm_info shm_info;
1.1.1.7   root     2936:     abi_long ret = -TARGET_EINVAL;
                   2937: 
                   2938:     cmd &= 0xff;
                   2939: 
1.1.1.8   root     2940:     switch(cmd) {
1.1.1.6   root     2941:     case IPC_STAT:
                   2942:     case IPC_SET:
1.1.1.8   root     2943:     case SHM_STAT:
                   2944:         if (target_to_host_shmid_ds(&dsarg, buf))
1.1.1.7   root     2945:             return -TARGET_EFAULT;
1.1.1.8   root     2946:         ret = get_errno(shmctl(shmid, cmd, &dsarg));
                   2947:         if (host_to_target_shmid_ds(buf, &dsarg))
1.1.1.7   root     2948:             return -TARGET_EFAULT;
                   2949:         break;
                   2950:     case IPC_INFO:
1.1.1.8   root     2951:         ret = get_errno(shmctl(shmid, cmd, (struct shmid_ds *)&shminfo));
                   2952:         if (host_to_target_shminfo(buf, &shminfo))
1.1.1.7   root     2953:             return -TARGET_EFAULT;
                   2954:         break;
1.1.1.8   root     2955:     case SHM_INFO:
                   2956:         ret = get_errno(shmctl(shmid, cmd, (struct shmid_ds *)&shm_info));
                   2957:         if (host_to_target_shm_info(buf, &shm_info))
                   2958:             return -TARGET_EFAULT;
                   2959:         break;
                   2960:     case IPC_RMID:
                   2961:     case SHM_LOCK:
                   2962:     case SHM_UNLOCK:
                   2963:         ret = get_errno(shmctl(shmid, cmd, NULL));
                   2964:         break;
1.1.1.6   root     2965:     }
1.1.1.7   root     2966: 
1.1.1.6   root     2967:     return ret;
                   2968: }
                   2969: 
1.1.1.8   root     2970: static inline abi_ulong do_shmat(int shmid, abi_ulong shmaddr, int shmflg)
1.1.1.6   root     2971: {
1.1.1.8   root     2972:     abi_long raddr;
                   2973:     void *host_raddr;
                   2974:     struct shmid_ds shm_info;
                   2975:     int i,ret;
1.1.1.6   root     2976: 
1.1.1.8   root     2977:     /* find out the length of the shared memory segment */
                   2978:     ret = get_errno(shmctl(shmid, IPC_STAT, &shm_info));
                   2979:     if (is_error(ret)) {
                   2980:         /* can't get length, bail out */
                   2981:         return ret;
                   2982:     }
1.1.1.6   root     2983: 
1.1.1.8   root     2984:     mmap_lock();
1.1.1.6   root     2985: 
1.1.1.8   root     2986:     if (shmaddr)
                   2987:         host_raddr = shmat(shmid, (void *)g2h(shmaddr), shmflg);
                   2988:     else {
                   2989:         abi_ulong mmap_start;
1.1.1.6   root     2990: 
1.1.1.8   root     2991:         mmap_start = mmap_find_vma(0, shm_info.shm_segsz);
1.1.1.7   root     2992: 
1.1.1.8   root     2993:         if (mmap_start == -1) {
                   2994:             errno = ENOMEM;
                   2995:             host_raddr = (void *)-1;
                   2996:         } else
                   2997:             host_raddr = shmat(shmid, g2h(mmap_start), shmflg | SHM_REMAP);
                   2998:     }
1.1.1.7   root     2999: 
1.1.1.8   root     3000:     if (host_raddr == (void *)-1) {
                   3001:         mmap_unlock();
                   3002:         return get_errno((long)host_raddr);
                   3003:     }
                   3004:     raddr=h2g((unsigned long)host_raddr);
                   3005: 
                   3006:     page_set_flags(raddr, raddr + shm_info.shm_segsz,
                   3007:                    PAGE_VALID | PAGE_READ |
                   3008:                    ((shmflg & SHM_RDONLY)? 0 : PAGE_WRITE));
                   3009: 
                   3010:     for (i = 0; i < N_SHM_REGIONS; i++) {
                   3011:         if (shm_regions[i].start == 0) {
                   3012:             shm_regions[i].start = raddr;
                   3013:             shm_regions[i].size = shm_info.shm_segsz;
                   3014:             break;
1.1.1.6   root     3015:         }
                   3016:     }
1.1.1.7   root     3017: 
1.1.1.8   root     3018:     mmap_unlock();
                   3019:     return raddr;
1.1.1.6   root     3020: 
1.1.1.8   root     3021: }
                   3022: 
                   3023: static inline abi_long do_shmdt(abi_ulong shmaddr)
                   3024: {
                   3025:     int i;
                   3026: 
                   3027:     for (i = 0; i < N_SHM_REGIONS; ++i) {
                   3028:         if (shm_regions[i].start == shmaddr) {
                   3029:             shm_regions[i].start = 0;
1.1.1.10  root     3030:             page_set_flags(shmaddr, shmaddr + shm_regions[i].size, 0);
1.1.1.8   root     3031:             break;
                   3032:         }
                   3033:     }
                   3034: 
                   3035:     return get_errno(shmdt(g2h(shmaddr)));
1.1.1.6   root     3036: }
                   3037: 
1.1.1.7   root     3038: #ifdef TARGET_NR_ipc
1.1.1.3   root     3039: /* ??? This only works with linear mappings.  */
1.1.1.6   root     3040: /* do_ipc() must return target values and target errnos. */
                   3041: static abi_long do_ipc(unsigned int call, int first,
                   3042:                        int second, int third,
                   3043:                        abi_long ptr, abi_long fifth)
1.1       root     3044: {
                   3045:     int version;
1.1.1.6   root     3046:     abi_long ret = 0;
1.1       root     3047: 
                   3048:     version = call >> 16;
                   3049:     call &= 0xffff;
                   3050: 
                   3051:     switch (call) {
1.1.1.5   root     3052:     case IPCOP_semop:
1.1.1.8   root     3053:         ret = do_semop(first, ptr, second);
1.1.1.5   root     3054:         break;
                   3055: 
                   3056:     case IPCOP_semget:
                   3057:         ret = get_errno(semget(first, second, third));
                   3058:         break;
                   3059: 
                   3060:     case IPCOP_semctl:
1.1.1.8   root     3061:         ret = do_semctl(first, second, third, (union target_semun)(abi_ulong) ptr);
1.1.1.5   root     3062:         break;
                   3063: 
1.1.1.7   root     3064:     case IPCOP_msgget:
                   3065:         ret = get_errno(msgget(first, second));
                   3066:         break;
1.1.1.5   root     3067: 
1.1.1.7   root     3068:     case IPCOP_msgsnd:
                   3069:         ret = do_msgsnd(first, ptr, second, third);
                   3070:         break;
1.1.1.5   root     3071: 
1.1.1.7   root     3072:     case IPCOP_msgctl:
                   3073:         ret = do_msgctl(first, second, ptr);
                   3074:         break;
1.1.1.5   root     3075: 
1.1.1.7   root     3076:     case IPCOP_msgrcv:
                   3077:         switch (version) {
                   3078:         case 0:
                   3079:             {
                   3080:                 struct target_ipc_kludge {
                   3081:                     abi_long msgp;
                   3082:                     abi_long msgtyp;
                   3083:                 } *tmp;
1.1.1.5   root     3084: 
1.1.1.7   root     3085:                 if (!lock_user_struct(VERIFY_READ, tmp, ptr, 1)) {
                   3086:                     ret = -TARGET_EFAULT;
                   3087:                     break;
                   3088:                 }
1.1.1.5   root     3089: 
1.1.1.7   root     3090:                 ret = do_msgrcv(first, tmp->msgp, second, tmp->msgtyp, third);
1.1.1.5   root     3091: 
1.1.1.7   root     3092:                 unlock_user_struct(tmp, ptr, 0);
                   3093:                 break;
                   3094:             }
                   3095:         default:
                   3096:             ret = do_msgrcv(first, ptr, second, fifth, third);
                   3097:         }
                   3098:         break;
1.1.1.5   root     3099: 
1.1       root     3100:     case IPCOP_shmat:
1.1.1.8   root     3101:         switch (version) {
                   3102:         default:
1.1.1.6   root     3103:         {
                   3104:             abi_ulong raddr;
1.1.1.8   root     3105:             raddr = do_shmat(first, ptr, second);
                   3106:             if (is_error(raddr))
                   3107:                 return get_errno(raddr);
1.1.1.6   root     3108:             if (put_user_ual(raddr, third))
                   3109:                 return -TARGET_EFAULT;
1.1.1.8   root     3110:             break;
                   3111:         }
                   3112:         case 1:
                   3113:             ret = -TARGET_EINVAL;
                   3114:             break;
1.1.1.6   root     3115:         }
1.1       root     3116:        break;
                   3117:     case IPCOP_shmdt:
1.1.1.8   root     3118:         ret = do_shmdt(ptr);
1.1       root     3119:        break;
                   3120: 
                   3121:     case IPCOP_shmget:
                   3122:        /* IPC_* flag values are the same on all linux platforms */
                   3123:        ret = get_errno(shmget(first, second, third));
                   3124:        break;
                   3125: 
                   3126:        /* IPC_* and SHM_* command values are the same on all linux platforms */
                   3127:     case IPCOP_shmctl:
1.1.1.8   root     3128:         ret = do_shmctl(first, second, third);
1.1       root     3129:         break;
                   3130:     default:
1.1.1.6   root     3131:        gemu_log("Unsupported ipc call: %d (version %d)\n", call, version);
                   3132:        ret = -TARGET_ENOSYS;
1.1       root     3133:        break;
                   3134:     }
                   3135:     return ret;
                   3136: }
1.1.1.6   root     3137: #endif
1.1       root     3138: 
                   3139: /* kernel structure types definitions */
                   3140: 
1.1.1.8   root     3141: #define STRUCT(name, ...) STRUCT_ ## name,
1.1       root     3142: #define STRUCT_SPECIAL(name) STRUCT_ ## name,
                   3143: enum {
                   3144: #include "syscall_types.h"
                   3145: };
                   3146: #undef STRUCT
                   3147: #undef STRUCT_SPECIAL
                   3148: 
1.1.1.8   root     3149: #define STRUCT(name, ...) static const argtype struct_ ## name ## _def[] = {  __VA_ARGS__, TYPE_NULL };
1.1       root     3150: #define STRUCT_SPECIAL(name)
                   3151: #include "syscall_types.h"
                   3152: #undef STRUCT
                   3153: #undef STRUCT_SPECIAL
                   3154: 
1.1.1.11  root     3155: typedef struct IOCTLEntry IOCTLEntry;
                   3156: 
                   3157: typedef abi_long do_ioctl_fn(const IOCTLEntry *ie, uint8_t *buf_temp,
                   3158:                              int fd, abi_long cmd, abi_long arg);
                   3159: 
                   3160: struct IOCTLEntry {
1.1       root     3161:     unsigned int target_cmd;
                   3162:     unsigned int host_cmd;
                   3163:     const char *name;
                   3164:     int access;
1.1.1.11  root     3165:     do_ioctl_fn *do_ioctl;
1.1       root     3166:     const argtype arg_type[5];
1.1.1.11  root     3167: };
1.1       root     3168: 
                   3169: #define IOC_R 0x0001
                   3170: #define IOC_W 0x0002
                   3171: #define IOC_RW (IOC_R | IOC_W)
                   3172: 
                   3173: #define MAX_STRUCT_SIZE 4096
                   3174: 
1.1.1.11  root     3175: #ifdef CONFIG_FIEMAP
                   3176: /* So fiemap access checks don't overflow on 32 bit systems.
                   3177:  * This is very slightly smaller than the limit imposed by
                   3178:  * the underlying kernel.
                   3179:  */
                   3180: #define FIEMAP_MAX_EXTENTS ((UINT_MAX - sizeof(struct fiemap))  \
                   3181:                             / sizeof(struct fiemap_extent))
                   3182: 
                   3183: static abi_long do_ioctl_fs_ioc_fiemap(const IOCTLEntry *ie, uint8_t *buf_temp,
                   3184:                                        int fd, abi_long cmd, abi_long arg)
                   3185: {
                   3186:     /* The parameter for this ioctl is a struct fiemap followed
                   3187:      * by an array of struct fiemap_extent whose size is set
                   3188:      * in fiemap->fm_extent_count. The array is filled in by the
                   3189:      * ioctl.
                   3190:      */
                   3191:     int target_size_in, target_size_out;
                   3192:     struct fiemap *fm;
                   3193:     const argtype *arg_type = ie->arg_type;
                   3194:     const argtype extent_arg_type[] = { MK_STRUCT(STRUCT_fiemap_extent) };
                   3195:     void *argptr, *p;
                   3196:     abi_long ret;
                   3197:     int i, extent_size = thunk_type_size(extent_arg_type, 0);
                   3198:     uint32_t outbufsz;
                   3199:     int free_fm = 0;
                   3200: 
                   3201:     assert(arg_type[0] == TYPE_PTR);
                   3202:     assert(ie->access == IOC_RW);
                   3203:     arg_type++;
                   3204:     target_size_in = thunk_type_size(arg_type, 0);
                   3205:     argptr = lock_user(VERIFY_READ, arg, target_size_in, 1);
                   3206:     if (!argptr) {
                   3207:         return -TARGET_EFAULT;
                   3208:     }
                   3209:     thunk_convert(buf_temp, argptr, arg_type, THUNK_HOST);
                   3210:     unlock_user(argptr, arg, 0);
                   3211:     fm = (struct fiemap *)buf_temp;
                   3212:     if (fm->fm_extent_count > FIEMAP_MAX_EXTENTS) {
                   3213:         return -TARGET_EINVAL;
                   3214:     }
                   3215: 
                   3216:     outbufsz = sizeof (*fm) +
                   3217:         (sizeof(struct fiemap_extent) * fm->fm_extent_count);
                   3218: 
                   3219:     if (outbufsz > MAX_STRUCT_SIZE) {
                   3220:         /* We can't fit all the extents into the fixed size buffer.
                   3221:          * Allocate one that is large enough and use it instead.
                   3222:          */
                   3223:         fm = malloc(outbufsz);
                   3224:         if (!fm) {
                   3225:             return -TARGET_ENOMEM;
                   3226:         }
                   3227:         memcpy(fm, buf_temp, sizeof(struct fiemap));
                   3228:         free_fm = 1;
                   3229:     }
                   3230:     ret = get_errno(ioctl(fd, ie->host_cmd, fm));
                   3231:     if (!is_error(ret)) {
                   3232:         target_size_out = target_size_in;
                   3233:         /* An extent_count of 0 means we were only counting the extents
                   3234:          * so there are no structs to copy
                   3235:          */
                   3236:         if (fm->fm_extent_count != 0) {
                   3237:             target_size_out += fm->fm_mapped_extents * extent_size;
                   3238:         }
                   3239:         argptr = lock_user(VERIFY_WRITE, arg, target_size_out, 0);
                   3240:         if (!argptr) {
                   3241:             ret = -TARGET_EFAULT;
                   3242:         } else {
                   3243:             /* Convert the struct fiemap */
                   3244:             thunk_convert(argptr, fm, arg_type, THUNK_TARGET);
                   3245:             if (fm->fm_extent_count != 0) {
                   3246:                 p = argptr + target_size_in;
                   3247:                 /* ...and then all the struct fiemap_extents */
                   3248:                 for (i = 0; i < fm->fm_mapped_extents; i++) {
                   3249:                     thunk_convert(p, &fm->fm_extents[i], extent_arg_type,
                   3250:                                   THUNK_TARGET);
                   3251:                     p += extent_size;
                   3252:                 }
                   3253:             }
                   3254:             unlock_user(argptr, arg, target_size_out);
                   3255:         }
                   3256:     }
                   3257:     if (free_fm) {
                   3258:         free(fm);
                   3259:     }
                   3260:     return ret;
                   3261: }
                   3262: #endif
                   3263: 
1.1.1.12  root     3264: static abi_long do_ioctl_ifconf(const IOCTLEntry *ie, uint8_t *buf_temp,
                   3265:                                 int fd, abi_long cmd, abi_long arg)
                   3266: {
                   3267:     const argtype *arg_type = ie->arg_type;
                   3268:     int target_size;
                   3269:     void *argptr;
                   3270:     int ret;
                   3271:     struct ifconf *host_ifconf;
                   3272:     uint32_t outbufsz;
                   3273:     const argtype ifreq_arg_type[] = { MK_STRUCT(STRUCT_sockaddr_ifreq) };
                   3274:     int target_ifreq_size;
                   3275:     int nb_ifreq;
                   3276:     int free_buf = 0;
                   3277:     int i;
                   3278:     int target_ifc_len;
                   3279:     abi_long target_ifc_buf;
                   3280:     int host_ifc_len;
                   3281:     char *host_ifc_buf;
                   3282: 
                   3283:     assert(arg_type[0] == TYPE_PTR);
                   3284:     assert(ie->access == IOC_RW);
                   3285: 
                   3286:     arg_type++;
                   3287:     target_size = thunk_type_size(arg_type, 0);
                   3288: 
                   3289:     argptr = lock_user(VERIFY_READ, arg, target_size, 1);
                   3290:     if (!argptr)
                   3291:         return -TARGET_EFAULT;
                   3292:     thunk_convert(buf_temp, argptr, arg_type, THUNK_HOST);
                   3293:     unlock_user(argptr, arg, 0);
                   3294: 
                   3295:     host_ifconf = (struct ifconf *)(unsigned long)buf_temp;
                   3296:     target_ifc_len = host_ifconf->ifc_len;
                   3297:     target_ifc_buf = (abi_long)(unsigned long)host_ifconf->ifc_buf;
                   3298: 
                   3299:     target_ifreq_size = thunk_type_size(ifreq_arg_type, 0);
                   3300:     nb_ifreq = target_ifc_len / target_ifreq_size;
                   3301:     host_ifc_len = nb_ifreq * sizeof(struct ifreq);
                   3302: 
                   3303:     outbufsz = sizeof(*host_ifconf) + host_ifc_len;
                   3304:     if (outbufsz > MAX_STRUCT_SIZE) {
                   3305:         /* We can't fit all the extents into the fixed size buffer.
                   3306:          * Allocate one that is large enough and use it instead.
                   3307:          */
                   3308:         host_ifconf = malloc(outbufsz);
                   3309:         if (!host_ifconf) {
                   3310:             return -TARGET_ENOMEM;
                   3311:         }
                   3312:         memcpy(host_ifconf, buf_temp, sizeof(*host_ifconf));
                   3313:         free_buf = 1;
                   3314:     }
                   3315:     host_ifc_buf = (char*)host_ifconf + sizeof(*host_ifconf);
                   3316: 
                   3317:     host_ifconf->ifc_len = host_ifc_len;
                   3318:     host_ifconf->ifc_buf = host_ifc_buf;
                   3319: 
                   3320:     ret = get_errno(ioctl(fd, ie->host_cmd, host_ifconf));
                   3321:     if (!is_error(ret)) {
                   3322:        /* convert host ifc_len to target ifc_len */
                   3323: 
                   3324:         nb_ifreq = host_ifconf->ifc_len / sizeof(struct ifreq);
                   3325:         target_ifc_len = nb_ifreq * target_ifreq_size;
                   3326:         host_ifconf->ifc_len = target_ifc_len;
                   3327: 
                   3328:        /* restore target ifc_buf */
                   3329: 
                   3330:         host_ifconf->ifc_buf = (char *)(unsigned long)target_ifc_buf;
                   3331: 
                   3332:        /* copy struct ifconf to target user */
                   3333: 
                   3334:         argptr = lock_user(VERIFY_WRITE, arg, target_size, 0);
                   3335:         if (!argptr)
                   3336:             return -TARGET_EFAULT;
                   3337:         thunk_convert(argptr, host_ifconf, arg_type, THUNK_TARGET);
                   3338:         unlock_user(argptr, arg, target_size);
                   3339: 
                   3340:        /* copy ifreq[] to target user */
                   3341: 
                   3342:         argptr = lock_user(VERIFY_WRITE, target_ifc_buf, target_ifc_len, 0);
                   3343:         for (i = 0; i < nb_ifreq ; i++) {
                   3344:             thunk_convert(argptr + i * target_ifreq_size,
                   3345:                           host_ifc_buf + i * sizeof(struct ifreq),
                   3346:                           ifreq_arg_type, THUNK_TARGET);
                   3347:         }
                   3348:         unlock_user(argptr, target_ifc_buf, target_ifc_len);
                   3349:     }
                   3350: 
                   3351:     if (free_buf) {
                   3352:         free(host_ifconf);
                   3353:     }
                   3354: 
                   3355:     return ret;
                   3356: }
                   3357: 
1.1.1.14! root     3358: static abi_long do_ioctl_dm(const IOCTLEntry *ie, uint8_t *buf_temp, int fd,
        !          3359:                             abi_long cmd, abi_long arg)
        !          3360: {
        !          3361:     void *argptr;
        !          3362:     struct dm_ioctl *host_dm;
        !          3363:     abi_long guest_data;
        !          3364:     uint32_t guest_data_size;
        !          3365:     int target_size;
        !          3366:     const argtype *arg_type = ie->arg_type;
        !          3367:     abi_long ret;
        !          3368:     void *big_buf = NULL;
        !          3369:     char *host_data;
        !          3370: 
        !          3371:     arg_type++;
        !          3372:     target_size = thunk_type_size(arg_type, 0);
        !          3373:     argptr = lock_user(VERIFY_READ, arg, target_size, 1);
        !          3374:     if (!argptr) {
        !          3375:         ret = -TARGET_EFAULT;
        !          3376:         goto out;
        !          3377:     }
        !          3378:     thunk_convert(buf_temp, argptr, arg_type, THUNK_HOST);
        !          3379:     unlock_user(argptr, arg, 0);
        !          3380: 
        !          3381:     /* buf_temp is too small, so fetch things into a bigger buffer */
        !          3382:     big_buf = g_malloc0(((struct dm_ioctl*)buf_temp)->data_size * 2);
        !          3383:     memcpy(big_buf, buf_temp, target_size);
        !          3384:     buf_temp = big_buf;
        !          3385:     host_dm = big_buf;
        !          3386: 
        !          3387:     guest_data = arg + host_dm->data_start;
        !          3388:     if ((guest_data - arg) < 0) {
        !          3389:         ret = -EINVAL;
        !          3390:         goto out;
        !          3391:     }
        !          3392:     guest_data_size = host_dm->data_size - host_dm->data_start;
        !          3393:     host_data = (char*)host_dm + host_dm->data_start;
        !          3394: 
        !          3395:     argptr = lock_user(VERIFY_READ, guest_data, guest_data_size, 1);
        !          3396:     switch (ie->host_cmd) {
        !          3397:     case DM_REMOVE_ALL:
        !          3398:     case DM_LIST_DEVICES:
        !          3399:     case DM_DEV_CREATE:
        !          3400:     case DM_DEV_REMOVE:
        !          3401:     case DM_DEV_SUSPEND:
        !          3402:     case DM_DEV_STATUS:
        !          3403:     case DM_DEV_WAIT:
        !          3404:     case DM_TABLE_STATUS:
        !          3405:     case DM_TABLE_CLEAR:
        !          3406:     case DM_TABLE_DEPS:
        !          3407:     case DM_LIST_VERSIONS:
        !          3408:         /* no input data */
        !          3409:         break;
        !          3410:     case DM_DEV_RENAME:
        !          3411:     case DM_DEV_SET_GEOMETRY:
        !          3412:         /* data contains only strings */
        !          3413:         memcpy(host_data, argptr, guest_data_size);
        !          3414:         break;
        !          3415:     case DM_TARGET_MSG:
        !          3416:         memcpy(host_data, argptr, guest_data_size);
        !          3417:         *(uint64_t*)host_data = tswap64(*(uint64_t*)argptr);
        !          3418:         break;
        !          3419:     case DM_TABLE_LOAD:
        !          3420:     {
        !          3421:         void *gspec = argptr;
        !          3422:         void *cur_data = host_data;
        !          3423:         const argtype arg_type[] = { MK_STRUCT(STRUCT_dm_target_spec) };
        !          3424:         int spec_size = thunk_type_size(arg_type, 0);
        !          3425:         int i;
        !          3426: 
        !          3427:         for (i = 0; i < host_dm->target_count; i++) {
        !          3428:             struct dm_target_spec *spec = cur_data;
        !          3429:             uint32_t next;
        !          3430:             int slen;
        !          3431: 
        !          3432:             thunk_convert(spec, gspec, arg_type, THUNK_HOST);
        !          3433:             slen = strlen((char*)gspec + spec_size) + 1;
        !          3434:             next = spec->next;
        !          3435:             spec->next = sizeof(*spec) + slen;
        !          3436:             strcpy((char*)&spec[1], gspec + spec_size);
        !          3437:             gspec += next;
        !          3438:             cur_data += spec->next;
        !          3439:         }
        !          3440:         break;
        !          3441:     }
        !          3442:     default:
        !          3443:         ret = -TARGET_EINVAL;
        !          3444:         goto out;
        !          3445:     }
        !          3446:     unlock_user(argptr, guest_data, 0);
        !          3447: 
        !          3448:     ret = get_errno(ioctl(fd, ie->host_cmd, buf_temp));
        !          3449:     if (!is_error(ret)) {
        !          3450:         guest_data = arg + host_dm->data_start;
        !          3451:         guest_data_size = host_dm->data_size - host_dm->data_start;
        !          3452:         argptr = lock_user(VERIFY_WRITE, guest_data, guest_data_size, 0);
        !          3453:         switch (ie->host_cmd) {
        !          3454:         case DM_REMOVE_ALL:
        !          3455:         case DM_DEV_CREATE:
        !          3456:         case DM_DEV_REMOVE:
        !          3457:         case DM_DEV_RENAME:
        !          3458:         case DM_DEV_SUSPEND:
        !          3459:         case DM_DEV_STATUS:
        !          3460:         case DM_TABLE_LOAD:
        !          3461:         case DM_TABLE_CLEAR:
        !          3462:         case DM_TARGET_MSG:
        !          3463:         case DM_DEV_SET_GEOMETRY:
        !          3464:             /* no return data */
        !          3465:             break;
        !          3466:         case DM_LIST_DEVICES:
        !          3467:         {
        !          3468:             struct dm_name_list *nl = (void*)host_dm + host_dm->data_start;
        !          3469:             uint32_t remaining_data = guest_data_size;
        !          3470:             void *cur_data = argptr;
        !          3471:             const argtype arg_type[] = { MK_STRUCT(STRUCT_dm_name_list) };
        !          3472:             int nl_size = 12; /* can't use thunk_size due to alignment */
        !          3473: 
        !          3474:             while (1) {
        !          3475:                 uint32_t next = nl->next;
        !          3476:                 if (next) {
        !          3477:                     nl->next = nl_size + (strlen(nl->name) + 1);
        !          3478:                 }
        !          3479:                 if (remaining_data < nl->next) {
        !          3480:                     host_dm->flags |= DM_BUFFER_FULL_FLAG;
        !          3481:                     break;
        !          3482:                 }
        !          3483:                 thunk_convert(cur_data, nl, arg_type, THUNK_TARGET);
        !          3484:                 strcpy(cur_data + nl_size, nl->name);
        !          3485:                 cur_data += nl->next;
        !          3486:                 remaining_data -= nl->next;
        !          3487:                 if (!next) {
        !          3488:                     break;
        !          3489:                 }
        !          3490:                 nl = (void*)nl + next;
        !          3491:             }
        !          3492:             break;
        !          3493:         }
        !          3494:         case DM_DEV_WAIT:
        !          3495:         case DM_TABLE_STATUS:
        !          3496:         {
        !          3497:             struct dm_target_spec *spec = (void*)host_dm + host_dm->data_start;
        !          3498:             void *cur_data = argptr;
        !          3499:             const argtype arg_type[] = { MK_STRUCT(STRUCT_dm_target_spec) };
        !          3500:             int spec_size = thunk_type_size(arg_type, 0);
        !          3501:             int i;
        !          3502: 
        !          3503:             for (i = 0; i < host_dm->target_count; i++) {
        !          3504:                 uint32_t next = spec->next;
        !          3505:                 int slen = strlen((char*)&spec[1]) + 1;
        !          3506:                 spec->next = (cur_data - argptr) + spec_size + slen;
        !          3507:                 if (guest_data_size < spec->next) {
        !          3508:                     host_dm->flags |= DM_BUFFER_FULL_FLAG;
        !          3509:                     break;
        !          3510:                 }
        !          3511:                 thunk_convert(cur_data, spec, arg_type, THUNK_TARGET);
        !          3512:                 strcpy(cur_data + spec_size, (char*)&spec[1]);
        !          3513:                 cur_data = argptr + spec->next;
        !          3514:                 spec = (void*)host_dm + host_dm->data_start + next;
        !          3515:             }
        !          3516:             break;
        !          3517:         }
        !          3518:         case DM_TABLE_DEPS:
        !          3519:         {
        !          3520:             void *hdata = (void*)host_dm + host_dm->data_start;
        !          3521:             int count = *(uint32_t*)hdata;
        !          3522:             uint64_t *hdev = hdata + 8;
        !          3523:             uint64_t *gdev = argptr + 8;
        !          3524:             int i;
        !          3525: 
        !          3526:             *(uint32_t*)argptr = tswap32(count);
        !          3527:             for (i = 0; i < count; i++) {
        !          3528:                 *gdev = tswap64(*hdev);
        !          3529:                 gdev++;
        !          3530:                 hdev++;
        !          3531:             }
        !          3532:             break;
        !          3533:         }
        !          3534:         case DM_LIST_VERSIONS:
        !          3535:         {
        !          3536:             struct dm_target_versions *vers = (void*)host_dm + host_dm->data_start;
        !          3537:             uint32_t remaining_data = guest_data_size;
        !          3538:             void *cur_data = argptr;
        !          3539:             const argtype arg_type[] = { MK_STRUCT(STRUCT_dm_target_versions) };
        !          3540:             int vers_size = thunk_type_size(arg_type, 0);
        !          3541: 
        !          3542:             while (1) {
        !          3543:                 uint32_t next = vers->next;
        !          3544:                 if (next) {
        !          3545:                     vers->next = vers_size + (strlen(vers->name) + 1);
        !          3546:                 }
        !          3547:                 if (remaining_data < vers->next) {
        !          3548:                     host_dm->flags |= DM_BUFFER_FULL_FLAG;
        !          3549:                     break;
        !          3550:                 }
        !          3551:                 thunk_convert(cur_data, vers, arg_type, THUNK_TARGET);
        !          3552:                 strcpy(cur_data + vers_size, vers->name);
        !          3553:                 cur_data += vers->next;
        !          3554:                 remaining_data -= vers->next;
        !          3555:                 if (!next) {
        !          3556:                     break;
        !          3557:                 }
        !          3558:                 vers = (void*)vers + next;
        !          3559:             }
        !          3560:             break;
        !          3561:         }
        !          3562:         default:
        !          3563:             ret = -TARGET_EINVAL;
        !          3564:             goto out;
        !          3565:         }
        !          3566:         unlock_user(argptr, guest_data, guest_data_size);
        !          3567: 
        !          3568:         argptr = lock_user(VERIFY_WRITE, arg, target_size, 0);
        !          3569:         if (!argptr) {
        !          3570:             ret = -TARGET_EFAULT;
        !          3571:             goto out;
        !          3572:         }
        !          3573:         thunk_convert(argptr, buf_temp, arg_type, THUNK_TARGET);
        !          3574:         unlock_user(argptr, arg, target_size);
        !          3575:     }
        !          3576: out:
        !          3577:     if (big_buf) {
        !          3578:         free(big_buf);
        !          3579:     }
        !          3580:     return ret;
        !          3581: }
        !          3582: 
1.1.1.7   root     3583: static IOCTLEntry ioctl_entries[] = {
1.1.1.8   root     3584: #define IOCTL(cmd, access, ...) \
1.1.1.11  root     3585:     { TARGET_ ## cmd, cmd, #cmd, access, 0, {  __VA_ARGS__ } },
                   3586: #define IOCTL_SPECIAL(cmd, access, dofn, ...)                      \
                   3587:     { TARGET_ ## cmd, cmd, #cmd, access, dofn, {  __VA_ARGS__ } },
1.1       root     3588: #include "ioctls.h"
                   3589:     { 0, 0, },
                   3590: };
                   3591: 
1.1.1.3   root     3592: /* ??? Implement proper locking for ioctls.  */
1.1.1.6   root     3593: /* do_ioctl() Must return target values and target errnos. */
                   3594: static abi_long do_ioctl(int fd, abi_long cmd, abi_long arg)
1.1       root     3595: {
                   3596:     const IOCTLEntry *ie;
                   3597:     const argtype *arg_type;
1.1.1.6   root     3598:     abi_long ret;
1.1       root     3599:     uint8_t buf_temp[MAX_STRUCT_SIZE];
1.1.1.3   root     3600:     int target_size;
                   3601:     void *argptr;
1.1       root     3602: 
                   3603:     ie = ioctl_entries;
                   3604:     for(;;) {
                   3605:         if (ie->target_cmd == 0) {
1.1.1.6   root     3606:             gemu_log("Unsupported ioctl: cmd=0x%04lx\n", (long)cmd);
                   3607:             return -TARGET_ENOSYS;
1.1       root     3608:         }
                   3609:         if (ie->target_cmd == cmd)
                   3610:             break;
                   3611:         ie++;
                   3612:     }
                   3613:     arg_type = ie->arg_type;
                   3614: #if defined(DEBUG)
1.1.1.6   root     3615:     gemu_log("ioctl: cmd=0x%04lx (%s)\n", (long)cmd, ie->name);
1.1       root     3616: #endif
1.1.1.11  root     3617:     if (ie->do_ioctl) {
                   3618:         return ie->do_ioctl(ie, buf_temp, fd, cmd, arg);
                   3619:     }
                   3620: 
1.1       root     3621:     switch(arg_type[0]) {
                   3622:     case TYPE_NULL:
                   3623:         /* no argument */
                   3624:         ret = get_errno(ioctl(fd, ie->host_cmd));
                   3625:         break;
                   3626:     case TYPE_PTRVOID:
                   3627:     case TYPE_INT:
                   3628:         /* int argment */
                   3629:         ret = get_errno(ioctl(fd, ie->host_cmd, arg));
                   3630:         break;
                   3631:     case TYPE_PTR:
                   3632:         arg_type++;
1.1.1.3   root     3633:         target_size = thunk_type_size(arg_type, 0);
1.1       root     3634:         switch(ie->access) {
                   3635:         case IOC_R:
                   3636:             ret = get_errno(ioctl(fd, ie->host_cmd, buf_temp));
                   3637:             if (!is_error(ret)) {
1.1.1.6   root     3638:                 argptr = lock_user(VERIFY_WRITE, arg, target_size, 0);
                   3639:                 if (!argptr)
                   3640:                     return -TARGET_EFAULT;
1.1.1.3   root     3641:                 thunk_convert(argptr, buf_temp, arg_type, THUNK_TARGET);
                   3642:                 unlock_user(argptr, arg, target_size);
1.1       root     3643:             }
                   3644:             break;
                   3645:         case IOC_W:
1.1.1.6   root     3646:             argptr = lock_user(VERIFY_READ, arg, target_size, 1);
                   3647:             if (!argptr)
                   3648:                 return -TARGET_EFAULT;
1.1.1.3   root     3649:             thunk_convert(buf_temp, argptr, arg_type, THUNK_HOST);
                   3650:             unlock_user(argptr, arg, 0);
1.1       root     3651:             ret = get_errno(ioctl(fd, ie->host_cmd, buf_temp));
                   3652:             break;
                   3653:         default:
                   3654:         case IOC_RW:
1.1.1.6   root     3655:             argptr = lock_user(VERIFY_READ, arg, target_size, 1);
                   3656:             if (!argptr)
                   3657:                 return -TARGET_EFAULT;
1.1.1.3   root     3658:             thunk_convert(buf_temp, argptr, arg_type, THUNK_HOST);
                   3659:             unlock_user(argptr, arg, 0);
1.1       root     3660:             ret = get_errno(ioctl(fd, ie->host_cmd, buf_temp));
                   3661:             if (!is_error(ret)) {
1.1.1.6   root     3662:                 argptr = lock_user(VERIFY_WRITE, arg, target_size, 0);
                   3663:                 if (!argptr)
                   3664:                     return -TARGET_EFAULT;
1.1.1.3   root     3665:                 thunk_convert(argptr, buf_temp, arg_type, THUNK_TARGET);
                   3666:                 unlock_user(argptr, arg, target_size);
1.1       root     3667:             }
                   3668:             break;
                   3669:         }
                   3670:         break;
                   3671:     default:
1.1.1.6   root     3672:         gemu_log("Unsupported ioctl type: cmd=0x%04lx type=%d\n",
                   3673:                  (long)cmd, arg_type[0]);
                   3674:         ret = -TARGET_ENOSYS;
1.1       root     3675:         break;
                   3676:     }
                   3677:     return ret;
                   3678: }
                   3679: 
1.1.1.7   root     3680: static const bitmask_transtbl iflag_tbl[] = {
1.1       root     3681:         { TARGET_IGNBRK, TARGET_IGNBRK, IGNBRK, IGNBRK },
                   3682:         { TARGET_BRKINT, TARGET_BRKINT, BRKINT, BRKINT },
                   3683:         { TARGET_IGNPAR, TARGET_IGNPAR, IGNPAR, IGNPAR },
                   3684:         { TARGET_PARMRK, TARGET_PARMRK, PARMRK, PARMRK },
                   3685:         { TARGET_INPCK, TARGET_INPCK, INPCK, INPCK },
                   3686:         { TARGET_ISTRIP, TARGET_ISTRIP, ISTRIP, ISTRIP },
                   3687:         { TARGET_INLCR, TARGET_INLCR, INLCR, INLCR },
                   3688:         { TARGET_IGNCR, TARGET_IGNCR, IGNCR, IGNCR },
                   3689:         { TARGET_ICRNL, TARGET_ICRNL, ICRNL, ICRNL },
                   3690:         { TARGET_IUCLC, TARGET_IUCLC, IUCLC, IUCLC },
                   3691:         { TARGET_IXON, TARGET_IXON, IXON, IXON },
                   3692:         { TARGET_IXANY, TARGET_IXANY, IXANY, IXANY },
                   3693:         { TARGET_IXOFF, TARGET_IXOFF, IXOFF, IXOFF },
                   3694:         { TARGET_IMAXBEL, TARGET_IMAXBEL, IMAXBEL, IMAXBEL },
                   3695:         { 0, 0, 0, 0 }
                   3696: };
                   3697: 
1.1.1.7   root     3698: static const bitmask_transtbl oflag_tbl[] = {
1.1       root     3699:        { TARGET_OPOST, TARGET_OPOST, OPOST, OPOST },
                   3700:        { TARGET_OLCUC, TARGET_OLCUC, OLCUC, OLCUC },
                   3701:        { TARGET_ONLCR, TARGET_ONLCR, ONLCR, ONLCR },
                   3702:        { TARGET_OCRNL, TARGET_OCRNL, OCRNL, OCRNL },
                   3703:        { TARGET_ONOCR, TARGET_ONOCR, ONOCR, ONOCR },
                   3704:        { TARGET_ONLRET, TARGET_ONLRET, ONLRET, ONLRET },
                   3705:        { TARGET_OFILL, TARGET_OFILL, OFILL, OFILL },
                   3706:        { TARGET_OFDEL, TARGET_OFDEL, OFDEL, OFDEL },
                   3707:        { TARGET_NLDLY, TARGET_NL0, NLDLY, NL0 },
                   3708:        { TARGET_NLDLY, TARGET_NL1, NLDLY, NL1 },
                   3709:        { TARGET_CRDLY, TARGET_CR0, CRDLY, CR0 },
                   3710:        { TARGET_CRDLY, TARGET_CR1, CRDLY, CR1 },
                   3711:        { TARGET_CRDLY, TARGET_CR2, CRDLY, CR2 },
                   3712:        { TARGET_CRDLY, TARGET_CR3, CRDLY, CR3 },
                   3713:        { TARGET_TABDLY, TARGET_TAB0, TABDLY, TAB0 },
                   3714:        { TARGET_TABDLY, TARGET_TAB1, TABDLY, TAB1 },
                   3715:        { TARGET_TABDLY, TARGET_TAB2, TABDLY, TAB2 },
                   3716:        { TARGET_TABDLY, TARGET_TAB3, TABDLY, TAB3 },
                   3717:        { TARGET_BSDLY, TARGET_BS0, BSDLY, BS0 },
                   3718:        { TARGET_BSDLY, TARGET_BS1, BSDLY, BS1 },
                   3719:        { TARGET_VTDLY, TARGET_VT0, VTDLY, VT0 },
                   3720:        { TARGET_VTDLY, TARGET_VT1, VTDLY, VT1 },
                   3721:        { TARGET_FFDLY, TARGET_FF0, FFDLY, FF0 },
                   3722:        { TARGET_FFDLY, TARGET_FF1, FFDLY, FF1 },
                   3723:        { 0, 0, 0, 0 }
                   3724: };
                   3725: 
1.1.1.7   root     3726: static const bitmask_transtbl cflag_tbl[] = {
1.1       root     3727:        { TARGET_CBAUD, TARGET_B0, CBAUD, B0 },
                   3728:        { TARGET_CBAUD, TARGET_B50, CBAUD, B50 },
                   3729:        { TARGET_CBAUD, TARGET_B75, CBAUD, B75 },
                   3730:        { TARGET_CBAUD, TARGET_B110, CBAUD, B110 },
                   3731:        { TARGET_CBAUD, TARGET_B134, CBAUD, B134 },
                   3732:        { TARGET_CBAUD, TARGET_B150, CBAUD, B150 },
                   3733:        { TARGET_CBAUD, TARGET_B200, CBAUD, B200 },
                   3734:        { TARGET_CBAUD, TARGET_B300, CBAUD, B300 },
                   3735:        { TARGET_CBAUD, TARGET_B600, CBAUD, B600 },
                   3736:        { TARGET_CBAUD, TARGET_B1200, CBAUD, B1200 },
                   3737:        { TARGET_CBAUD, TARGET_B1800, CBAUD, B1800 },
                   3738:        { TARGET_CBAUD, TARGET_B2400, CBAUD, B2400 },
                   3739:        { TARGET_CBAUD, TARGET_B4800, CBAUD, B4800 },
                   3740:        { TARGET_CBAUD, TARGET_B9600, CBAUD, B9600 },
                   3741:        { TARGET_CBAUD, TARGET_B19200, CBAUD, B19200 },
                   3742:        { TARGET_CBAUD, TARGET_B38400, CBAUD, B38400 },
                   3743:        { TARGET_CBAUD, TARGET_B57600, CBAUD, B57600 },
                   3744:        { TARGET_CBAUD, TARGET_B115200, CBAUD, B115200 },
                   3745:        { TARGET_CBAUD, TARGET_B230400, CBAUD, B230400 },
                   3746:        { TARGET_CBAUD, TARGET_B460800, CBAUD, B460800 },
                   3747:        { TARGET_CSIZE, TARGET_CS5, CSIZE, CS5 },
                   3748:        { TARGET_CSIZE, TARGET_CS6, CSIZE, CS6 },
                   3749:        { TARGET_CSIZE, TARGET_CS7, CSIZE, CS7 },
                   3750:        { TARGET_CSIZE, TARGET_CS8, CSIZE, CS8 },
                   3751:        { TARGET_CSTOPB, TARGET_CSTOPB, CSTOPB, CSTOPB },
                   3752:        { TARGET_CREAD, TARGET_CREAD, CREAD, CREAD },
                   3753:        { TARGET_PARENB, TARGET_PARENB, PARENB, PARENB },
                   3754:        { TARGET_PARODD, TARGET_PARODD, PARODD, PARODD },
                   3755:        { TARGET_HUPCL, TARGET_HUPCL, HUPCL, HUPCL },
                   3756:        { TARGET_CLOCAL, TARGET_CLOCAL, CLOCAL, CLOCAL },
                   3757:        { TARGET_CRTSCTS, TARGET_CRTSCTS, CRTSCTS, CRTSCTS },
                   3758:        { 0, 0, 0, 0 }
                   3759: };
                   3760: 
1.1.1.7   root     3761: static const bitmask_transtbl lflag_tbl[] = {
1.1       root     3762:        { TARGET_ISIG, TARGET_ISIG, ISIG, ISIG },
                   3763:        { TARGET_ICANON, TARGET_ICANON, ICANON, ICANON },
                   3764:        { TARGET_XCASE, TARGET_XCASE, XCASE, XCASE },
                   3765:        { TARGET_ECHO, TARGET_ECHO, ECHO, ECHO },
                   3766:        { TARGET_ECHOE, TARGET_ECHOE, ECHOE, ECHOE },
                   3767:        { TARGET_ECHOK, TARGET_ECHOK, ECHOK, ECHOK },
                   3768:        { TARGET_ECHONL, TARGET_ECHONL, ECHONL, ECHONL },
                   3769:        { TARGET_NOFLSH, TARGET_NOFLSH, NOFLSH, NOFLSH },
                   3770:        { TARGET_TOSTOP, TARGET_TOSTOP, TOSTOP, TOSTOP },
                   3771:        { TARGET_ECHOCTL, TARGET_ECHOCTL, ECHOCTL, ECHOCTL },
                   3772:        { TARGET_ECHOPRT, TARGET_ECHOPRT, ECHOPRT, ECHOPRT },
                   3773:        { TARGET_ECHOKE, TARGET_ECHOKE, ECHOKE, ECHOKE },
                   3774:        { TARGET_FLUSHO, TARGET_FLUSHO, FLUSHO, FLUSHO },
                   3775:        { TARGET_PENDIN, TARGET_PENDIN, PENDIN, PENDIN },
                   3776:        { TARGET_IEXTEN, TARGET_IEXTEN, IEXTEN, IEXTEN },
                   3777:        { 0, 0, 0, 0 }
                   3778: };
                   3779: 
                   3780: static void target_to_host_termios (void *dst, const void *src)
                   3781: {
                   3782:     struct host_termios *host = dst;
                   3783:     const struct target_termios *target = src;
1.1.1.6   root     3784: 
                   3785:     host->c_iflag =
1.1       root     3786:         target_to_host_bitmask(tswap32(target->c_iflag), iflag_tbl);
1.1.1.6   root     3787:     host->c_oflag =
1.1       root     3788:         target_to_host_bitmask(tswap32(target->c_oflag), oflag_tbl);
1.1.1.6   root     3789:     host->c_cflag =
1.1       root     3790:         target_to_host_bitmask(tswap32(target->c_cflag), cflag_tbl);
1.1.1.6   root     3791:     host->c_lflag =
1.1       root     3792:         target_to_host_bitmask(tswap32(target->c_lflag), lflag_tbl);
                   3793:     host->c_line = target->c_line;
1.1.1.6   root     3794: 
1.1.1.8   root     3795:     memset(host->c_cc, 0, sizeof(host->c_cc));
1.1.1.6   root     3796:     host->c_cc[VINTR] = target->c_cc[TARGET_VINTR];
                   3797:     host->c_cc[VQUIT] = target->c_cc[TARGET_VQUIT];
                   3798:     host->c_cc[VERASE] = target->c_cc[TARGET_VERASE];
                   3799:     host->c_cc[VKILL] = target->c_cc[TARGET_VKILL];
                   3800:     host->c_cc[VEOF] = target->c_cc[TARGET_VEOF];
                   3801:     host->c_cc[VTIME] = target->c_cc[TARGET_VTIME];
                   3802:     host->c_cc[VMIN] = target->c_cc[TARGET_VMIN];
                   3803:     host->c_cc[VSWTC] = target->c_cc[TARGET_VSWTC];
                   3804:     host->c_cc[VSTART] = target->c_cc[TARGET_VSTART];
                   3805:     host->c_cc[VSTOP] = target->c_cc[TARGET_VSTOP];
                   3806:     host->c_cc[VSUSP] = target->c_cc[TARGET_VSUSP];
                   3807:     host->c_cc[VEOL] = target->c_cc[TARGET_VEOL];
                   3808:     host->c_cc[VREPRINT] = target->c_cc[TARGET_VREPRINT];
                   3809:     host->c_cc[VDISCARD] = target->c_cc[TARGET_VDISCARD];
                   3810:     host->c_cc[VWERASE] = target->c_cc[TARGET_VWERASE];
                   3811:     host->c_cc[VLNEXT] = target->c_cc[TARGET_VLNEXT];
                   3812:     host->c_cc[VEOL2] = target->c_cc[TARGET_VEOL2];
1.1       root     3813: }
1.1.1.6   root     3814: 
1.1       root     3815: static void host_to_target_termios (void *dst, const void *src)
                   3816: {
                   3817:     struct target_termios *target = dst;
                   3818:     const struct host_termios *host = src;
                   3819: 
1.1.1.6   root     3820:     target->c_iflag =
1.1       root     3821:         tswap32(host_to_target_bitmask(host->c_iflag, iflag_tbl));
1.1.1.6   root     3822:     target->c_oflag =
1.1       root     3823:         tswap32(host_to_target_bitmask(host->c_oflag, oflag_tbl));
1.1.1.6   root     3824:     target->c_cflag =
1.1       root     3825:         tswap32(host_to_target_bitmask(host->c_cflag, cflag_tbl));
1.1.1.6   root     3826:     target->c_lflag =
1.1       root     3827:         tswap32(host_to_target_bitmask(host->c_lflag, lflag_tbl));
                   3828:     target->c_line = host->c_line;
1.1.1.6   root     3829: 
1.1.1.8   root     3830:     memset(target->c_cc, 0, sizeof(target->c_cc));
1.1       root     3831:     target->c_cc[TARGET_VINTR] = host->c_cc[VINTR];
                   3832:     target->c_cc[TARGET_VQUIT] = host->c_cc[VQUIT];
                   3833:     target->c_cc[TARGET_VERASE] = host->c_cc[VERASE];
                   3834:     target->c_cc[TARGET_VKILL] = host->c_cc[VKILL];
                   3835:     target->c_cc[TARGET_VEOF] = host->c_cc[VEOF];
                   3836:     target->c_cc[TARGET_VTIME] = host->c_cc[VTIME];
                   3837:     target->c_cc[TARGET_VMIN] = host->c_cc[VMIN];
                   3838:     target->c_cc[TARGET_VSWTC] = host->c_cc[VSWTC];
                   3839:     target->c_cc[TARGET_VSTART] = host->c_cc[VSTART];
                   3840:     target->c_cc[TARGET_VSTOP] = host->c_cc[VSTOP];
                   3841:     target->c_cc[TARGET_VSUSP] = host->c_cc[VSUSP];
                   3842:     target->c_cc[TARGET_VEOL] = host->c_cc[VEOL];
                   3843:     target->c_cc[TARGET_VREPRINT] = host->c_cc[VREPRINT];
                   3844:     target->c_cc[TARGET_VDISCARD] = host->c_cc[VDISCARD];
                   3845:     target->c_cc[TARGET_VWERASE] = host->c_cc[VWERASE];
                   3846:     target->c_cc[TARGET_VLNEXT] = host->c_cc[VLNEXT];
                   3847:     target->c_cc[TARGET_VEOL2] = host->c_cc[VEOL2];
                   3848: }
                   3849: 
1.1.1.7   root     3850: static const StructEntry struct_termios_def = {
1.1       root     3851:     .convert = { host_to_target_termios, target_to_host_termios },
                   3852:     .size = { sizeof(struct target_termios), sizeof(struct host_termios) },
                   3853:     .align = { __alignof__(struct target_termios), __alignof__(struct host_termios) },
                   3854: };
                   3855: 
                   3856: static bitmask_transtbl mmap_flags_tbl[] = {
                   3857:        { TARGET_MAP_SHARED, TARGET_MAP_SHARED, MAP_SHARED, MAP_SHARED },
                   3858:        { TARGET_MAP_PRIVATE, TARGET_MAP_PRIVATE, MAP_PRIVATE, MAP_PRIVATE },
                   3859:        { TARGET_MAP_FIXED, TARGET_MAP_FIXED, MAP_FIXED, MAP_FIXED },
                   3860:        { TARGET_MAP_ANONYMOUS, TARGET_MAP_ANONYMOUS, MAP_ANONYMOUS, MAP_ANONYMOUS },
                   3861:        { TARGET_MAP_GROWSDOWN, TARGET_MAP_GROWSDOWN, MAP_GROWSDOWN, MAP_GROWSDOWN },
                   3862:        { TARGET_MAP_DENYWRITE, TARGET_MAP_DENYWRITE, MAP_DENYWRITE, MAP_DENYWRITE },
                   3863:        { TARGET_MAP_EXECUTABLE, TARGET_MAP_EXECUTABLE, MAP_EXECUTABLE, MAP_EXECUTABLE },
                   3864:        { TARGET_MAP_LOCKED, TARGET_MAP_LOCKED, MAP_LOCKED, MAP_LOCKED },
                   3865:        { 0, 0, 0, 0 }
                   3866: };
                   3867: 
                   3868: #if defined(TARGET_I386)
                   3869: 
                   3870: /* NOTE: there is really one LDT for all the threads */
1.1.1.7   root     3871: static uint8_t *ldt_table;
1.1       root     3872: 
1.1.1.6   root     3873: static abi_long read_ldt(abi_ulong ptr, unsigned long bytecount)
1.1       root     3874: {
                   3875:     int size;
1.1.1.3   root     3876:     void *p;
1.1       root     3877: 
                   3878:     if (!ldt_table)
                   3879:         return 0;
                   3880:     size = TARGET_LDT_ENTRIES * TARGET_LDT_ENTRY_SIZE;
                   3881:     if (size > bytecount)
                   3882:         size = bytecount;
1.1.1.6   root     3883:     p = lock_user(VERIFY_WRITE, ptr, size, 0);
                   3884:     if (!p)
                   3885:         return -TARGET_EFAULT;
                   3886:     /* ??? Should this by byteswapped?  */
1.1.1.3   root     3887:     memcpy(p, ldt_table, size);
                   3888:     unlock_user(p, ptr, size);
1.1       root     3889:     return size;
                   3890: }
                   3891: 
                   3892: /* XXX: add locking support */
1.1.1.6   root     3893: static abi_long write_ldt(CPUX86State *env,
                   3894:                           abi_ulong ptr, unsigned long bytecount, int oldmode)
1.1       root     3895: {
                   3896:     struct target_modify_ldt_ldt_s ldt_info;
1.1.1.3   root     3897:     struct target_modify_ldt_ldt_s *target_ldt_info;
1.1       root     3898:     int seg_32bit, contents, read_exec_only, limit_in_pages;
1.1.1.6   root     3899:     int seg_not_present, useable, lm;
1.1       root     3900:     uint32_t *lp, entry_1, entry_2;
                   3901: 
                   3902:     if (bytecount != sizeof(ldt_info))
1.1.1.6   root     3903:         return -TARGET_EINVAL;
                   3904:     if (!lock_user_struct(VERIFY_READ, target_ldt_info, ptr, 1))
                   3905:         return -TARGET_EFAULT;
1.1.1.3   root     3906:     ldt_info.entry_number = tswap32(target_ldt_info->entry_number);
1.1.1.13  root     3907:     ldt_info.base_addr = tswapal(target_ldt_info->base_addr);
1.1.1.3   root     3908:     ldt_info.limit = tswap32(target_ldt_info->limit);
                   3909:     ldt_info.flags = tswap32(target_ldt_info->flags);
                   3910:     unlock_user_struct(target_ldt_info, ptr, 0);
1.1.1.6   root     3911: 
1.1       root     3912:     if (ldt_info.entry_number >= TARGET_LDT_ENTRIES)
1.1.1.6   root     3913:         return -TARGET_EINVAL;
1.1       root     3914:     seg_32bit = ldt_info.flags & 1;
                   3915:     contents = (ldt_info.flags >> 1) & 3;
                   3916:     read_exec_only = (ldt_info.flags >> 3) & 1;
                   3917:     limit_in_pages = (ldt_info.flags >> 4) & 1;
                   3918:     seg_not_present = (ldt_info.flags >> 5) & 1;
                   3919:     useable = (ldt_info.flags >> 6) & 1;
1.1.1.6   root     3920: #ifdef TARGET_ABI32
                   3921:     lm = 0;
                   3922: #else
                   3923:     lm = (ldt_info.flags >> 7) & 1;
                   3924: #endif
1.1       root     3925:     if (contents == 3) {
                   3926:         if (oldmode)
1.1.1.6   root     3927:             return -TARGET_EINVAL;
1.1       root     3928:         if (seg_not_present == 0)
1.1.1.6   root     3929:             return -TARGET_EINVAL;
1.1       root     3930:     }
                   3931:     /* allocate the LDT */
                   3932:     if (!ldt_table) {
1.1.1.7   root     3933:         env->ldt.base = target_mmap(0,
                   3934:                                     TARGET_LDT_ENTRIES * TARGET_LDT_ENTRY_SIZE,
                   3935:                                     PROT_READ|PROT_WRITE,
                   3936:                                     MAP_ANONYMOUS|MAP_PRIVATE, -1, 0);
                   3937:         if (env->ldt.base == -1)
1.1.1.6   root     3938:             return -TARGET_ENOMEM;
1.1.1.7   root     3939:         memset(g2h(env->ldt.base), 0,
                   3940:                TARGET_LDT_ENTRIES * TARGET_LDT_ENTRY_SIZE);
1.1       root     3941:         env->ldt.limit = 0xffff;
1.1.1.7   root     3942:         ldt_table = g2h(env->ldt.base);
1.1       root     3943:     }
                   3944: 
                   3945:     /* NOTE: same code as Linux kernel */
                   3946:     /* Allow LDTs to be cleared by the user. */
                   3947:     if (ldt_info.base_addr == 0 && ldt_info.limit == 0) {
                   3948:         if (oldmode ||
                   3949:             (contents == 0             &&
                   3950:              read_exec_only == 1       &&
                   3951:              seg_32bit == 0            &&
                   3952:              limit_in_pages == 0       &&
                   3953:              seg_not_present == 1      &&
                   3954:              useable == 0 )) {
                   3955:             entry_1 = 0;
                   3956:             entry_2 = 0;
                   3957:             goto install;
                   3958:         }
                   3959:     }
1.1.1.6   root     3960: 
1.1       root     3961:     entry_1 = ((ldt_info.base_addr & 0x0000ffff) << 16) |
                   3962:         (ldt_info.limit & 0x0ffff);
                   3963:     entry_2 = (ldt_info.base_addr & 0xff000000) |
                   3964:         ((ldt_info.base_addr & 0x00ff0000) >> 16) |
                   3965:         (ldt_info.limit & 0xf0000) |
                   3966:         ((read_exec_only ^ 1) << 9) |
                   3967:         (contents << 10) |
                   3968:         ((seg_not_present ^ 1) << 15) |
                   3969:         (seg_32bit << 22) |
                   3970:         (limit_in_pages << 23) |
1.1.1.6   root     3971:         (lm << 21) |
1.1       root     3972:         0x7000;
                   3973:     if (!oldmode)
                   3974:         entry_2 |= (useable << 20);
                   3975: 
                   3976:     /* Install the new entry ...  */
                   3977: install:
                   3978:     lp = (uint32_t *)(ldt_table + (ldt_info.entry_number << 3));
                   3979:     lp[0] = tswap32(entry_1);
                   3980:     lp[1] = tswap32(entry_2);
                   3981:     return 0;
                   3982: }
                   3983: 
                   3984: /* specific and weird i386 syscalls */
1.1.1.7   root     3985: static abi_long do_modify_ldt(CPUX86State *env, int func, abi_ulong ptr,
                   3986:                               unsigned long bytecount)
1.1       root     3987: {
1.1.1.6   root     3988:     abi_long ret;
                   3989: 
1.1       root     3990:     switch (func) {
                   3991:     case 0:
                   3992:         ret = read_ldt(ptr, bytecount);
                   3993:         break;
                   3994:     case 1:
                   3995:         ret = write_ldt(env, ptr, bytecount, 1);
                   3996:         break;
                   3997:     case 0x11:
                   3998:         ret = write_ldt(env, ptr, bytecount, 0);
                   3999:         break;
1.1.1.6   root     4000:     default:
                   4001:         ret = -TARGET_ENOSYS;
                   4002:         break;
1.1       root     4003:     }
                   4004:     return ret;
                   4005: }
                   4006: 
1.1.1.7   root     4007: #if defined(TARGET_I386) && defined(TARGET_ABI32)
                   4008: static abi_long do_set_thread_area(CPUX86State *env, abi_ulong ptr)
1.1.1.6   root     4009: {
                   4010:     uint64_t *gdt_table = g2h(env->gdt.base);
                   4011:     struct target_modify_ldt_ldt_s ldt_info;
                   4012:     struct target_modify_ldt_ldt_s *target_ldt_info;
                   4013:     int seg_32bit, contents, read_exec_only, limit_in_pages;
                   4014:     int seg_not_present, useable, lm;
                   4015:     uint32_t *lp, entry_1, entry_2;
                   4016:     int i;
                   4017: 
                   4018:     lock_user_struct(VERIFY_WRITE, target_ldt_info, ptr, 1);
                   4019:     if (!target_ldt_info)
                   4020:         return -TARGET_EFAULT;
                   4021:     ldt_info.entry_number = tswap32(target_ldt_info->entry_number);
1.1.1.13  root     4022:     ldt_info.base_addr = tswapal(target_ldt_info->base_addr);
1.1.1.6   root     4023:     ldt_info.limit = tswap32(target_ldt_info->limit);
                   4024:     ldt_info.flags = tswap32(target_ldt_info->flags);
                   4025:     if (ldt_info.entry_number == -1) {
                   4026:         for (i=TARGET_GDT_ENTRY_TLS_MIN; i<=TARGET_GDT_ENTRY_TLS_MAX; i++) {
                   4027:             if (gdt_table[i] == 0) {
                   4028:                 ldt_info.entry_number = i;
                   4029:                 target_ldt_info->entry_number = tswap32(i);
                   4030:                 break;
                   4031:             }
                   4032:         }
                   4033:     }
                   4034:     unlock_user_struct(target_ldt_info, ptr, 1);
                   4035: 
                   4036:     if (ldt_info.entry_number < TARGET_GDT_ENTRY_TLS_MIN || 
                   4037:         ldt_info.entry_number > TARGET_GDT_ENTRY_TLS_MAX)
                   4038:            return -TARGET_EINVAL;
                   4039:     seg_32bit = ldt_info.flags & 1;
                   4040:     contents = (ldt_info.flags >> 1) & 3;
                   4041:     read_exec_only = (ldt_info.flags >> 3) & 1;
                   4042:     limit_in_pages = (ldt_info.flags >> 4) & 1;
                   4043:     seg_not_present = (ldt_info.flags >> 5) & 1;
                   4044:     useable = (ldt_info.flags >> 6) & 1;
                   4045: #ifdef TARGET_ABI32
                   4046:     lm = 0;
                   4047: #else
                   4048:     lm = (ldt_info.flags >> 7) & 1;
                   4049: #endif
                   4050: 
                   4051:     if (contents == 3) {
                   4052:         if (seg_not_present == 0)
                   4053:             return -TARGET_EINVAL;
                   4054:     }
                   4055: 
                   4056:     /* NOTE: same code as Linux kernel */
                   4057:     /* Allow LDTs to be cleared by the user. */
                   4058:     if (ldt_info.base_addr == 0 && ldt_info.limit == 0) {
                   4059:         if ((contents == 0             &&
                   4060:              read_exec_only == 1       &&
                   4061:              seg_32bit == 0            &&
                   4062:              limit_in_pages == 0       &&
                   4063:              seg_not_present == 1      &&
                   4064:              useable == 0 )) {
                   4065:             entry_1 = 0;
                   4066:             entry_2 = 0;
                   4067:             goto install;
                   4068:         }
                   4069:     }
                   4070: 
                   4071:     entry_1 = ((ldt_info.base_addr & 0x0000ffff) << 16) |
                   4072:         (ldt_info.limit & 0x0ffff);
                   4073:     entry_2 = (ldt_info.base_addr & 0xff000000) |
                   4074:         ((ldt_info.base_addr & 0x00ff0000) >> 16) |
                   4075:         (ldt_info.limit & 0xf0000) |
                   4076:         ((read_exec_only ^ 1) << 9) |
                   4077:         (contents << 10) |
                   4078:         ((seg_not_present ^ 1) << 15) |
                   4079:         (seg_32bit << 22) |
                   4080:         (limit_in_pages << 23) |
                   4081:         (useable << 20) |
                   4082:         (lm << 21) |
                   4083:         0x7000;
                   4084: 
                   4085:     /* Install the new entry ...  */
                   4086: install:
                   4087:     lp = (uint32_t *)(gdt_table + ldt_info.entry_number);
                   4088:     lp[0] = tswap32(entry_1);
                   4089:     lp[1] = tswap32(entry_2);
                   4090:     return 0;
                   4091: }
                   4092: 
1.1.1.7   root     4093: static abi_long do_get_thread_area(CPUX86State *env, abi_ulong ptr)
1.1.1.6   root     4094: {
                   4095:     struct target_modify_ldt_ldt_s *target_ldt_info;
                   4096:     uint64_t *gdt_table = g2h(env->gdt.base);
                   4097:     uint32_t base_addr, limit, flags;
                   4098:     int seg_32bit, contents, read_exec_only, limit_in_pages, idx;
                   4099:     int seg_not_present, useable, lm;
                   4100:     uint32_t *lp, entry_1, entry_2;
                   4101: 
                   4102:     lock_user_struct(VERIFY_WRITE, target_ldt_info, ptr, 1);
                   4103:     if (!target_ldt_info)
                   4104:         return -TARGET_EFAULT;
                   4105:     idx = tswap32(target_ldt_info->entry_number);
                   4106:     if (idx < TARGET_GDT_ENTRY_TLS_MIN ||
                   4107:         idx > TARGET_GDT_ENTRY_TLS_MAX) {
                   4108:         unlock_user_struct(target_ldt_info, ptr, 1);
                   4109:         return -TARGET_EINVAL;
                   4110:     }
                   4111:     lp = (uint32_t *)(gdt_table + idx);
                   4112:     entry_1 = tswap32(lp[0]);
                   4113:     entry_2 = tswap32(lp[1]);
                   4114:     
                   4115:     read_exec_only = ((entry_2 >> 9) & 1) ^ 1;
                   4116:     contents = (entry_2 >> 10) & 3;
                   4117:     seg_not_present = ((entry_2 >> 15) & 1) ^ 1;
                   4118:     seg_32bit = (entry_2 >> 22) & 1;
                   4119:     limit_in_pages = (entry_2 >> 23) & 1;
                   4120:     useable = (entry_2 >> 20) & 1;
                   4121: #ifdef TARGET_ABI32
                   4122:     lm = 0;
                   4123: #else
                   4124:     lm = (entry_2 >> 21) & 1;
                   4125: #endif
                   4126:     flags = (seg_32bit << 0) | (contents << 1) |
                   4127:         (read_exec_only << 3) | (limit_in_pages << 4) |
                   4128:         (seg_not_present << 5) | (useable << 6) | (lm << 7);
                   4129:     limit = (entry_1 & 0xffff) | (entry_2  & 0xf0000);
                   4130:     base_addr = (entry_1 >> 16) | 
                   4131:         (entry_2 & 0xff000000) | 
                   4132:         ((entry_2 & 0xff) << 16);
1.1.1.13  root     4133:     target_ldt_info->base_addr = tswapal(base_addr);
1.1.1.6   root     4134:     target_ldt_info->limit = tswap32(limit);
                   4135:     target_ldt_info->flags = tswap32(flags);
                   4136:     unlock_user_struct(target_ldt_info, ptr, 1);
                   4137:     return 0;
                   4138: }
1.1.1.7   root     4139: #endif /* TARGET_I386 && TARGET_ABI32 */
1.1.1.6   root     4140: 
                   4141: #ifndef TARGET_ABI32
1.1.1.7   root     4142: static abi_long do_arch_prctl(CPUX86State *env, int code, abi_ulong addr)
1.1.1.6   root     4143: {
1.1.1.12  root     4144:     abi_long ret = 0;
1.1.1.6   root     4145:     abi_ulong val;
                   4146:     int idx;
1.1.1.12  root     4147: 
1.1.1.6   root     4148:     switch(code) {
                   4149:     case TARGET_ARCH_SET_GS:
                   4150:     case TARGET_ARCH_SET_FS:
                   4151:         if (code == TARGET_ARCH_SET_GS)
                   4152:             idx = R_GS;
                   4153:         else
                   4154:             idx = R_FS;
                   4155:         cpu_x86_load_seg(env, idx, 0);
                   4156:         env->segs[idx].base = addr;
                   4157:         break;
                   4158:     case TARGET_ARCH_GET_GS:
                   4159:     case TARGET_ARCH_GET_FS:
                   4160:         if (code == TARGET_ARCH_GET_GS)
                   4161:             idx = R_GS;
                   4162:         else
                   4163:             idx = R_FS;
                   4164:         val = env->segs[idx].base;
                   4165:         if (put_user(val, addr, abi_ulong))
1.1.1.12  root     4166:             ret = -TARGET_EFAULT;
1.1.1.6   root     4167:         break;
                   4168:     default:
                   4169:         ret = -TARGET_EINVAL;
                   4170:         break;
                   4171:     }
1.1.1.12  root     4172:     return ret;
1.1.1.6   root     4173: }
                   4174: #endif
                   4175: 
1.1       root     4176: #endif /* defined(TARGET_I386) */
                   4177: 
1.1.1.12  root     4178: #define NEW_STACK_SIZE 0x40000
1.1.1.7   root     4179: 
1.1.1.12  root     4180: #if defined(CONFIG_USE_NPTL)
1.1.1.7   root     4181: 
                   4182: static pthread_mutex_t clone_lock = PTHREAD_MUTEX_INITIALIZER;
                   4183: typedef struct {
1.1.1.14! root     4184:     CPUArchState *env;
1.1.1.7   root     4185:     pthread_mutex_t mutex;
                   4186:     pthread_cond_t cond;
                   4187:     pthread_t thread;
                   4188:     uint32_t tid;
                   4189:     abi_ulong child_tidptr;
                   4190:     abi_ulong parent_tidptr;
                   4191:     sigset_t sigmask;
                   4192: } new_thread_info;
                   4193: 
                   4194: static void *clone_func(void *arg)
                   4195: {
                   4196:     new_thread_info *info = arg;
1.1.1.14! root     4197:     CPUArchState *env;
1.1.1.8   root     4198:     TaskState *ts;
1.1.1.7   root     4199: 
                   4200:     env = info->env;
                   4201:     thread_env = env;
1.1.1.8   root     4202:     ts = (TaskState *)thread_env->opaque;
1.1.1.7   root     4203:     info->tid = gettid();
1.1.1.8   root     4204:     env->host_tid = info->tid;
                   4205:     task_settid(ts);
1.1.1.7   root     4206:     if (info->child_tidptr)
                   4207:         put_user_u32(info->tid, info->child_tidptr);
                   4208:     if (info->parent_tidptr)
                   4209:         put_user_u32(info->tid, info->parent_tidptr);
                   4210:     /* Enable signals.  */
                   4211:     sigprocmask(SIG_SETMASK, &info->sigmask, NULL);
                   4212:     /* Signal to the parent that we're ready.  */
                   4213:     pthread_mutex_lock(&info->mutex);
                   4214:     pthread_cond_broadcast(&info->cond);
                   4215:     pthread_mutex_unlock(&info->mutex);
                   4216:     /* Wait until the parent has finshed initializing the tls state.  */
                   4217:     pthread_mutex_lock(&clone_lock);
                   4218:     pthread_mutex_unlock(&clone_lock);
                   4219:     cpu_loop(env);
                   4220:     /* never exits */
                   4221:     return NULL;
                   4222: }
                   4223: #else
1.1       root     4224: 
                   4225: static int clone_func(void *arg)
                   4226: {
1.1.1.14! root     4227:     CPUArchState *env = arg;
1.1       root     4228:     cpu_loop(env);
                   4229:     /* never exits */
                   4230:     return 0;
                   4231: }
1.1.1.7   root     4232: #endif
1.1       root     4233: 
1.1.1.6   root     4234: /* do_fork() Must return host values and target errnos (unlike most
                   4235:    do_*() functions). */
1.1.1.14! root     4236: static int do_fork(CPUArchState *env, unsigned int flags, abi_ulong newsp,
1.1.1.7   root     4237:                    abi_ulong parent_tidptr, target_ulong newtls,
                   4238:                    abi_ulong child_tidptr)
1.1       root     4239: {
                   4240:     int ret;
                   4241:     TaskState *ts;
1.1.1.14! root     4242:     CPUArchState *new_env;
1.1.1.9   root     4243: #if defined(CONFIG_USE_NPTL)
1.1.1.7   root     4244:     unsigned int nptl_flags;
                   4245:     sigset_t sigmask;
1.1.1.11  root     4246: #else
                   4247:     uint8_t *new_stack;
1.1.1.7   root     4248: #endif
                   4249: 
                   4250:     /* Emulate vfork() with fork() */
                   4251:     if (flags & CLONE_VFORK)
                   4252:         flags &= ~(CLONE_VFORK | CLONE_VM);
1.1.1.6   root     4253: 
1.1       root     4254:     if (flags & CLONE_VM) {
1.1.1.8   root     4255:         TaskState *parent_ts = (TaskState *)env->opaque;
1.1.1.9   root     4256: #if defined(CONFIG_USE_NPTL)
1.1.1.7   root     4257:         new_thread_info info;
                   4258:         pthread_attr_t attr;
                   4259: #endif
1.1.1.13  root     4260:         ts = g_malloc0(sizeof(TaskState));
1.1.1.7   root     4261:         init_task_state(ts);
1.1       root     4262:         /* we create a new CPU instance. */
1.1.1.6   root     4263:         new_env = cpu_copy(env);
1.1.1.9   root     4264: #if defined(TARGET_I386) || defined(TARGET_SPARC) || defined(TARGET_PPC)
1.1.1.14! root     4265:         cpu_state_reset(new_env);
1.1.1.9   root     4266: #endif
1.1.1.7   root     4267:         /* Init regs that differ from the parent.  */
                   4268:         cpu_clone_regs(new_env, newsp);
                   4269:         new_env->opaque = ts;
1.1.1.8   root     4270:         ts->bprm = parent_ts->bprm;
                   4271:         ts->info = parent_ts->info;
1.1.1.9   root     4272: #if defined(CONFIG_USE_NPTL)
1.1.1.7   root     4273:         nptl_flags = flags;
                   4274:         flags &= ~CLONE_NPTL_FLAGS2;
                   4275: 
1.1.1.8   root     4276:         if (nptl_flags & CLONE_CHILD_CLEARTID) {
                   4277:             ts->child_tidptr = child_tidptr;
                   4278:         }
                   4279: 
1.1.1.7   root     4280:         if (nptl_flags & CLONE_SETTLS)
                   4281:             cpu_set_tls (new_env, newtls);
                   4282: 
                   4283:         /* Grab a mutex so that thread setup appears atomic.  */
                   4284:         pthread_mutex_lock(&clone_lock);
                   4285: 
                   4286:         memset(&info, 0, sizeof(info));
                   4287:         pthread_mutex_init(&info.mutex, NULL);
                   4288:         pthread_mutex_lock(&info.mutex);
                   4289:         pthread_cond_init(&info.cond, NULL);
                   4290:         info.env = new_env;
                   4291:         if (nptl_flags & CLONE_CHILD_SETTID)
                   4292:             info.child_tidptr = child_tidptr;
                   4293:         if (nptl_flags & CLONE_PARENT_SETTID)
                   4294:             info.parent_tidptr = parent_tidptr;
                   4295: 
                   4296:         ret = pthread_attr_init(&attr);
1.1.1.11  root     4297:         ret = pthread_attr_setstacksize(&attr, NEW_STACK_SIZE);
                   4298:         ret = pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED);
1.1.1.7   root     4299:         /* It is not safe to deliver signals until the child has finished
                   4300:            initializing, so temporarily block all signals.  */
                   4301:         sigfillset(&sigmask);
                   4302:         sigprocmask(SIG_BLOCK, &sigmask, &info.sigmask);
                   4303: 
                   4304:         ret = pthread_create(&info.thread, &attr, clone_func, &info);
1.1.1.8   root     4305:         /* TODO: Free new CPU state if thread creation failed.  */
1.1.1.7   root     4306: 
                   4307:         sigprocmask(SIG_SETMASK, &info.sigmask, NULL);
                   4308:         pthread_attr_destroy(&attr);
                   4309:         if (ret == 0) {
                   4310:             /* Wait for the child to initialize.  */
                   4311:             pthread_cond_wait(&info.cond, &info.mutex);
                   4312:             ret = info.tid;
                   4313:             if (flags & CLONE_PARENT_SETTID)
                   4314:                 put_user_u32(ret, parent_tidptr);
                   4315:         } else {
                   4316:             ret = -1;
1.1.1.6   root     4317:         }
1.1.1.7   root     4318:         pthread_mutex_unlock(&info.mutex);
                   4319:         pthread_cond_destroy(&info.cond);
                   4320:         pthread_mutex_destroy(&info.mutex);
                   4321:         pthread_mutex_unlock(&clone_lock);
1.1       root     4322: #else
1.1.1.7   root     4323:         if (flags & CLONE_NPTL_FLAGS2)
                   4324:             return -EINVAL;
                   4325:         /* This is probably going to die very quickly, but do it anyway.  */
1.1.1.13  root     4326:         new_stack = g_malloc0 (NEW_STACK_SIZE);
1.1       root     4327: #ifdef __ia64__
1.1.1.10  root     4328:         ret = __clone2(clone_func, new_stack, NEW_STACK_SIZE, flags, new_env);
1.1       root     4329: #else
                   4330:        ret = clone(clone_func, new_stack + NEW_STACK_SIZE, flags, new_env);
                   4331: #endif
1.1.1.7   root     4332: #endif
1.1       root     4333:     } else {
                   4334:         /* if no CLONE_VM, we consider it is a fork */
1.1.1.7   root     4335:         if ((flags & ~(CSIGNAL | CLONE_NPTL_FLAGS2)) != 0)
1.1       root     4336:             return -EINVAL;
1.1.1.7   root     4337:         fork_start();
1.1       root     4338:         ret = fork();
1.1.1.7   root     4339:         if (ret == 0) {
                   4340:             /* Child Process.  */
                   4341:             cpu_clone_regs(env, newsp);
                   4342:             fork_end(1);
1.1.1.9   root     4343: #if defined(CONFIG_USE_NPTL)
1.1.1.7   root     4344:             /* There is a race condition here.  The parent process could
                   4345:                theoretically read the TID in the child process before the child
                   4346:                tid is set.  This would require using either ptrace
                   4347:                (not implemented) or having *_tidptr to point at a shared memory
                   4348:                mapping.  We can't repeat the spinlock hack used above because
                   4349:                the child process gets its own copy of the lock.  */
                   4350:             if (flags & CLONE_CHILD_SETTID)
                   4351:                 put_user_u32(gettid(), child_tidptr);
                   4352:             if (flags & CLONE_PARENT_SETTID)
                   4353:                 put_user_u32(gettid(), parent_tidptr);
                   4354:             ts = (TaskState *)env->opaque;
                   4355:             if (flags & CLONE_SETTLS)
                   4356:                 cpu_set_tls (env, newtls);
1.1.1.8   root     4357:             if (flags & CLONE_CHILD_CLEARTID)
                   4358:                 ts->child_tidptr = child_tidptr;
1.1.1.7   root     4359: #endif
                   4360:         } else {
                   4361:             fork_end(0);
                   4362:         }
1.1       root     4363:     }
                   4364:     return ret;
                   4365: }
                   4366: 
1.1.1.8   root     4367: /* warning : doesn't handle linux specific flags... */
                   4368: static int target_to_host_fcntl_cmd(int cmd)
                   4369: {
                   4370:     switch(cmd) {
                   4371:        case TARGET_F_DUPFD:
                   4372:        case TARGET_F_GETFD:
                   4373:        case TARGET_F_SETFD:
                   4374:        case TARGET_F_GETFL:
                   4375:        case TARGET_F_SETFL:
                   4376:             return cmd;
                   4377:         case TARGET_F_GETLK:
                   4378:            return F_GETLK;
                   4379:        case TARGET_F_SETLK:
                   4380:            return F_SETLK;
                   4381:        case TARGET_F_SETLKW:
                   4382:            return F_SETLKW;
                   4383:        case TARGET_F_GETOWN:
                   4384:            return F_GETOWN;
                   4385:        case TARGET_F_SETOWN:
                   4386:            return F_SETOWN;
                   4387:        case TARGET_F_GETSIG:
                   4388:            return F_GETSIG;
                   4389:        case TARGET_F_SETSIG:
                   4390:            return F_SETSIG;
                   4391: #if TARGET_ABI_BITS == 32
                   4392:         case TARGET_F_GETLK64:
                   4393:            return F_GETLK64;
                   4394:        case TARGET_F_SETLK64:
                   4395:            return F_SETLK64;
                   4396:        case TARGET_F_SETLKW64:
                   4397:            return F_SETLKW64;
                   4398: #endif
1.1.1.9   root     4399:         case TARGET_F_SETLEASE:
                   4400:             return F_SETLEASE;
                   4401:         case TARGET_F_GETLEASE:
                   4402:             return F_GETLEASE;
                   4403: #ifdef F_DUPFD_CLOEXEC
                   4404:         case TARGET_F_DUPFD_CLOEXEC:
                   4405:             return F_DUPFD_CLOEXEC;
                   4406: #endif
                   4407:         case TARGET_F_NOTIFY:
                   4408:             return F_NOTIFY;
1.1.1.8   root     4409:        default:
                   4410:             return -TARGET_EINVAL;
                   4411:     }
                   4412:     return -TARGET_EINVAL;
                   4413: }
                   4414: 
1.1.1.6   root     4415: static abi_long do_fcntl(int fd, int cmd, abi_ulong arg)
1.1       root     4416: {
                   4417:     struct flock fl;
1.1.1.3   root     4418:     struct target_flock *target_fl;
1.1.1.5   root     4419:     struct flock64 fl64;
                   4420:     struct target_flock64 *target_fl64;
1.1.1.6   root     4421:     abi_long ret;
1.1.1.8   root     4422:     int host_cmd = target_to_host_fcntl_cmd(cmd);
                   4423: 
                   4424:     if (host_cmd == -TARGET_EINVAL)
                   4425:            return host_cmd;
1.1.1.3   root     4426: 
1.1       root     4427:     switch(cmd) {
                   4428:     case TARGET_F_GETLK:
1.1.1.6   root     4429:         if (!lock_user_struct(VERIFY_READ, target_fl, arg, 1))
                   4430:             return -TARGET_EFAULT;
                   4431:         fl.l_type = tswap16(target_fl->l_type);
                   4432:         fl.l_whence = tswap16(target_fl->l_whence);
1.1.1.13  root     4433:         fl.l_start = tswapal(target_fl->l_start);
                   4434:         fl.l_len = tswapal(target_fl->l_len);
1.1.1.9   root     4435:         fl.l_pid = tswap32(target_fl->l_pid);
1.1.1.6   root     4436:         unlock_user_struct(target_fl, arg, 0);
1.1.1.8   root     4437:         ret = get_errno(fcntl(fd, host_cmd, &fl));
1.1       root     4438:         if (ret == 0) {
1.1.1.6   root     4439:             if (!lock_user_struct(VERIFY_WRITE, target_fl, arg, 0))
                   4440:                 return -TARGET_EFAULT;
1.1       root     4441:             target_fl->l_type = tswap16(fl.l_type);
                   4442:             target_fl->l_whence = tswap16(fl.l_whence);
1.1.1.13  root     4443:             target_fl->l_start = tswapal(fl.l_start);
                   4444:             target_fl->l_len = tswapal(fl.l_len);
1.1.1.9   root     4445:             target_fl->l_pid = tswap32(fl.l_pid);
1.1.1.3   root     4446:             unlock_user_struct(target_fl, arg, 1);
1.1       root     4447:         }
                   4448:         break;
1.1.1.6   root     4449: 
1.1       root     4450:     case TARGET_F_SETLK:
                   4451:     case TARGET_F_SETLKW:
1.1.1.6   root     4452:         if (!lock_user_struct(VERIFY_READ, target_fl, arg, 1))
                   4453:             return -TARGET_EFAULT;
1.1       root     4454:         fl.l_type = tswap16(target_fl->l_type);
                   4455:         fl.l_whence = tswap16(target_fl->l_whence);
1.1.1.13  root     4456:         fl.l_start = tswapal(target_fl->l_start);
                   4457:         fl.l_len = tswapal(target_fl->l_len);
1.1.1.9   root     4458:         fl.l_pid = tswap32(target_fl->l_pid);
1.1.1.3   root     4459:         unlock_user_struct(target_fl, arg, 0);
1.1.1.8   root     4460:         ret = get_errno(fcntl(fd, host_cmd, &fl));
1.1       root     4461:         break;
1.1.1.6   root     4462: 
1.1       root     4463:     case TARGET_F_GETLK64:
1.1.1.6   root     4464:         if (!lock_user_struct(VERIFY_READ, target_fl64, arg, 1))
                   4465:             return -TARGET_EFAULT;
                   4466:         fl64.l_type = tswap16(target_fl64->l_type) >> 1;
                   4467:         fl64.l_whence = tswap16(target_fl64->l_whence);
1.1.1.13  root     4468:         fl64.l_start = tswap64(target_fl64->l_start);
                   4469:         fl64.l_len = tswap64(target_fl64->l_len);
1.1.1.9   root     4470:         fl64.l_pid = tswap32(target_fl64->l_pid);
1.1.1.6   root     4471:         unlock_user_struct(target_fl64, arg, 0);
1.1.1.8   root     4472:         ret = get_errno(fcntl(fd, host_cmd, &fl64));
1.1.1.5   root     4473:         if (ret == 0) {
1.1.1.6   root     4474:             if (!lock_user_struct(VERIFY_WRITE, target_fl64, arg, 0))
                   4475:                 return -TARGET_EFAULT;
1.1.1.5   root     4476:             target_fl64->l_type = tswap16(fl64.l_type) >> 1;
                   4477:             target_fl64->l_whence = tswap16(fl64.l_whence);
1.1.1.13  root     4478:             target_fl64->l_start = tswap64(fl64.l_start);
                   4479:             target_fl64->l_len = tswap64(fl64.l_len);
1.1.1.9   root     4480:             target_fl64->l_pid = tswap32(fl64.l_pid);
1.1.1.5   root     4481:             unlock_user_struct(target_fl64, arg, 1);
                   4482:         }
1.1.1.6   root     4483:         break;
1.1       root     4484:     case TARGET_F_SETLK64:
                   4485:     case TARGET_F_SETLKW64:
1.1.1.6   root     4486:         if (!lock_user_struct(VERIFY_READ, target_fl64, arg, 1))
                   4487:             return -TARGET_EFAULT;
1.1.1.5   root     4488:         fl64.l_type = tswap16(target_fl64->l_type) >> 1;
                   4489:         fl64.l_whence = tswap16(target_fl64->l_whence);
1.1.1.13  root     4490:         fl64.l_start = tswap64(target_fl64->l_start);
                   4491:         fl64.l_len = tswap64(target_fl64->l_len);
1.1.1.9   root     4492:         fl64.l_pid = tswap32(target_fl64->l_pid);
1.1.1.5   root     4493:         unlock_user_struct(target_fl64, arg, 0);
1.1.1.8   root     4494:         ret = get_errno(fcntl(fd, host_cmd, &fl64));
1.1       root     4495:         break;
                   4496: 
1.1.1.8   root     4497:     case TARGET_F_GETFL:
                   4498:         ret = get_errno(fcntl(fd, host_cmd, arg));
1.1.1.6   root     4499:         if (ret >= 0) {
                   4500:             ret = host_to_target_bitmask(ret, fcntl_flags_tbl);
                   4501:         }
1.1       root     4502:         break;
                   4503: 
1.1.1.8   root     4504:     case TARGET_F_SETFL:
                   4505:         ret = get_errno(fcntl(fd, host_cmd, target_to_host_bitmask(arg, fcntl_flags_tbl)));
                   4506:         break;
                   4507: 
                   4508:     case TARGET_F_SETOWN:
                   4509:     case TARGET_F_GETOWN:
                   4510:     case TARGET_F_SETSIG:
                   4511:     case TARGET_F_GETSIG:
1.1.1.9   root     4512:     case TARGET_F_SETLEASE:
                   4513:     case TARGET_F_GETLEASE:
1.1.1.8   root     4514:         ret = get_errno(fcntl(fd, host_cmd, arg));
1.1       root     4515:         break;
                   4516: 
                   4517:     default:
1.1.1.6   root     4518:         ret = get_errno(fcntl(fd, cmd, arg));
1.1       root     4519:         break;
                   4520:     }
                   4521:     return ret;
                   4522: }
                   4523: 
                   4524: #ifdef USE_UID16
                   4525: 
                   4526: static inline int high2lowuid(int uid)
                   4527: {
                   4528:     if (uid > 65535)
                   4529:         return 65534;
                   4530:     else
                   4531:         return uid;
                   4532: }
                   4533: 
                   4534: static inline int high2lowgid(int gid)
                   4535: {
                   4536:     if (gid > 65535)
                   4537:         return 65534;
                   4538:     else
                   4539:         return gid;
                   4540: }
                   4541: 
                   4542: static inline int low2highuid(int uid)
                   4543: {
                   4544:     if ((int16_t)uid == -1)
                   4545:         return -1;
                   4546:     else
                   4547:         return uid;
                   4548: }
                   4549: 
                   4550: static inline int low2highgid(int gid)
                   4551: {
                   4552:     if ((int16_t)gid == -1)
                   4553:         return -1;
                   4554:     else
                   4555:         return gid;
                   4556: }
1.1.1.12  root     4557: static inline int tswapid(int id)
                   4558: {
                   4559:     return tswap16(id);
                   4560: }
                   4561: #else /* !USE_UID16 */
                   4562: static inline int high2lowuid(int uid)
                   4563: {
                   4564:     return uid;
                   4565: }
                   4566: static inline int high2lowgid(int gid)
                   4567: {
                   4568:     return gid;
                   4569: }
                   4570: static inline int low2highuid(int uid)
                   4571: {
                   4572:     return uid;
                   4573: }
                   4574: static inline int low2highgid(int gid)
                   4575: {
                   4576:     return gid;
                   4577: }
                   4578: static inline int tswapid(int id)
                   4579: {
                   4580:     return tswap32(id);
                   4581: }
1.1       root     4582: #endif /* USE_UID16 */
                   4583: 
                   4584: void syscall_init(void)
                   4585: {
                   4586:     IOCTLEntry *ie;
                   4587:     const argtype *arg_type;
                   4588:     int size;
1.1.1.6   root     4589:     int i;
1.1       root     4590: 
1.1.1.8   root     4591: #define STRUCT(name, ...) thunk_register_struct(STRUCT_ ## name, #name, struct_ ## name ## _def);
1.1.1.6   root     4592: #define STRUCT_SPECIAL(name) thunk_register_struct_direct(STRUCT_ ## name, #name, &struct_ ## name ## _def);
1.1       root     4593: #include "syscall_types.h"
                   4594: #undef STRUCT
                   4595: #undef STRUCT_SPECIAL
                   4596: 
                   4597:     /* we patch the ioctl size if necessary. We rely on the fact that
                   4598:        no ioctl has all the bits at '1' in the size field */
                   4599:     ie = ioctl_entries;
                   4600:     while (ie->target_cmd != 0) {
                   4601:         if (((ie->target_cmd >> TARGET_IOC_SIZESHIFT) & TARGET_IOC_SIZEMASK) ==
                   4602:             TARGET_IOC_SIZEMASK) {
                   4603:             arg_type = ie->arg_type;
                   4604:             if (arg_type[0] != TYPE_PTR) {
1.1.1.6   root     4605:                 fprintf(stderr, "cannot patch size for ioctl 0x%x\n",
1.1       root     4606:                         ie->target_cmd);
                   4607:                 exit(1);
                   4608:             }
                   4609:             arg_type++;
                   4610:             size = thunk_type_size(arg_type, 0);
1.1.1.6   root     4611:             ie->target_cmd = (ie->target_cmd &
1.1       root     4612:                               ~(TARGET_IOC_SIZEMASK << TARGET_IOC_SIZESHIFT)) |
                   4613:                 (size << TARGET_IOC_SIZESHIFT);
                   4614:         }
1.1.1.6   root     4615: 
                   4616:         /* Build target_to_host_errno_table[] table from
                   4617:          * host_to_target_errno_table[]. */
                   4618:         for (i=0; i < ERRNO_TABLE_SIZE; i++)
                   4619:                 target_to_host_errno_table[host_to_target_errno_table[i]] = i;
                   4620: 
1.1       root     4621:         /* automatic consistency check if same arch */
1.1.1.7   root     4622: #if (defined(__i386__) && defined(TARGET_I386) && defined(TARGET_ABI32)) || \
                   4623:     (defined(__x86_64__) && defined(TARGET_X86_64))
                   4624:         if (unlikely(ie->target_cmd != ie->host_cmd)) {
                   4625:             fprintf(stderr, "ERROR: ioctl(%s): target=0x%x host=0x%x\n",
                   4626:                     ie->name, ie->target_cmd, ie->host_cmd);
1.1       root     4627:         }
                   4628: #endif
                   4629:         ie++;
                   4630:     }
                   4631: }
                   4632: 
1.1.1.6   root     4633: #if TARGET_ABI_BITS == 32
1.1.1.3   root     4634: static inline uint64_t target_offset64(uint32_t word0, uint32_t word1)
                   4635: {
1.1.1.7   root     4636: #ifdef TARGET_WORDS_BIGENDIAN
1.1.1.3   root     4637:     return ((uint64_t)word0 << 32) | word1;
                   4638: #else
                   4639:     return ((uint64_t)word1 << 32) | word0;
                   4640: #endif
                   4641: }
1.1.1.6   root     4642: #else /* TARGET_ABI_BITS == 32 */
                   4643: static inline uint64_t target_offset64(uint64_t word0, uint64_t word1)
                   4644: {
                   4645:     return word0;
                   4646: }
                   4647: #endif /* TARGET_ABI_BITS != 32 */
1.1.1.3   root     4648: 
                   4649: #ifdef TARGET_NR_truncate64
1.1.1.6   root     4650: static inline abi_long target_truncate64(void *cpu_env, const char *arg1,
                   4651:                                          abi_long arg2,
                   4652:                                          abi_long arg3,
                   4653:                                          abi_long arg4)
1.1.1.3   root     4654: {
1.1.1.12  root     4655:     if (regpairs_aligned(cpu_env)) {
1.1.1.3   root     4656:         arg2 = arg3;
                   4657:         arg3 = arg4;
1.1.1.12  root     4658:     }
1.1.1.3   root     4659:     return get_errno(truncate64(arg1, target_offset64(arg2, arg3)));
                   4660: }
                   4661: #endif
                   4662: 
                   4663: #ifdef TARGET_NR_ftruncate64
1.1.1.6   root     4664: static inline abi_long target_ftruncate64(void *cpu_env, abi_long arg1,
                   4665:                                           abi_long arg2,
                   4666:                                           abi_long arg3,
                   4667:                                           abi_long arg4)
1.1.1.3   root     4668: {
1.1.1.12  root     4669:     if (regpairs_aligned(cpu_env)) {
1.1.1.3   root     4670:         arg2 = arg3;
                   4671:         arg3 = arg4;
1.1.1.12  root     4672:     }
1.1.1.3   root     4673:     return get_errno(ftruncate64(arg1, target_offset64(arg2, arg3)));
                   4674: }
                   4675: #endif
                   4676: 
1.1.1.6   root     4677: static inline abi_long target_to_host_timespec(struct timespec *host_ts,
                   4678:                                                abi_ulong target_addr)
1.1.1.3   root     4679: {
                   4680:     struct target_timespec *target_ts;
                   4681: 
1.1.1.6   root     4682:     if (!lock_user_struct(VERIFY_READ, target_ts, target_addr, 1))
                   4683:         return -TARGET_EFAULT;
1.1.1.13  root     4684:     host_ts->tv_sec = tswapal(target_ts->tv_sec);
                   4685:     host_ts->tv_nsec = tswapal(target_ts->tv_nsec);
1.1.1.3   root     4686:     unlock_user_struct(target_ts, target_addr, 0);
1.1.1.7   root     4687:     return 0;
1.1.1.3   root     4688: }
                   4689: 
1.1.1.6   root     4690: static inline abi_long host_to_target_timespec(abi_ulong target_addr,
                   4691:                                                struct timespec *host_ts)
1.1.1.3   root     4692: {
                   4693:     struct target_timespec *target_ts;
                   4694: 
1.1.1.6   root     4695:     if (!lock_user_struct(VERIFY_WRITE, target_ts, target_addr, 0))
                   4696:         return -TARGET_EFAULT;
1.1.1.13  root     4697:     target_ts->tv_sec = tswapal(host_ts->tv_sec);
                   4698:     target_ts->tv_nsec = tswapal(host_ts->tv_nsec);
1.1.1.3   root     4699:     unlock_user_struct(target_ts, target_addr, 1);
1.1.1.7   root     4700:     return 0;
                   4701: }
                   4702: 
1.1.1.8   root     4703: #if defined(TARGET_NR_stat64) || defined(TARGET_NR_newfstatat)
1.1.1.7   root     4704: static inline abi_long host_to_target_stat64(void *cpu_env,
                   4705:                                              abi_ulong target_addr,
                   4706:                                              struct stat *host_st)
                   4707: {
                   4708: #ifdef TARGET_ARM
                   4709:     if (((CPUARMState *)cpu_env)->eabi) {
                   4710:         struct target_eabi_stat64 *target_st;
                   4711: 
                   4712:         if (!lock_user_struct(VERIFY_WRITE, target_st, target_addr, 0))
                   4713:             return -TARGET_EFAULT;
                   4714:         memset(target_st, 0, sizeof(struct target_eabi_stat64));
                   4715:         __put_user(host_st->st_dev, &target_st->st_dev);
                   4716:         __put_user(host_st->st_ino, &target_st->st_ino);
                   4717: #ifdef TARGET_STAT64_HAS_BROKEN_ST_INO
                   4718:         __put_user(host_st->st_ino, &target_st->__st_ino);
                   4719: #endif
                   4720:         __put_user(host_st->st_mode, &target_st->st_mode);
                   4721:         __put_user(host_st->st_nlink, &target_st->st_nlink);
                   4722:         __put_user(host_st->st_uid, &target_st->st_uid);
                   4723:         __put_user(host_st->st_gid, &target_st->st_gid);
                   4724:         __put_user(host_st->st_rdev, &target_st->st_rdev);
                   4725:         __put_user(host_st->st_size, &target_st->st_size);
                   4726:         __put_user(host_st->st_blksize, &target_st->st_blksize);
                   4727:         __put_user(host_st->st_blocks, &target_st->st_blocks);
                   4728:         __put_user(host_st->st_atime, &target_st->target_st_atime);
                   4729:         __put_user(host_st->st_mtime, &target_st->target_st_mtime);
                   4730:         __put_user(host_st->st_ctime, &target_st->target_st_ctime);
                   4731:         unlock_user_struct(target_st, target_addr, 1);
                   4732:     } else
                   4733: #endif
                   4734:     {
1.1.1.10  root     4735: #if TARGET_ABI_BITS == 64 && !defined(TARGET_ALPHA)
1.1.1.8   root     4736:         struct target_stat *target_st;
                   4737: #else
1.1.1.7   root     4738:         struct target_stat64 *target_st;
1.1.1.8   root     4739: #endif
1.1.1.7   root     4740: 
                   4741:         if (!lock_user_struct(VERIFY_WRITE, target_st, target_addr, 0))
                   4742:             return -TARGET_EFAULT;
1.1.1.8   root     4743:         memset(target_st, 0, sizeof(*target_st));
1.1.1.7   root     4744:         __put_user(host_st->st_dev, &target_st->st_dev);
                   4745:         __put_user(host_st->st_ino, &target_st->st_ino);
                   4746: #ifdef TARGET_STAT64_HAS_BROKEN_ST_INO
                   4747:         __put_user(host_st->st_ino, &target_st->__st_ino);
                   4748: #endif
                   4749:         __put_user(host_st->st_mode, &target_st->st_mode);
                   4750:         __put_user(host_st->st_nlink, &target_st->st_nlink);
                   4751:         __put_user(host_st->st_uid, &target_st->st_uid);
                   4752:         __put_user(host_st->st_gid, &target_st->st_gid);
                   4753:         __put_user(host_st->st_rdev, &target_st->st_rdev);
                   4754:         /* XXX: better use of kernel struct */
                   4755:         __put_user(host_st->st_size, &target_st->st_size);
                   4756:         __put_user(host_st->st_blksize, &target_st->st_blksize);
                   4757:         __put_user(host_st->st_blocks, &target_st->st_blocks);
                   4758:         __put_user(host_st->st_atime, &target_st->target_st_atime);
                   4759:         __put_user(host_st->st_mtime, &target_st->target_st_mtime);
                   4760:         __put_user(host_st->st_ctime, &target_st->target_st_ctime);
                   4761:         unlock_user_struct(target_st, target_addr, 1);
                   4762:     }
                   4763: 
                   4764:     return 0;
                   4765: }
                   4766: #endif
                   4767: 
1.1.1.9   root     4768: #if defined(CONFIG_USE_NPTL)
1.1.1.7   root     4769: /* ??? Using host futex calls even when target atomic operations
                   4770:    are not really atomic probably breaks things.  However implementing
                   4771:    futexes locally would make futexes shared between multiple processes
                   4772:    tricky.  However they're probably useless because guest atomic
                   4773:    operations won't work either.  */
                   4774: static int do_futex(target_ulong uaddr, int op, int val, target_ulong timeout,
                   4775:                     target_ulong uaddr2, int val3)
                   4776: {
                   4777:     struct timespec ts, *pts;
1.1.1.9   root     4778:     int base_op;
1.1.1.7   root     4779: 
                   4780:     /* ??? We assume FUTEX_* constants are the same on both host
                   4781:        and target.  */
1.1.1.8   root     4782: #ifdef FUTEX_CMD_MASK
1.1.1.9   root     4783:     base_op = op & FUTEX_CMD_MASK;
1.1.1.8   root     4784: #else
1.1.1.9   root     4785:     base_op = op;
1.1.1.8   root     4786: #endif
1.1.1.9   root     4787:     switch (base_op) {
1.1.1.7   root     4788:     case FUTEX_WAIT:
                   4789:         if (timeout) {
                   4790:             pts = &ts;
                   4791:             target_to_host_timespec(pts, timeout);
                   4792:         } else {
                   4793:             pts = NULL;
                   4794:         }
1.1.1.8   root     4795:         return get_errno(sys_futex(g2h(uaddr), op, tswap32(val),
1.1.1.7   root     4796:                          pts, NULL, 0));
                   4797:     case FUTEX_WAKE:
1.1.1.8   root     4798:         return get_errno(sys_futex(g2h(uaddr), op, val, NULL, NULL, 0));
1.1.1.7   root     4799:     case FUTEX_FD:
1.1.1.8   root     4800:         return get_errno(sys_futex(g2h(uaddr), op, val, NULL, NULL, 0));
1.1.1.7   root     4801:     case FUTEX_REQUEUE:
                   4802:     case FUTEX_CMP_REQUEUE:
1.1.1.9   root     4803:     case FUTEX_WAKE_OP:
                   4804:         /* For FUTEX_REQUEUE, FUTEX_CMP_REQUEUE, and FUTEX_WAKE_OP, the
                   4805:            TIMEOUT parameter is interpreted as a uint32_t by the kernel.
                   4806:            But the prototype takes a `struct timespec *'; insert casts
                   4807:            to satisfy the compiler.  We do not need to tswap TIMEOUT
                   4808:            since it's not compared to guest memory.  */
                   4809:         pts = (struct timespec *)(uintptr_t) timeout;
                   4810:         return get_errno(sys_futex(g2h(uaddr), op, val, pts,
                   4811:                                    g2h(uaddr2),
                   4812:                                    (base_op == FUTEX_CMP_REQUEUE
                   4813:                                     ? tswap32(val3)
                   4814:                                     : val3)));
1.1.1.7   root     4815:     default:
                   4816:         return -TARGET_ENOSYS;
                   4817:     }
                   4818: }
                   4819: #endif
                   4820: 
1.1.1.8   root     4821: /* Map host to target signal numbers for the wait family of syscalls.
                   4822:    Assume all other status bits are the same.  */
                   4823: static int host_to_target_waitstatus(int status)
                   4824: {
                   4825:     if (WIFSIGNALED(status)) {
                   4826:         return host_to_target_signal(WTERMSIG(status)) | (status & ~0x7f);
                   4827:     }
                   4828:     if (WIFSTOPPED(status)) {
                   4829:         return (host_to_target_signal(WSTOPSIG(status)) << 8)
                   4830:                | (status & 0xff);
                   4831:     }
                   4832:     return status;
                   4833: }
                   4834: 
1.1.1.7   root     4835: int get_osversion(void)
                   4836: {
                   4837:     static int osversion;
                   4838:     struct new_utsname buf;
                   4839:     const char *s;
                   4840:     int i, n, tmp;
                   4841:     if (osversion)
                   4842:         return osversion;
                   4843:     if (qemu_uname_release && *qemu_uname_release) {
                   4844:         s = qemu_uname_release;
                   4845:     } else {
                   4846:         if (sys_uname(&buf))
                   4847:             return 0;
                   4848:         s = buf.release;
                   4849:     }
                   4850:     tmp = 0;
                   4851:     for (i = 0; i < 3; i++) {
                   4852:         n = 0;
                   4853:         while (*s >= '0' && *s <= '9') {
                   4854:             n *= 10;
                   4855:             n += *s - '0';
                   4856:             s++;
                   4857:         }
                   4858:         tmp = (tmp << 8) + n;
                   4859:         if (*s == '.')
                   4860:             s++;
                   4861:     }
                   4862:     osversion = tmp;
                   4863:     return osversion;
1.1.1.3   root     4864: }
                   4865: 
1.1.1.14! root     4866: 
        !          4867: static int open_self_maps(void *cpu_env, int fd)
        !          4868: {
        !          4869: #if defined(TARGET_ARM) || defined(TARGET_M68K) || defined(TARGET_UNICORE32)
        !          4870:     TaskState *ts = ((CPUArchState *)cpu_env)->opaque;
        !          4871: #endif
        !          4872:     FILE *fp;
        !          4873:     char *line = NULL;
        !          4874:     size_t len = 0;
        !          4875:     ssize_t read;
        !          4876: 
        !          4877:     fp = fopen("/proc/self/maps", "r");
        !          4878:     if (fp == NULL) {
        !          4879:         return -EACCES;
        !          4880:     }
        !          4881: 
        !          4882:     while ((read = getline(&line, &len, fp)) != -1) {
        !          4883:         int fields, dev_maj, dev_min, inode;
        !          4884:         uint64_t min, max, offset;
        !          4885:         char flag_r, flag_w, flag_x, flag_p;
        !          4886:         char path[512] = "";
        !          4887:         fields = sscanf(line, "%"PRIx64"-%"PRIx64" %c%c%c%c %"PRIx64" %x:%x %d"
        !          4888:                         " %512s", &min, &max, &flag_r, &flag_w, &flag_x,
        !          4889:                         &flag_p, &offset, &dev_maj, &dev_min, &inode, path);
        !          4890: 
        !          4891:         if ((fields < 10) || (fields > 11)) {
        !          4892:             continue;
        !          4893:         }
        !          4894:         if (!strncmp(path, "[stack]", 7)) {
        !          4895:             continue;
        !          4896:         }
        !          4897:         if (h2g_valid(min) && h2g_valid(max)) {
        !          4898:             dprintf(fd, TARGET_ABI_FMT_lx "-" TARGET_ABI_FMT_lx
        !          4899:                     " %c%c%c%c %08" PRIx64 " %02x:%02x %d%s%s\n",
        !          4900:                     h2g(min), h2g(max), flag_r, flag_w,
        !          4901:                     flag_x, flag_p, offset, dev_maj, dev_min, inode,
        !          4902:                     path[0] ? "          " : "", path);
        !          4903:         }
        !          4904:     }
        !          4905: 
        !          4906:     free(line);
        !          4907:     fclose(fp);
        !          4908: 
        !          4909: #if defined(TARGET_ARM) || defined(TARGET_M68K) || defined(TARGET_UNICORE32)
        !          4910:     dprintf(fd, "%08llx-%08llx rw-p %08llx 00:00 0          [stack]\n",
        !          4911:                 (unsigned long long)ts->info->stack_limit,
        !          4912:                 (unsigned long long)(ts->stack_base + (TARGET_PAGE_SIZE - 1))
        !          4913:                                      & TARGET_PAGE_MASK,
        !          4914:                 (unsigned long long)0);
        !          4915: #endif
        !          4916: 
        !          4917:     return 0;
        !          4918: }
        !          4919: 
        !          4920: static int open_self_stat(void *cpu_env, int fd)
        !          4921: {
        !          4922:     TaskState *ts = ((CPUArchState *)cpu_env)->opaque;
        !          4923:     abi_ulong start_stack = ts->info->start_stack;
        !          4924:     int i;
        !          4925: 
        !          4926:     for (i = 0; i < 44; i++) {
        !          4927:       char buf[128];
        !          4928:       int len;
        !          4929:       uint64_t val = 0;
        !          4930: 
        !          4931:       if (i == 0) {
        !          4932:         /* pid */
        !          4933:         val = getpid();
        !          4934:         snprintf(buf, sizeof(buf), "%"PRId64 " ", val);
        !          4935:       } else if (i == 1) {
        !          4936:         /* app name */
        !          4937:         snprintf(buf, sizeof(buf), "(%s) ", ts->bprm->argv[0]);
        !          4938:       } else if (i == 27) {
        !          4939:         /* stack bottom */
        !          4940:         val = start_stack;
        !          4941:         snprintf(buf, sizeof(buf), "%"PRId64 " ", val);
        !          4942:       } else {
        !          4943:         /* for the rest, there is MasterCard */
        !          4944:         snprintf(buf, sizeof(buf), "0%c", i == 43 ? '\n' : ' ');
        !          4945:       }
        !          4946: 
        !          4947:       len = strlen(buf);
        !          4948:       if (write(fd, buf, len) != len) {
        !          4949:           return -1;
        !          4950:       }
        !          4951:     }
        !          4952: 
        !          4953:     return 0;
        !          4954: }
        !          4955: 
        !          4956: static int open_self_auxv(void *cpu_env, int fd)
        !          4957: {
        !          4958:     TaskState *ts = ((CPUArchState *)cpu_env)->opaque;
        !          4959:     abi_ulong auxv = ts->info->saved_auxv;
        !          4960:     abi_ulong len = ts->info->auxv_len;
        !          4961:     char *ptr;
        !          4962: 
        !          4963:     /*
        !          4964:      * Auxiliary vector is stored in target process stack.
        !          4965:      * read in whole auxv vector and copy it to file
        !          4966:      */
        !          4967:     ptr = lock_user(VERIFY_READ, auxv, len, 0);
        !          4968:     if (ptr != NULL) {
        !          4969:         while (len > 0) {
        !          4970:             ssize_t r;
        !          4971:             r = write(fd, ptr, len);
        !          4972:             if (r <= 0) {
        !          4973:                 break;
        !          4974:             }
        !          4975:             len -= r;
        !          4976:             ptr += r;
        !          4977:         }
        !          4978:         lseek(fd, 0, SEEK_SET);
        !          4979:         unlock_user(ptr, auxv, len);
        !          4980:     }
        !          4981: 
        !          4982:     return 0;
        !          4983: }
        !          4984: 
        !          4985: static int do_open(void *cpu_env, const char *pathname, int flags, mode_t mode)
        !          4986: {
        !          4987:     struct fake_open {
        !          4988:         const char *filename;
        !          4989:         int (*fill)(void *cpu_env, int fd);
        !          4990:     };
        !          4991:     const struct fake_open *fake_open;
        !          4992:     static const struct fake_open fakes[] = {
        !          4993:         { "/proc/self/maps", open_self_maps },
        !          4994:         { "/proc/self/stat", open_self_stat },
        !          4995:         { "/proc/self/auxv", open_self_auxv },
        !          4996:         { NULL, NULL }
        !          4997:     };
        !          4998: 
        !          4999:     for (fake_open = fakes; fake_open->filename; fake_open++) {
        !          5000:         if (!strncmp(pathname, fake_open->filename,
        !          5001:                      strlen(fake_open->filename))) {
        !          5002:             break;
        !          5003:         }
        !          5004:     }
        !          5005: 
        !          5006:     if (fake_open->filename) {
        !          5007:         const char *tmpdir;
        !          5008:         char filename[PATH_MAX];
        !          5009:         int fd, r;
        !          5010: 
        !          5011:         /* create temporary file to map stat to */
        !          5012:         tmpdir = getenv("TMPDIR");
        !          5013:         if (!tmpdir)
        !          5014:             tmpdir = "/tmp";
        !          5015:         snprintf(filename, sizeof(filename), "%s/qemu-open.XXXXXX", tmpdir);
        !          5016:         fd = mkstemp(filename);
        !          5017:         if (fd < 0) {
        !          5018:             return fd;
        !          5019:         }
        !          5020:         unlink(filename);
        !          5021: 
        !          5022:         if ((r = fake_open->fill(cpu_env, fd))) {
        !          5023:             close(fd);
        !          5024:             return r;
        !          5025:         }
        !          5026:         lseek(fd, 0, SEEK_SET);
        !          5027: 
        !          5028:         return fd;
        !          5029:     }
        !          5030: 
        !          5031:     return get_errno(open(path(pathname), flags, mode));
        !          5032: }
        !          5033: 
1.1.1.6   root     5034: /* do_syscall() should always have a single exit point at the end so
                   5035:    that actions, such as logging of syscall results, can be performed.
                   5036:    All errnos that do_syscall() returns must be -TARGET_<errcode>. */
                   5037: abi_long do_syscall(void *cpu_env, int num, abi_long arg1,
                   5038:                     abi_long arg2, abi_long arg3, abi_long arg4,
1.1.1.12  root     5039:                     abi_long arg5, abi_long arg6, abi_long arg7,
                   5040:                     abi_long arg8)
1.1       root     5041: {
1.1.1.6   root     5042:     abi_long ret;
1.1       root     5043:     struct stat st;
1.1.1.2   root     5044:     struct statfs stfs;
1.1.1.3   root     5045:     void *p;
1.1.1.6   root     5046: 
1.1       root     5047: #ifdef DEBUG
                   5048:     gemu_log("syscall %d", num);
                   5049: #endif
1.1.1.6   root     5050:     if(do_strace)
                   5051:         print_syscall(num, arg1, arg2, arg3, arg4, arg5, arg6);
                   5052: 
1.1       root     5053:     switch(num) {
                   5054:     case TARGET_NR_exit:
1.1.1.9   root     5055: #ifdef CONFIG_USE_NPTL
1.1.1.8   root     5056:       /* In old applications this may be used to implement _exit(2).
                   5057:          However in threaded applictions it is used for thread termination,
                   5058:          and _exit_group is used for application termination.
                   5059:          Do thread termination if we have more then one thread.  */
                   5060:       /* FIXME: This probably breaks if a signal arrives.  We should probably
                   5061:          be disabling signals.  */
                   5062:       if (first_cpu->next_cpu) {
                   5063:           TaskState *ts;
1.1.1.14! root     5064:           CPUArchState **lastp;
        !          5065:           CPUArchState *p;
1.1.1.8   root     5066: 
                   5067:           cpu_list_lock();
                   5068:           lastp = &first_cpu;
                   5069:           p = first_cpu;
1.1.1.14! root     5070:           while (p && p != (CPUArchState *)cpu_env) {
1.1.1.8   root     5071:               lastp = &p->next_cpu;
                   5072:               p = p->next_cpu;
                   5073:           }
                   5074:           /* If we didn't find the CPU for this thread then something is
                   5075:              horribly wrong.  */
                   5076:           if (!p)
                   5077:               abort();
                   5078:           /* Remove the CPU from the list.  */
                   5079:           *lastp = p->next_cpu;
                   5080:           cpu_list_unlock();
1.1.1.14! root     5081:           ts = ((CPUArchState *)cpu_env)->opaque;
1.1.1.8   root     5082:           if (ts->child_tidptr) {
                   5083:               put_user_u32(0, ts->child_tidptr);
                   5084:               sys_futex(g2h(ts->child_tidptr), FUTEX_WAKE, INT_MAX,
                   5085:                         NULL, NULL, 0);
                   5086:           }
1.1.1.11  root     5087:           thread_env = NULL;
1.1.1.14! root     5088:           object_delete(OBJECT(ENV_GET_CPU(cpu_env)));
1.1.1.13  root     5089:           g_free(ts);
1.1.1.8   root     5090:           pthread_exit(NULL);
                   5091:       }
                   5092: #endif
1.1.1.9   root     5093: #ifdef TARGET_GPROF
1.1       root     5094:         _mcleanup();
                   5095: #endif
                   5096:         gdb_exit(cpu_env, arg1);
1.1.1.8   root     5097:         _exit(arg1);
1.1       root     5098:         ret = 0; /* avoid warning */
                   5099:         break;
                   5100:     case TARGET_NR_read:
1.1.1.7   root     5101:         if (arg3 == 0)
                   5102:             ret = 0;
                   5103:         else {
                   5104:             if (!(p = lock_user(VERIFY_WRITE, arg2, arg3, 0)))
                   5105:                 goto efault;
                   5106:             ret = get_errno(read(arg1, p, arg3));
                   5107:             unlock_user(p, arg2, ret);
                   5108:         }
1.1       root     5109:         break;
                   5110:     case TARGET_NR_write:
1.1.1.6   root     5111:         if (!(p = lock_user(VERIFY_READ, arg2, arg3, 1)))
                   5112:             goto efault;
1.1.1.3   root     5113:         ret = get_errno(write(arg1, p, arg3));
                   5114:         unlock_user(p, arg2, 0);
1.1       root     5115:         break;
                   5116:     case TARGET_NR_open:
1.1.1.6   root     5117:         if (!(p = lock_user_string(arg1)))
                   5118:             goto efault;
1.1.1.14! root     5119:         ret = get_errno(do_open(cpu_env, p,
        !          5120:                                 target_to_host_bitmask(arg2, fcntl_flags_tbl),
        !          5121:                                 arg3));
1.1.1.3   root     5122:         unlock_user(p, arg1, 0);
1.1       root     5123:         break;
1.1.1.6   root     5124: #if defined(TARGET_NR_openat) && defined(__NR_openat)
                   5125:     case TARGET_NR_openat:
                   5126:         if (!(p = lock_user_string(arg2)))
                   5127:             goto efault;
                   5128:         ret = get_errno(sys_openat(arg1,
                   5129:                                    path(p),
                   5130:                                    target_to_host_bitmask(arg3, fcntl_flags_tbl),
                   5131:                                    arg4));
                   5132:         unlock_user(p, arg2, 0);
                   5133:         break;
                   5134: #endif
1.1       root     5135:     case TARGET_NR_close:
                   5136:         ret = get_errno(close(arg1));
                   5137:         break;
                   5138:     case TARGET_NR_brk:
1.1.1.3   root     5139:         ret = do_brk(arg1);
1.1       root     5140:         break;
                   5141:     case TARGET_NR_fork:
1.1.1.7   root     5142:         ret = get_errno(do_fork(cpu_env, SIGCHLD, 0, 0, 0, 0));
1.1       root     5143:         break;
1.1.1.6   root     5144: #ifdef TARGET_NR_waitpid
1.1       root     5145:     case TARGET_NR_waitpid:
                   5146:         {
1.1.1.3   root     5147:             int status;
                   5148:             ret = get_errno(waitpid(arg1, &status, arg3));
1.1.1.14! root     5149:             if (!is_error(ret) && arg2 && ret
1.1.1.8   root     5150:                 && put_user_s32(host_to_target_waitstatus(status), arg2))
1.1.1.6   root     5151:                 goto efault;
1.1       root     5152:         }
                   5153:         break;
1.1.1.6   root     5154: #endif
1.1.1.7   root     5155: #ifdef TARGET_NR_waitid
                   5156:     case TARGET_NR_waitid:
                   5157:         {
                   5158:             siginfo_t info;
                   5159:             info.si_pid = 0;
                   5160:             ret = get_errno(waitid(arg1, arg2, &info, arg4));
                   5161:             if (!is_error(ret) && arg3 && info.si_pid != 0) {
                   5162:                 if (!(p = lock_user(VERIFY_WRITE, arg3, sizeof(target_siginfo_t), 0)))
                   5163:                     goto efault;
                   5164:                 host_to_target_siginfo(p, &info);
                   5165:                 unlock_user(p, arg3, sizeof(target_siginfo_t));
                   5166:             }
                   5167:         }
                   5168:         break;
                   5169: #endif
1.1.1.6   root     5170: #ifdef TARGET_NR_creat /* not on alpha */
1.1       root     5171:     case TARGET_NR_creat:
1.1.1.6   root     5172:         if (!(p = lock_user_string(arg1)))
                   5173:             goto efault;
1.1.1.3   root     5174:         ret = get_errno(creat(p, arg2));
                   5175:         unlock_user(p, arg1, 0);
1.1       root     5176:         break;
1.1.1.6   root     5177: #endif
1.1       root     5178:     case TARGET_NR_link:
1.1.1.3   root     5179:         {
                   5180:             void * p2;
                   5181:             p = lock_user_string(arg1);
                   5182:             p2 = lock_user_string(arg2);
1.1.1.6   root     5183:             if (!p || !p2)
                   5184:                 ret = -TARGET_EFAULT;
                   5185:             else
                   5186:                 ret = get_errno(link(p, p2));
1.1.1.3   root     5187:             unlock_user(p2, arg2, 0);
                   5188:             unlock_user(p, arg1, 0);
                   5189:         }
1.1       root     5190:         break;
1.1.1.6   root     5191: #if defined(TARGET_NR_linkat) && defined(__NR_linkat)
                   5192:     case TARGET_NR_linkat:
                   5193:         {
                   5194:             void * p2 = NULL;
                   5195:             if (!arg2 || !arg4)
                   5196:                 goto efault;
                   5197:             p  = lock_user_string(arg2);
                   5198:             p2 = lock_user_string(arg4);
                   5199:             if (!p || !p2)
                   5200:                 ret = -TARGET_EFAULT;
                   5201:             else
                   5202:                 ret = get_errno(sys_linkat(arg1, p, arg3, p2, arg5));
                   5203:             unlock_user(p, arg2, 0);
                   5204:             unlock_user(p2, arg4, 0);
                   5205:         }
                   5206:         break;
                   5207: #endif
1.1       root     5208:     case TARGET_NR_unlink:
1.1.1.6   root     5209:         if (!(p = lock_user_string(arg1)))
                   5210:             goto efault;
1.1.1.3   root     5211:         ret = get_errno(unlink(p));
                   5212:         unlock_user(p, arg1, 0);
1.1       root     5213:         break;
1.1.1.6   root     5214: #if defined(TARGET_NR_unlinkat) && defined(__NR_unlinkat)
                   5215:     case TARGET_NR_unlinkat:
                   5216:         if (!(p = lock_user_string(arg2)))
                   5217:             goto efault;
                   5218:         ret = get_errno(sys_unlinkat(arg1, p, arg3));
                   5219:         unlock_user(p, arg2, 0);
                   5220:         break;
                   5221: #endif
1.1       root     5222:     case TARGET_NR_execve:
                   5223:         {
                   5224:             char **argp, **envp;
                   5225:             int argc, envc;
1.1.1.6   root     5226:             abi_ulong gp;
                   5227:             abi_ulong guest_argp;
                   5228:             abi_ulong guest_envp;
                   5229:             abi_ulong addr;
1.1       root     5230:             char **q;
1.1.1.14! root     5231:             int total_size = 0;
1.1       root     5232: 
                   5233:             argc = 0;
1.1.1.3   root     5234:             guest_argp = arg2;
1.1.1.7   root     5235:             for (gp = guest_argp; gp; gp += sizeof(abi_ulong)) {
1.1.1.6   root     5236:                 if (get_user_ual(addr, gp))
                   5237:                     goto efault;
                   5238:                 if (!addr)
                   5239:                     break;
1.1       root     5240:                 argc++;
1.1.1.6   root     5241:             }
1.1       root     5242:             envc = 0;
1.1.1.3   root     5243:             guest_envp = arg3;
1.1.1.7   root     5244:             for (gp = guest_envp; gp; gp += sizeof(abi_ulong)) {
1.1.1.6   root     5245:                 if (get_user_ual(addr, gp))
                   5246:                     goto efault;
                   5247:                 if (!addr)
                   5248:                     break;
1.1       root     5249:                 envc++;
1.1.1.6   root     5250:             }
1.1       root     5251: 
                   5252:             argp = alloca((argc + 1) * sizeof(void *));
                   5253:             envp = alloca((envc + 1) * sizeof(void *));
                   5254: 
1.1.1.7   root     5255:             for (gp = guest_argp, q = argp; gp;
1.1.1.6   root     5256:                   gp += sizeof(abi_ulong), q++) {
                   5257:                 if (get_user_ual(addr, gp))
                   5258:                     goto execve_efault;
1.1.1.3   root     5259:                 if (!addr)
                   5260:                     break;
1.1.1.6   root     5261:                 if (!(*q = lock_user_string(addr)))
                   5262:                     goto execve_efault;
1.1.1.14! root     5263:                 total_size += strlen(*q) + 1;
1.1.1.3   root     5264:             }
1.1       root     5265:             *q = NULL;
                   5266: 
1.1.1.7   root     5267:             for (gp = guest_envp, q = envp; gp;
1.1.1.6   root     5268:                   gp += sizeof(abi_ulong), q++) {
                   5269:                 if (get_user_ual(addr, gp))
                   5270:                     goto execve_efault;
1.1.1.3   root     5271:                 if (!addr)
                   5272:                     break;
1.1.1.6   root     5273:                 if (!(*q = lock_user_string(addr)))
                   5274:                     goto execve_efault;
1.1.1.14! root     5275:                 total_size += strlen(*q) + 1;
1.1.1.3   root     5276:             }
1.1       root     5277:             *q = NULL;
                   5278: 
1.1.1.14! root     5279:             /* This case will not be caught by the host's execve() if its
        !          5280:                page size is bigger than the target's. */
        !          5281:             if (total_size > MAX_ARG_PAGES * TARGET_PAGE_SIZE) {
        !          5282:                 ret = -TARGET_E2BIG;
        !          5283:                 goto execve_end;
        !          5284:             }
1.1.1.6   root     5285:             if (!(p = lock_user_string(arg1)))
                   5286:                 goto execve_efault;
1.1.1.3   root     5287:             ret = get_errno(execve(p, argp, envp));
                   5288:             unlock_user(p, arg1, 0);
                   5289: 
1.1.1.6   root     5290:             goto execve_end;
                   5291: 
                   5292:         execve_efault:
                   5293:             ret = -TARGET_EFAULT;
                   5294: 
                   5295:         execve_end:
1.1.1.3   root     5296:             for (gp = guest_argp, q = argp; *q;
1.1.1.6   root     5297:                   gp += sizeof(abi_ulong), q++) {
                   5298:                 if (get_user_ual(addr, gp)
                   5299:                     || !addr)
                   5300:                     break;
1.1.1.3   root     5301:                 unlock_user(*q, addr, 0);
                   5302:             }
                   5303:             for (gp = guest_envp, q = envp; *q;
1.1.1.6   root     5304:                   gp += sizeof(abi_ulong), q++) {
                   5305:                 if (get_user_ual(addr, gp)
                   5306:                     || !addr)
                   5307:                     break;
1.1.1.3   root     5308:                 unlock_user(*q, addr, 0);
                   5309:             }
1.1       root     5310:         }
                   5311:         break;
                   5312:     case TARGET_NR_chdir:
1.1.1.6   root     5313:         if (!(p = lock_user_string(arg1)))
                   5314:             goto efault;
1.1.1.3   root     5315:         ret = get_errno(chdir(p));
                   5316:         unlock_user(p, arg1, 0);
1.1       root     5317:         break;
                   5318: #ifdef TARGET_NR_time
                   5319:     case TARGET_NR_time:
                   5320:         {
1.1.1.3   root     5321:             time_t host_time;
                   5322:             ret = get_errno(time(&host_time));
1.1.1.6   root     5323:             if (!is_error(ret)
                   5324:                 && arg1
                   5325:                 && put_user_sal(host_time, arg1))
                   5326:                 goto efault;
1.1       root     5327:         }
                   5328:         break;
                   5329: #endif
                   5330:     case TARGET_NR_mknod:
1.1.1.6   root     5331:         if (!(p = lock_user_string(arg1)))
                   5332:             goto efault;
1.1.1.3   root     5333:         ret = get_errno(mknod(p, arg2, arg3));
                   5334:         unlock_user(p, arg1, 0);
1.1       root     5335:         break;
1.1.1.6   root     5336: #if defined(TARGET_NR_mknodat) && defined(__NR_mknodat)
                   5337:     case TARGET_NR_mknodat:
                   5338:         if (!(p = lock_user_string(arg2)))
                   5339:             goto efault;
                   5340:         ret = get_errno(sys_mknodat(arg1, p, arg3, arg4));
                   5341:         unlock_user(p, arg2, 0);
                   5342:         break;
                   5343: #endif
1.1       root     5344:     case TARGET_NR_chmod:
1.1.1.6   root     5345:         if (!(p = lock_user_string(arg1)))
                   5346:             goto efault;
1.1.1.3   root     5347:         ret = get_errno(chmod(p, arg2));
                   5348:         unlock_user(p, arg1, 0);
1.1       root     5349:         break;
                   5350: #ifdef TARGET_NR_break
                   5351:     case TARGET_NR_break:
                   5352:         goto unimplemented;
                   5353: #endif
                   5354: #ifdef TARGET_NR_oldstat
                   5355:     case TARGET_NR_oldstat:
                   5356:         goto unimplemented;
                   5357: #endif
                   5358:     case TARGET_NR_lseek:
                   5359:         ret = get_errno(lseek(arg1, arg2, arg3));
                   5360:         break;
1.1.1.10  root     5361: #if defined(TARGET_NR_getxpid) && defined(TARGET_ALPHA)
                   5362:     /* Alpha specific */
1.1.1.6   root     5363:     case TARGET_NR_getxpid:
1.1.1.10  root     5364:         ((CPUAlphaState *)cpu_env)->ir[IR_A4] = getppid();
                   5365:         ret = get_errno(getpid());
                   5366:         break;
1.1.1.6   root     5367: #endif
1.1.1.10  root     5368: #ifdef TARGET_NR_getpid
                   5369:     case TARGET_NR_getpid:
1.1       root     5370:         ret = get_errno(getpid());
                   5371:         break;
1.1.1.10  root     5372: #endif
1.1       root     5373:     case TARGET_NR_mount:
1.1.1.6   root     5374:                {
                   5375:                        /* need to look at the data field */
                   5376:                        void *p2, *p3;
                   5377:                        p = lock_user_string(arg1);
                   5378:                        p2 = lock_user_string(arg2);
                   5379:                        p3 = lock_user_string(arg3);
                   5380:                         if (!p || !p2 || !p3)
                   5381:                             ret = -TARGET_EFAULT;
1.1.1.9   root     5382:                         else {
1.1.1.6   root     5383:                             /* FIXME - arg5 should be locked, but it isn't clear how to
                   5384:                              * do that since it's not guaranteed to be a NULL-terminated
                   5385:                              * string.
                   5386:                              */
1.1.1.9   root     5387:                             if ( ! arg5 )
                   5388:                                 ret = get_errno(mount(p, p2, p3, (unsigned long)arg4, NULL));
                   5389:                             else
                   5390:                                 ret = get_errno(mount(p, p2, p3, (unsigned long)arg4, g2h(arg5)));
                   5391:                         }
1.1.1.6   root     5392:                         unlock_user(p, arg1, 0);
                   5393:                         unlock_user(p2, arg2, 0);
                   5394:                         unlock_user(p3, arg3, 0);
                   5395:                        break;
                   5396:                }
                   5397: #ifdef TARGET_NR_umount
1.1       root     5398:     case TARGET_NR_umount:
1.1.1.6   root     5399:         if (!(p = lock_user_string(arg1)))
                   5400:             goto efault;
1.1.1.3   root     5401:         ret = get_errno(umount(p));
                   5402:         unlock_user(p, arg1, 0);
1.1       root     5403:         break;
1.1.1.6   root     5404: #endif
                   5405: #ifdef TARGET_NR_stime /* not on alpha */
1.1       root     5406:     case TARGET_NR_stime:
                   5407:         {
1.1.1.3   root     5408:             time_t host_time;
1.1.1.6   root     5409:             if (get_user_sal(host_time, arg1))
                   5410:                 goto efault;
1.1.1.3   root     5411:             ret = get_errno(stime(&host_time));
1.1       root     5412:         }
                   5413:         break;
1.1.1.6   root     5414: #endif
1.1       root     5415:     case TARGET_NR_ptrace:
                   5416:         goto unimplemented;
1.1.1.6   root     5417: #ifdef TARGET_NR_alarm /* not on alpha */
1.1       root     5418:     case TARGET_NR_alarm:
                   5419:         ret = alarm(arg1);
                   5420:         break;
1.1.1.6   root     5421: #endif
1.1       root     5422: #ifdef TARGET_NR_oldfstat
                   5423:     case TARGET_NR_oldfstat:
                   5424:         goto unimplemented;
                   5425: #endif
1.1.1.6   root     5426: #ifdef TARGET_NR_pause /* not on alpha */
1.1       root     5427:     case TARGET_NR_pause:
                   5428:         ret = get_errno(pause());
                   5429:         break;
1.1.1.6   root     5430: #endif
                   5431: #ifdef TARGET_NR_utime
1.1       root     5432:     case TARGET_NR_utime:
                   5433:         {
1.1.1.3   root     5434:             struct utimbuf tbuf, *host_tbuf;
                   5435:             struct target_utimbuf *target_tbuf;
                   5436:             if (arg2) {
1.1.1.6   root     5437:                 if (!lock_user_struct(VERIFY_READ, target_tbuf, arg2, 1))
                   5438:                     goto efault;
1.1.1.13  root     5439:                 tbuf.actime = tswapal(target_tbuf->actime);
                   5440:                 tbuf.modtime = tswapal(target_tbuf->modtime);
1.1.1.3   root     5441:                 unlock_user_struct(target_tbuf, arg2, 0);
                   5442:                 host_tbuf = &tbuf;
1.1       root     5443:             } else {
1.1.1.3   root     5444:                 host_tbuf = NULL;
1.1       root     5445:             }
1.1.1.6   root     5446:             if (!(p = lock_user_string(arg1)))
                   5447:                 goto efault;
1.1.1.3   root     5448:             ret = get_errno(utime(p, host_tbuf));
                   5449:             unlock_user(p, arg1, 0);
1.1       root     5450:         }
                   5451:         break;
1.1.1.6   root     5452: #endif
1.1       root     5453:     case TARGET_NR_utimes:
                   5454:         {
                   5455:             struct timeval *tvp, tv[2];
1.1.1.3   root     5456:             if (arg2) {
1.1.1.6   root     5457:                 if (copy_from_user_timeval(&tv[0], arg2)
                   5458:                     || copy_from_user_timeval(&tv[1],
                   5459:                                               arg2 + sizeof(struct target_timeval)))
                   5460:                     goto efault;
1.1       root     5461:                 tvp = tv;
                   5462:             } else {
                   5463:                 tvp = NULL;
                   5464:             }
1.1.1.6   root     5465:             if (!(p = lock_user_string(arg1)))
                   5466:                 goto efault;
1.1.1.3   root     5467:             ret = get_errno(utimes(p, tvp));
                   5468:             unlock_user(p, arg1, 0);
1.1       root     5469:         }
                   5470:         break;
1.1.1.7   root     5471: #if defined(TARGET_NR_futimesat) && defined(__NR_futimesat)
                   5472:     case TARGET_NR_futimesat:
                   5473:         {
                   5474:             struct timeval *tvp, tv[2];
                   5475:             if (arg3) {
                   5476:                 if (copy_from_user_timeval(&tv[0], arg3)
                   5477:                     || copy_from_user_timeval(&tv[1],
                   5478:                                               arg3 + sizeof(struct target_timeval)))
                   5479:                     goto efault;
                   5480:                 tvp = tv;
                   5481:             } else {
                   5482:                 tvp = NULL;
                   5483:             }
                   5484:             if (!(p = lock_user_string(arg2)))
                   5485:                 goto efault;
                   5486:             ret = get_errno(sys_futimesat(arg1, path(p), tvp));
                   5487:             unlock_user(p, arg2, 0);
                   5488:         }
                   5489:         break;
                   5490: #endif
1.1       root     5491: #ifdef TARGET_NR_stty
                   5492:     case TARGET_NR_stty:
                   5493:         goto unimplemented;
                   5494: #endif
                   5495: #ifdef TARGET_NR_gtty
                   5496:     case TARGET_NR_gtty:
                   5497:         goto unimplemented;
                   5498: #endif
                   5499:     case TARGET_NR_access:
1.1.1.6   root     5500:         if (!(p = lock_user_string(arg1)))
                   5501:             goto efault;
1.1.1.8   root     5502:         ret = get_errno(access(path(p), arg2));
1.1.1.3   root     5503:         unlock_user(p, arg1, 0);
1.1       root     5504:         break;
1.1.1.6   root     5505: #if defined(TARGET_NR_faccessat) && defined(__NR_faccessat)
                   5506:     case TARGET_NR_faccessat:
                   5507:         if (!(p = lock_user_string(arg2)))
                   5508:             goto efault;
1.1.1.8   root     5509:         ret = get_errno(sys_faccessat(arg1, p, arg3));
1.1.1.6   root     5510:         unlock_user(p, arg2, 0);
                   5511:         break;
                   5512: #endif
                   5513: #ifdef TARGET_NR_nice /* not on alpha */
1.1       root     5514:     case TARGET_NR_nice:
                   5515:         ret = get_errno(nice(arg1));
                   5516:         break;
1.1.1.6   root     5517: #endif
1.1       root     5518: #ifdef TARGET_NR_ftime
                   5519:     case TARGET_NR_ftime:
                   5520:         goto unimplemented;
                   5521: #endif
                   5522:     case TARGET_NR_sync:
                   5523:         sync();
                   5524:         ret = 0;
                   5525:         break;
                   5526:     case TARGET_NR_kill:
1.1.1.7   root     5527:         ret = get_errno(kill(arg1, target_to_host_signal(arg2)));
1.1       root     5528:         break;
                   5529:     case TARGET_NR_rename:
1.1.1.3   root     5530:         {
                   5531:             void *p2;
                   5532:             p = lock_user_string(arg1);
                   5533:             p2 = lock_user_string(arg2);
1.1.1.6   root     5534:             if (!p || !p2)
                   5535:                 ret = -TARGET_EFAULT;
                   5536:             else
                   5537:                 ret = get_errno(rename(p, p2));
1.1.1.3   root     5538:             unlock_user(p2, arg2, 0);
                   5539:             unlock_user(p, arg1, 0);
                   5540:         }
1.1       root     5541:         break;
1.1.1.6   root     5542: #if defined(TARGET_NR_renameat) && defined(__NR_renameat)
                   5543:     case TARGET_NR_renameat:
                   5544:         {
                   5545:             void *p2;
                   5546:             p  = lock_user_string(arg2);
                   5547:             p2 = lock_user_string(arg4);
                   5548:             if (!p || !p2)
                   5549:                 ret = -TARGET_EFAULT;
                   5550:             else
                   5551:                 ret = get_errno(sys_renameat(arg1, p, arg3, p2));
                   5552:             unlock_user(p2, arg4, 0);
                   5553:             unlock_user(p, arg2, 0);
                   5554:         }
                   5555:         break;
                   5556: #endif
1.1       root     5557:     case TARGET_NR_mkdir:
1.1.1.6   root     5558:         if (!(p = lock_user_string(arg1)))
                   5559:             goto efault;
1.1.1.3   root     5560:         ret = get_errno(mkdir(p, arg2));
                   5561:         unlock_user(p, arg1, 0);
1.1       root     5562:         break;
1.1.1.6   root     5563: #if defined(TARGET_NR_mkdirat) && defined(__NR_mkdirat)
                   5564:     case TARGET_NR_mkdirat:
                   5565:         if (!(p = lock_user_string(arg2)))
                   5566:             goto efault;
                   5567:         ret = get_errno(sys_mkdirat(arg1, p, arg3));
                   5568:         unlock_user(p, arg2, 0);
                   5569:         break;
                   5570: #endif
1.1       root     5571:     case TARGET_NR_rmdir:
1.1.1.6   root     5572:         if (!(p = lock_user_string(arg1)))
                   5573:             goto efault;
1.1.1.3   root     5574:         ret = get_errno(rmdir(p));
                   5575:         unlock_user(p, arg1, 0);
1.1       root     5576:         break;
                   5577:     case TARGET_NR_dup:
                   5578:         ret = get_errno(dup(arg1));
                   5579:         break;
                   5580:     case TARGET_NR_pipe:
1.1.1.10  root     5581:         ret = do_pipe(cpu_env, arg1, 0, 0);
1.1       root     5582:         break;
1.1.1.8   root     5583: #ifdef TARGET_NR_pipe2
                   5584:     case TARGET_NR_pipe2:
1.1.1.10  root     5585:         ret = do_pipe(cpu_env, arg1, arg2, 1);
1.1.1.8   root     5586:         break;
                   5587: #endif
1.1       root     5588:     case TARGET_NR_times:
                   5589:         {
1.1.1.3   root     5590:             struct target_tms *tmsp;
1.1       root     5591:             struct tms tms;
                   5592:             ret = get_errno(times(&tms));
1.1.1.3   root     5593:             if (arg1) {
1.1.1.6   root     5594:                 tmsp = lock_user(VERIFY_WRITE, arg1, sizeof(struct target_tms), 0);
                   5595:                 if (!tmsp)
                   5596:                     goto efault;
1.1.1.13  root     5597:                 tmsp->tms_utime = tswapal(host_to_target_clock_t(tms.tms_utime));
                   5598:                 tmsp->tms_stime = tswapal(host_to_target_clock_t(tms.tms_stime));
                   5599:                 tmsp->tms_cutime = tswapal(host_to_target_clock_t(tms.tms_cutime));
                   5600:                 tmsp->tms_cstime = tswapal(host_to_target_clock_t(tms.tms_cstime));
1.1       root     5601:             }
                   5602:             if (!is_error(ret))
                   5603:                 ret = host_to_target_clock_t(ret);
                   5604:         }
                   5605:         break;
                   5606: #ifdef TARGET_NR_prof
                   5607:     case TARGET_NR_prof:
                   5608:         goto unimplemented;
                   5609: #endif
1.1.1.6   root     5610: #ifdef TARGET_NR_signal
1.1       root     5611:     case TARGET_NR_signal:
                   5612:         goto unimplemented;
1.1.1.6   root     5613: #endif
1.1       root     5614:     case TARGET_NR_acct:
1.1.1.7   root     5615:         if (arg1 == 0) {
                   5616:             ret = get_errno(acct(NULL));
                   5617:         } else {
                   5618:             if (!(p = lock_user_string(arg1)))
                   5619:                 goto efault;
                   5620:             ret = get_errno(acct(path(p)));
                   5621:             unlock_user(p, arg1, 0);
                   5622:         }
1.1.1.3   root     5623:         break;
1.1.1.6   root     5624: #ifdef TARGET_NR_umount2 /* not on alpha */
1.1       root     5625:     case TARGET_NR_umount2:
1.1.1.6   root     5626:         if (!(p = lock_user_string(arg1)))
                   5627:             goto efault;
1.1.1.3   root     5628:         ret = get_errno(umount2(p, arg2));
                   5629:         unlock_user(p, arg1, 0);
1.1       root     5630:         break;
1.1.1.6   root     5631: #endif
1.1       root     5632: #ifdef TARGET_NR_lock
                   5633:     case TARGET_NR_lock:
                   5634:         goto unimplemented;
                   5635: #endif
                   5636:     case TARGET_NR_ioctl:
                   5637:         ret = do_ioctl(arg1, arg2, arg3);
                   5638:         break;
                   5639:     case TARGET_NR_fcntl:
1.1.1.6   root     5640:         ret = do_fcntl(arg1, arg2, arg3);
1.1       root     5641:         break;
                   5642: #ifdef TARGET_NR_mpx
                   5643:     case TARGET_NR_mpx:
                   5644:         goto unimplemented;
                   5645: #endif
                   5646:     case TARGET_NR_setpgid:
                   5647:         ret = get_errno(setpgid(arg1, arg2));
                   5648:         break;
                   5649: #ifdef TARGET_NR_ulimit
                   5650:     case TARGET_NR_ulimit:
                   5651:         goto unimplemented;
                   5652: #endif
                   5653: #ifdef TARGET_NR_oldolduname
                   5654:     case TARGET_NR_oldolduname:
                   5655:         goto unimplemented;
                   5656: #endif
                   5657:     case TARGET_NR_umask:
                   5658:         ret = get_errno(umask(arg1));
                   5659:         break;
                   5660:     case TARGET_NR_chroot:
1.1.1.6   root     5661:         if (!(p = lock_user_string(arg1)))
                   5662:             goto efault;
1.1.1.3   root     5663:         ret = get_errno(chroot(p));
                   5664:         unlock_user(p, arg1, 0);
1.1       root     5665:         break;
                   5666:     case TARGET_NR_ustat:
                   5667:         goto unimplemented;
                   5668:     case TARGET_NR_dup2:
                   5669:         ret = get_errno(dup2(arg1, arg2));
                   5670:         break;
1.1.1.9   root     5671: #if defined(CONFIG_DUP3) && defined(TARGET_NR_dup3)
                   5672:     case TARGET_NR_dup3:
                   5673:         ret = get_errno(dup3(arg1, arg2, arg3));
                   5674:         break;
                   5675: #endif
1.1.1.6   root     5676: #ifdef TARGET_NR_getppid /* not on alpha */
1.1       root     5677:     case TARGET_NR_getppid:
                   5678:         ret = get_errno(getppid());
                   5679:         break;
1.1.1.6   root     5680: #endif
1.1       root     5681:     case TARGET_NR_getpgrp:
                   5682:         ret = get_errno(getpgrp());
                   5683:         break;
                   5684:     case TARGET_NR_setsid:
                   5685:         ret = get_errno(setsid());
                   5686:         break;
1.1.1.6   root     5687: #ifdef TARGET_NR_sigaction
1.1       root     5688:     case TARGET_NR_sigaction:
                   5689:         {
1.1.1.10  root     5690: #if defined(TARGET_ALPHA)
                   5691:             struct target_sigaction act, oact, *pact = 0;
1.1.1.3   root     5692:             struct target_old_sigaction *old_act;
                   5693:             if (arg2) {
1.1.1.6   root     5694:                 if (!lock_user_struct(VERIFY_READ, old_act, arg2, 1))
                   5695:                     goto efault;
1.1       root     5696:                 act._sa_handler = old_act->_sa_handler;
                   5697:                 target_siginitset(&act.sa_mask, old_act->sa_mask);
                   5698:                 act.sa_flags = old_act->sa_flags;
1.1.1.10  root     5699:                 act.sa_restorer = 0;
1.1.1.3   root     5700:                 unlock_user_struct(old_act, arg2, 0);
1.1       root     5701:                 pact = &act;
                   5702:             }
                   5703:             ret = get_errno(do_sigaction(arg1, pact, &oact));
1.1.1.3   root     5704:             if (!is_error(ret) && arg3) {
1.1.1.6   root     5705:                 if (!lock_user_struct(VERIFY_WRITE, old_act, arg3, 0))
                   5706:                     goto efault;
1.1.1.3   root     5707:                 old_act->_sa_handler = oact._sa_handler;
                   5708:                 old_act->sa_mask = oact.sa_mask.sig[0];
                   5709:                 old_act->sa_flags = oact.sa_flags;
                   5710:                 unlock_user_struct(old_act, arg3, 1);
1.1       root     5711:             }
1.1.1.10  root     5712: #elif defined(TARGET_MIPS)
1.1.1.4   root     5713:            struct target_sigaction act, oact, *pact, *old_act;
                   5714: 
                   5715:            if (arg2) {
1.1.1.6   root     5716:                 if (!lock_user_struct(VERIFY_READ, old_act, arg2, 1))
                   5717:                     goto efault;
1.1.1.4   root     5718:                act._sa_handler = old_act->_sa_handler;
                   5719:                target_siginitset(&act.sa_mask, old_act->sa_mask.sig[0]);
                   5720:                act.sa_flags = old_act->sa_flags;
                   5721:                unlock_user_struct(old_act, arg2, 0);
                   5722:                pact = &act;
                   5723:            } else {
                   5724:                pact = NULL;
                   5725:            }
                   5726: 
                   5727:            ret = get_errno(do_sigaction(arg1, pact, &oact));
                   5728: 
                   5729:            if (!is_error(ret) && arg3) {
1.1.1.6   root     5730:                 if (!lock_user_struct(VERIFY_WRITE, old_act, arg3, 0))
                   5731:                     goto efault;
1.1.1.4   root     5732:                old_act->_sa_handler = oact._sa_handler;
                   5733:                old_act->sa_flags = oact.sa_flags;
                   5734:                old_act->sa_mask.sig[0] = oact.sa_mask.sig[0];
                   5735:                old_act->sa_mask.sig[1] = 0;
                   5736:                old_act->sa_mask.sig[2] = 0;
                   5737:                old_act->sa_mask.sig[3] = 0;
                   5738:                unlock_user_struct(old_act, arg3, 1);
                   5739:            }
1.1.1.10  root     5740: #else
                   5741:             struct target_old_sigaction *old_act;
                   5742:             struct target_sigaction act, oact, *pact;
                   5743:             if (arg2) {
                   5744:                 if (!lock_user_struct(VERIFY_READ, old_act, arg2, 1))
                   5745:                     goto efault;
                   5746:                 act._sa_handler = old_act->_sa_handler;
                   5747:                 target_siginitset(&act.sa_mask, old_act->sa_mask);
                   5748:                 act.sa_flags = old_act->sa_flags;
                   5749:                 act.sa_restorer = old_act->sa_restorer;
                   5750:                 unlock_user_struct(old_act, arg2, 0);
                   5751:                 pact = &act;
                   5752:             } else {
                   5753:                 pact = NULL;
                   5754:             }
                   5755:             ret = get_errno(do_sigaction(arg1, pact, &oact));
                   5756:             if (!is_error(ret) && arg3) {
                   5757:                 if (!lock_user_struct(VERIFY_WRITE, old_act, arg3, 0))
                   5758:                     goto efault;
                   5759:                 old_act->_sa_handler = oact._sa_handler;
                   5760:                 old_act->sa_mask = oact.sa_mask.sig[0];
                   5761:                 old_act->sa_flags = oact.sa_flags;
                   5762:                 old_act->sa_restorer = oact.sa_restorer;
                   5763:                 unlock_user_struct(old_act, arg3, 1);
                   5764:             }
1.1.1.6   root     5765: #endif
1.1       root     5766:         }
                   5767:         break;
1.1.1.6   root     5768: #endif
1.1       root     5769:     case TARGET_NR_rt_sigaction:
1.1.1.3   root     5770:         {
1.1.1.10  root     5771: #if defined(TARGET_ALPHA)
                   5772:             struct target_sigaction act, oact, *pact = 0;
                   5773:             struct target_rt_sigaction *rt_act;
                   5774:             /* ??? arg4 == sizeof(sigset_t).  */
                   5775:             if (arg2) {
                   5776:                 if (!lock_user_struct(VERIFY_READ, rt_act, arg2, 1))
                   5777:                     goto efault;
                   5778:                 act._sa_handler = rt_act->_sa_handler;
                   5779:                 act.sa_mask = rt_act->sa_mask;
                   5780:                 act.sa_flags = rt_act->sa_flags;
                   5781:                 act.sa_restorer = arg5;
                   5782:                 unlock_user_struct(rt_act, arg2, 0);
                   5783:                 pact = &act;
                   5784:             }
                   5785:             ret = get_errno(do_sigaction(arg1, pact, &oact));
                   5786:             if (!is_error(ret) && arg3) {
                   5787:                 if (!lock_user_struct(VERIFY_WRITE, rt_act, arg3, 0))
                   5788:                     goto efault;
                   5789:                 rt_act->_sa_handler = oact._sa_handler;
                   5790:                 rt_act->sa_mask = oact.sa_mask;
                   5791:                 rt_act->sa_flags = oact.sa_flags;
                   5792:                 unlock_user_struct(rt_act, arg3, 1);
                   5793:             }
                   5794: #else
1.1.1.3   root     5795:             struct target_sigaction *act;
                   5796:             struct target_sigaction *oact;
                   5797: 
1.1.1.6   root     5798:             if (arg2) {
                   5799:                 if (!lock_user_struct(VERIFY_READ, act, arg2, 1))
                   5800:                     goto efault;
                   5801:             } else
1.1.1.3   root     5802:                 act = NULL;
1.1.1.6   root     5803:             if (arg3) {
                   5804:                 if (!lock_user_struct(VERIFY_WRITE, oact, arg3, 0)) {
                   5805:                     ret = -TARGET_EFAULT;
                   5806:                     goto rt_sigaction_fail;
                   5807:                 }
                   5808:             } else
1.1.1.3   root     5809:                 oact = NULL;
                   5810:             ret = get_errno(do_sigaction(arg1, act, oact));
1.1.1.6   root     5811:        rt_sigaction_fail:
                   5812:             if (act)
1.1.1.3   root     5813:                 unlock_user_struct(act, arg2, 0);
1.1.1.6   root     5814:             if (oact)
1.1.1.3   root     5815:                 unlock_user_struct(oact, arg3, 1);
1.1.1.10  root     5816: #endif
1.1.1.3   root     5817:         }
1.1       root     5818:         break;
1.1.1.6   root     5819: #ifdef TARGET_NR_sgetmask /* not on alpha */
1.1       root     5820:     case TARGET_NR_sgetmask:
                   5821:         {
                   5822:             sigset_t cur_set;
1.1.1.6   root     5823:             abi_ulong target_set;
1.1       root     5824:             sigprocmask(0, NULL, &cur_set);
                   5825:             host_to_target_old_sigset(&target_set, &cur_set);
                   5826:             ret = target_set;
                   5827:         }
                   5828:         break;
1.1.1.6   root     5829: #endif
                   5830: #ifdef TARGET_NR_ssetmask /* not on alpha */
1.1       root     5831:     case TARGET_NR_ssetmask:
                   5832:         {
                   5833:             sigset_t set, oset, cur_set;
1.1.1.6   root     5834:             abi_ulong target_set = arg1;
1.1       root     5835:             sigprocmask(0, NULL, &cur_set);
                   5836:             target_to_host_old_sigset(&set, &target_set);
                   5837:             sigorset(&set, &set, &cur_set);
                   5838:             sigprocmask(SIG_SETMASK, &set, &oset);
                   5839:             host_to_target_old_sigset(&target_set, &oset);
                   5840:             ret = target_set;
                   5841:         }
                   5842:         break;
1.1.1.6   root     5843: #endif
                   5844: #ifdef TARGET_NR_sigprocmask
1.1       root     5845:     case TARGET_NR_sigprocmask:
                   5846:         {
1.1.1.10  root     5847: #if defined(TARGET_ALPHA)
                   5848:             sigset_t set, oldset;
                   5849:             abi_ulong mask;
                   5850:             int how;
                   5851: 
                   5852:             switch (arg1) {
                   5853:             case TARGET_SIG_BLOCK:
                   5854:                 how = SIG_BLOCK;
                   5855:                 break;
                   5856:             case TARGET_SIG_UNBLOCK:
                   5857:                 how = SIG_UNBLOCK;
                   5858:                 break;
                   5859:             case TARGET_SIG_SETMASK:
                   5860:                 how = SIG_SETMASK;
                   5861:                 break;
                   5862:             default:
                   5863:                 ret = -TARGET_EINVAL;
                   5864:                 goto fail;
                   5865:             }
                   5866:             mask = arg2;
                   5867:             target_to_host_old_sigset(&set, &mask);
                   5868: 
                   5869:             ret = get_errno(sigprocmask(how, &set, &oldset));
                   5870: 
                   5871:             if (!is_error(ret)) {
                   5872:                 host_to_target_old_sigset(&mask, &oldset);
                   5873:                 ret = mask;
                   5874:                 ((CPUAlphaState *)cpu_env)->[IR_V0] = 0; /* force no error */
                   5875:             }
                   5876: #else
1.1       root     5877:             sigset_t set, oldset, *set_ptr;
1.1.1.10  root     5878:             int how;
1.1.1.6   root     5879: 
1.1.1.3   root     5880:             if (arg2) {
1.1.1.10  root     5881:                 switch (arg1) {
1.1       root     5882:                 case TARGET_SIG_BLOCK:
                   5883:                     how = SIG_BLOCK;
                   5884:                     break;
                   5885:                 case TARGET_SIG_UNBLOCK:
                   5886:                     how = SIG_UNBLOCK;
                   5887:                     break;
                   5888:                 case TARGET_SIG_SETMASK:
                   5889:                     how = SIG_SETMASK;
                   5890:                     break;
                   5891:                 default:
1.1.1.6   root     5892:                     ret = -TARGET_EINVAL;
1.1       root     5893:                     goto fail;
                   5894:                 }
1.1.1.6   root     5895:                 if (!(p = lock_user(VERIFY_READ, arg2, sizeof(target_sigset_t), 1)))
                   5896:                     goto efault;
1.1.1.3   root     5897:                 target_to_host_old_sigset(&set, p);
                   5898:                 unlock_user(p, arg2, 0);
1.1       root     5899:                 set_ptr = &set;
                   5900:             } else {
                   5901:                 how = 0;
                   5902:                 set_ptr = NULL;
                   5903:             }
1.1.1.10  root     5904:             ret = get_errno(sigprocmask(how, set_ptr, &oldset));
1.1.1.3   root     5905:             if (!is_error(ret) && arg3) {
1.1.1.6   root     5906:                 if (!(p = lock_user(VERIFY_WRITE, arg3, sizeof(target_sigset_t), 0)))
                   5907:                     goto efault;
1.1.1.3   root     5908:                 host_to_target_old_sigset(p, &oldset);
                   5909:                 unlock_user(p, arg3, sizeof(target_sigset_t));
1.1       root     5910:             }
1.1.1.10  root     5911: #endif
1.1       root     5912:         }
                   5913:         break;
1.1.1.6   root     5914: #endif
1.1       root     5915:     case TARGET_NR_rt_sigprocmask:
                   5916:         {
                   5917:             int how = arg1;
                   5918:             sigset_t set, oldset, *set_ptr;
1.1.1.6   root     5919: 
1.1.1.3   root     5920:             if (arg2) {
1.1       root     5921:                 switch(how) {
                   5922:                 case TARGET_SIG_BLOCK:
                   5923:                     how = SIG_BLOCK;
                   5924:                     break;
                   5925:                 case TARGET_SIG_UNBLOCK:
                   5926:                     how = SIG_UNBLOCK;
                   5927:                     break;
                   5928:                 case TARGET_SIG_SETMASK:
                   5929:                     how = SIG_SETMASK;
                   5930:                     break;
                   5931:                 default:
1.1.1.6   root     5932:                     ret = -TARGET_EINVAL;
1.1       root     5933:                     goto fail;
                   5934:                 }
1.1.1.6   root     5935:                 if (!(p = lock_user(VERIFY_READ, arg2, sizeof(target_sigset_t), 1)))
                   5936:                     goto efault;
1.1.1.3   root     5937:                 target_to_host_sigset(&set, p);
                   5938:                 unlock_user(p, arg2, 0);
1.1       root     5939:                 set_ptr = &set;
                   5940:             } else {
                   5941:                 how = 0;
                   5942:                 set_ptr = NULL;
                   5943:             }
                   5944:             ret = get_errno(sigprocmask(how, set_ptr, &oldset));
1.1.1.3   root     5945:             if (!is_error(ret) && arg3) {
1.1.1.6   root     5946:                 if (!(p = lock_user(VERIFY_WRITE, arg3, sizeof(target_sigset_t), 0)))
                   5947:                     goto efault;
1.1.1.3   root     5948:                 host_to_target_sigset(p, &oldset);
                   5949:                 unlock_user(p, arg3, sizeof(target_sigset_t));
1.1       root     5950:             }
                   5951:         }
                   5952:         break;
1.1.1.6   root     5953: #ifdef TARGET_NR_sigpending
1.1       root     5954:     case TARGET_NR_sigpending:
                   5955:         {
                   5956:             sigset_t set;
                   5957:             ret = get_errno(sigpending(&set));
                   5958:             if (!is_error(ret)) {
1.1.1.6   root     5959:                 if (!(p = lock_user(VERIFY_WRITE, arg1, sizeof(target_sigset_t), 0)))
                   5960:                     goto efault;
1.1.1.3   root     5961:                 host_to_target_old_sigset(p, &set);
                   5962:                 unlock_user(p, arg1, sizeof(target_sigset_t));
1.1       root     5963:             }
                   5964:         }
                   5965:         break;
1.1.1.6   root     5966: #endif
1.1       root     5967:     case TARGET_NR_rt_sigpending:
                   5968:         {
                   5969:             sigset_t set;
                   5970:             ret = get_errno(sigpending(&set));
                   5971:             if (!is_error(ret)) {
1.1.1.6   root     5972:                 if (!(p = lock_user(VERIFY_WRITE, arg1, sizeof(target_sigset_t), 0)))
                   5973:                     goto efault;
1.1.1.3   root     5974:                 host_to_target_sigset(p, &set);
                   5975:                 unlock_user(p, arg1, sizeof(target_sigset_t));
1.1       root     5976:             }
                   5977:         }
                   5978:         break;
1.1.1.6   root     5979: #ifdef TARGET_NR_sigsuspend
1.1       root     5980:     case TARGET_NR_sigsuspend:
                   5981:         {
                   5982:             sigset_t set;
1.1.1.10  root     5983: #if defined(TARGET_ALPHA)
                   5984:             abi_ulong mask = arg1;
                   5985:             target_to_host_old_sigset(&set, &mask);
                   5986: #else
1.1.1.6   root     5987:             if (!(p = lock_user(VERIFY_READ, arg1, sizeof(target_sigset_t), 1)))
                   5988:                 goto efault;
1.1.1.3   root     5989:             target_to_host_old_sigset(&set, p);
                   5990:             unlock_user(p, arg1, 0);
1.1.1.10  root     5991: #endif
1.1       root     5992:             ret = get_errno(sigsuspend(&set));
                   5993:         }
                   5994:         break;
1.1.1.6   root     5995: #endif
1.1       root     5996:     case TARGET_NR_rt_sigsuspend:
                   5997:         {
                   5998:             sigset_t set;
1.1.1.6   root     5999:             if (!(p = lock_user(VERIFY_READ, arg1, sizeof(target_sigset_t), 1)))
                   6000:                 goto efault;
1.1.1.3   root     6001:             target_to_host_sigset(&set, p);
                   6002:             unlock_user(p, arg1, 0);
1.1       root     6003:             ret = get_errno(sigsuspend(&set));
                   6004:         }
                   6005:         break;
                   6006:     case TARGET_NR_rt_sigtimedwait:
                   6007:         {
                   6008:             sigset_t set;
                   6009:             struct timespec uts, *puts;
                   6010:             siginfo_t uinfo;
1.1.1.6   root     6011: 
                   6012:             if (!(p = lock_user(VERIFY_READ, arg1, sizeof(target_sigset_t), 1)))
                   6013:                 goto efault;
1.1.1.3   root     6014:             target_to_host_sigset(&set, p);
                   6015:             unlock_user(p, arg1, 0);
                   6016:             if (arg3) {
1.1       root     6017:                 puts = &uts;
1.1.1.3   root     6018:                 target_to_host_timespec(puts, arg3);
1.1       root     6019:             } else {
                   6020:                 puts = NULL;
                   6021:             }
                   6022:             ret = get_errno(sigtimedwait(&set, &uinfo, puts));
1.1.1.3   root     6023:             if (!is_error(ret) && arg2) {
1.1.1.7   root     6024:                 if (!(p = lock_user(VERIFY_WRITE, arg2, sizeof(target_siginfo_t), 0)))
1.1.1.6   root     6025:                     goto efault;
1.1.1.3   root     6026:                 host_to_target_siginfo(p, &uinfo);
1.1.1.7   root     6027:                 unlock_user(p, arg2, sizeof(target_siginfo_t));
1.1       root     6028:             }
                   6029:         }
                   6030:         break;
                   6031:     case TARGET_NR_rt_sigqueueinfo:
                   6032:         {
                   6033:             siginfo_t uinfo;
1.1.1.6   root     6034:             if (!(p = lock_user(VERIFY_READ, arg3, sizeof(target_sigset_t), 1)))
                   6035:                 goto efault;
1.1.1.3   root     6036:             target_to_host_siginfo(&uinfo, p);
                   6037:             unlock_user(p, arg1, 0);
1.1       root     6038:             ret = get_errno(sys_rt_sigqueueinfo(arg1, arg2, &uinfo));
                   6039:         }
                   6040:         break;
1.1.1.6   root     6041: #ifdef TARGET_NR_sigreturn
1.1       root     6042:     case TARGET_NR_sigreturn:
                   6043:         /* NOTE: ret is eax, so not transcoding must be done */
                   6044:         ret = do_sigreturn(cpu_env);
                   6045:         break;
1.1.1.6   root     6046: #endif
1.1       root     6047:     case TARGET_NR_rt_sigreturn:
                   6048:         /* NOTE: ret is eax, so not transcoding must be done */
                   6049:         ret = do_rt_sigreturn(cpu_env);
                   6050:         break;
                   6051:     case TARGET_NR_sethostname:
1.1.1.6   root     6052:         if (!(p = lock_user_string(arg1)))
                   6053:             goto efault;
1.1.1.3   root     6054:         ret = get_errno(sethostname(p, arg2));
                   6055:         unlock_user(p, arg1, 0);
1.1       root     6056:         break;
                   6057:     case TARGET_NR_setrlimit:
                   6058:         {
1.1.1.12  root     6059:             int resource = target_to_host_resource(arg1);
1.1.1.3   root     6060:             struct target_rlimit *target_rlim;
1.1       root     6061:             struct rlimit rlim;
1.1.1.6   root     6062:             if (!lock_user_struct(VERIFY_READ, target_rlim, arg2, 1))
                   6063:                 goto efault;
1.1.1.10  root     6064:             rlim.rlim_cur = target_to_host_rlim(target_rlim->rlim_cur);
                   6065:             rlim.rlim_max = target_to_host_rlim(target_rlim->rlim_max);
1.1.1.3   root     6066:             unlock_user_struct(target_rlim, arg2, 0);
1.1       root     6067:             ret = get_errno(setrlimit(resource, &rlim));
                   6068:         }
                   6069:         break;
                   6070:     case TARGET_NR_getrlimit:
                   6071:         {
1.1.1.12  root     6072:             int resource = target_to_host_resource(arg1);
1.1.1.3   root     6073:             struct target_rlimit *target_rlim;
1.1       root     6074:             struct rlimit rlim;
1.1.1.6   root     6075: 
1.1       root     6076:             ret = get_errno(getrlimit(resource, &rlim));
                   6077:             if (!is_error(ret)) {
1.1.1.6   root     6078:                 if (!lock_user_struct(VERIFY_WRITE, target_rlim, arg2, 0))
                   6079:                     goto efault;
1.1.1.10  root     6080:                 target_rlim->rlim_cur = host_to_target_rlim(rlim.rlim_cur);
                   6081:                 target_rlim->rlim_max = host_to_target_rlim(rlim.rlim_max);
1.1.1.3   root     6082:                 unlock_user_struct(target_rlim, arg2, 1);
1.1       root     6083:             }
                   6084:         }
                   6085:         break;
                   6086:     case TARGET_NR_getrusage:
                   6087:         {
                   6088:             struct rusage rusage;
                   6089:             ret = get_errno(getrusage(arg1, &rusage));
                   6090:             if (!is_error(ret)) {
1.1.1.3   root     6091:                 host_to_target_rusage(arg2, &rusage);
1.1       root     6092:             }
                   6093:         }
                   6094:         break;
                   6095:     case TARGET_NR_gettimeofday:
                   6096:         {
                   6097:             struct timeval tv;
                   6098:             ret = get_errno(gettimeofday(&tv, NULL));
                   6099:             if (!is_error(ret)) {
1.1.1.6   root     6100:                 if (copy_to_user_timeval(arg1, &tv))
                   6101:                     goto efault;
1.1       root     6102:             }
                   6103:         }
                   6104:         break;
                   6105:     case TARGET_NR_settimeofday:
                   6106:         {
                   6107:             struct timeval tv;
1.1.1.6   root     6108:             if (copy_from_user_timeval(&tv, arg1))
                   6109:                 goto efault;
1.1       root     6110:             ret = get_errno(settimeofday(&tv, NULL));
                   6111:         }
                   6112:         break;
1.1.1.12  root     6113: #if defined(TARGET_NR_select) && !defined(TARGET_S390X) && !defined(TARGET_S390)
1.1       root     6114:     case TARGET_NR_select:
                   6115:         {
1.1.1.3   root     6116:             struct target_sel_arg_struct *sel;
1.1.1.6   root     6117:             abi_ulong inp, outp, exp, tvp;
1.1.1.3   root     6118:             long nsel;
                   6119: 
1.1.1.6   root     6120:             if (!lock_user_struct(VERIFY_READ, sel, arg1, 1))
                   6121:                 goto efault;
1.1.1.13  root     6122:             nsel = tswapal(sel->n);
                   6123:             inp = tswapal(sel->inp);
                   6124:             outp = tswapal(sel->outp);
                   6125:             exp = tswapal(sel->exp);
                   6126:             tvp = tswapal(sel->tvp);
1.1.1.3   root     6127:             unlock_user_struct(sel, arg1, 0);
                   6128:             ret = do_select(nsel, inp, outp, exp, tvp);
1.1       root     6129:         }
                   6130:         break;
1.1.1.2   root     6131: #endif
1.1.1.10  root     6132: #ifdef TARGET_NR_pselect6
                   6133:     case TARGET_NR_pselect6:
1.1.1.12  root     6134:         {
                   6135:             abi_long rfd_addr, wfd_addr, efd_addr, n, ts_addr;
                   6136:             fd_set rfds, wfds, efds;
                   6137:             fd_set *rfds_ptr, *wfds_ptr, *efds_ptr;
                   6138:             struct timespec ts, *ts_ptr;
                   6139: 
                   6140:             /*
                   6141:              * The 6th arg is actually two args smashed together,
                   6142:              * so we cannot use the C library.
                   6143:              */
                   6144:             sigset_t set;
                   6145:             struct {
                   6146:                 sigset_t *set;
                   6147:                 size_t size;
                   6148:             } sig, *sig_ptr;
                   6149: 
                   6150:             abi_ulong arg_sigset, arg_sigsize, *arg7;
                   6151:             target_sigset_t *target_sigset;
                   6152: 
                   6153:             n = arg1;
                   6154:             rfd_addr = arg2;
                   6155:             wfd_addr = arg3;
                   6156:             efd_addr = arg4;
                   6157:             ts_addr = arg5;
                   6158: 
                   6159:             ret = copy_from_user_fdset_ptr(&rfds, &rfds_ptr, rfd_addr, n);
                   6160:             if (ret) {
                   6161:                 goto fail;
                   6162:             }
                   6163:             ret = copy_from_user_fdset_ptr(&wfds, &wfds_ptr, wfd_addr, n);
                   6164:             if (ret) {
                   6165:                 goto fail;
                   6166:             }
                   6167:             ret = copy_from_user_fdset_ptr(&efds, &efds_ptr, efd_addr, n);
                   6168:             if (ret) {
                   6169:                 goto fail;
                   6170:             }
                   6171: 
                   6172:             /*
                   6173:              * This takes a timespec, and not a timeval, so we cannot
                   6174:              * use the do_select() helper ...
                   6175:              */
                   6176:             if (ts_addr) {
                   6177:                 if (target_to_host_timespec(&ts, ts_addr)) {
                   6178:                     goto efault;
                   6179:                 }
                   6180:                 ts_ptr = &ts;
                   6181:             } else {
                   6182:                 ts_ptr = NULL;
                   6183:             }
                   6184: 
                   6185:             /* Extract the two packed args for the sigset */
                   6186:             if (arg6) {
                   6187:                 sig_ptr = &sig;
                   6188:                 sig.size = _NSIG / 8;
                   6189: 
                   6190:                 arg7 = lock_user(VERIFY_READ, arg6, sizeof(*arg7) * 2, 1);
                   6191:                 if (!arg7) {
                   6192:                     goto efault;
                   6193:                 }
1.1.1.13  root     6194:                 arg_sigset = tswapal(arg7[0]);
                   6195:                 arg_sigsize = tswapal(arg7[1]);
1.1.1.12  root     6196:                 unlock_user(arg7, arg6, 0);
                   6197: 
                   6198:                 if (arg_sigset) {
                   6199:                     sig.set = &set;
                   6200:                     if (arg_sigsize != sizeof(*target_sigset)) {
                   6201:                         /* Like the kernel, we enforce correct size sigsets */
                   6202:                         ret = -TARGET_EINVAL;
                   6203:                         goto fail;
                   6204:                     }
                   6205:                     target_sigset = lock_user(VERIFY_READ, arg_sigset,
                   6206:                                               sizeof(*target_sigset), 1);
                   6207:                     if (!target_sigset) {
                   6208:                         goto efault;
                   6209:                     }
                   6210:                     target_to_host_sigset(&set, target_sigset);
                   6211:                     unlock_user(target_sigset, arg_sigset, 0);
                   6212:                 } else {
                   6213:                     sig.set = NULL;
                   6214:                 }
                   6215:             } else {
                   6216:                 sig_ptr = NULL;
                   6217:             }
                   6218: 
                   6219:             ret = get_errno(sys_pselect6(n, rfds_ptr, wfds_ptr, efds_ptr,
                   6220:                                          ts_ptr, sig_ptr));
                   6221: 
                   6222:             if (!is_error(ret)) {
                   6223:                 if (rfd_addr && copy_to_user_fdset(rfd_addr, &rfds, n))
                   6224:                     goto efault;
                   6225:                 if (wfd_addr && copy_to_user_fdset(wfd_addr, &wfds, n))
                   6226:                     goto efault;
                   6227:                 if (efd_addr && copy_to_user_fdset(efd_addr, &efds, n))
                   6228:                     goto efault;
                   6229: 
                   6230:                 if (ts_addr && host_to_target_timespec(ts_addr, &ts))
                   6231:                     goto efault;
                   6232:             }
                   6233:         }
                   6234:         break;
1.1.1.10  root     6235: #endif
1.1       root     6236:     case TARGET_NR_symlink:
1.1.1.3   root     6237:         {
                   6238:             void *p2;
                   6239:             p = lock_user_string(arg1);
                   6240:             p2 = lock_user_string(arg2);
1.1.1.6   root     6241:             if (!p || !p2)
                   6242:                 ret = -TARGET_EFAULT;
                   6243:             else
                   6244:                 ret = get_errno(symlink(p, p2));
1.1.1.3   root     6245:             unlock_user(p2, arg2, 0);
                   6246:             unlock_user(p, arg1, 0);
                   6247:         }
1.1       root     6248:         break;
1.1.1.6   root     6249: #if defined(TARGET_NR_symlinkat) && defined(__NR_symlinkat)
                   6250:     case TARGET_NR_symlinkat:
                   6251:         {
                   6252:             void *p2;
                   6253:             p  = lock_user_string(arg1);
                   6254:             p2 = lock_user_string(arg3);
                   6255:             if (!p || !p2)
                   6256:                 ret = -TARGET_EFAULT;
                   6257:             else
                   6258:                 ret = get_errno(sys_symlinkat(p, arg2, p2));
                   6259:             unlock_user(p2, arg3, 0);
                   6260:             unlock_user(p, arg1, 0);
                   6261:         }
                   6262:         break;
                   6263: #endif
1.1       root     6264: #ifdef TARGET_NR_oldlstat
                   6265:     case TARGET_NR_oldlstat:
                   6266:         goto unimplemented;
                   6267: #endif
                   6268:     case TARGET_NR_readlink:
1.1.1.3   root     6269:         {
1.1.1.7   root     6270:             void *p2, *temp;
1.1.1.3   root     6271:             p = lock_user_string(arg1);
1.1.1.6   root     6272:             p2 = lock_user(VERIFY_WRITE, arg2, arg3, 0);
                   6273:             if (!p || !p2)
                   6274:                 ret = -TARGET_EFAULT;
1.1.1.7   root     6275:             else {
                   6276:                 if (strncmp((const char *)p, "/proc/self/exe", 14) == 0) {
                   6277:                     char real[PATH_MAX];
                   6278:                     temp = realpath(exec_path,real);
                   6279:                     ret = (temp==NULL) ? get_errno(-1) : strlen(real) ;
                   6280:                     snprintf((char *)p2, arg3, "%s", real);
                   6281:                     }
                   6282:                 else
                   6283:                     ret = get_errno(readlink(path(p), p2, arg3));
                   6284:             }
1.1.1.3   root     6285:             unlock_user(p2, arg2, ret);
                   6286:             unlock_user(p, arg1, 0);
                   6287:         }
1.1       root     6288:         break;
1.1.1.6   root     6289: #if defined(TARGET_NR_readlinkat) && defined(__NR_readlinkat)
                   6290:     case TARGET_NR_readlinkat:
                   6291:         {
                   6292:             void *p2;
                   6293:             p  = lock_user_string(arg2);
                   6294:             p2 = lock_user(VERIFY_WRITE, arg3, arg4, 0);
                   6295:             if (!p || !p2)
                   6296:                ret = -TARGET_EFAULT;
                   6297:             else
                   6298:                 ret = get_errno(sys_readlinkat(arg1, path(p), p2, arg4));
                   6299:             unlock_user(p2, arg3, ret);
                   6300:             unlock_user(p, arg2, 0);
                   6301:         }
                   6302:         break;
                   6303: #endif
                   6304: #ifdef TARGET_NR_uselib
1.1       root     6305:     case TARGET_NR_uselib:
                   6306:         goto unimplemented;
1.1.1.6   root     6307: #endif
                   6308: #ifdef TARGET_NR_swapon
1.1       root     6309:     case TARGET_NR_swapon:
1.1.1.6   root     6310:         if (!(p = lock_user_string(arg1)))
                   6311:             goto efault;
1.1.1.3   root     6312:         ret = get_errno(swapon(p, arg2));
                   6313:         unlock_user(p, arg1, 0);
1.1       root     6314:         break;
1.1.1.6   root     6315: #endif
1.1       root     6316:     case TARGET_NR_reboot:
1.1.1.13  root     6317:         if (!(p = lock_user_string(arg4)))
                   6318:             goto efault;
                   6319:         ret = reboot(arg1, arg2, arg3, p);
                   6320:         unlock_user(p, arg4, 0);
                   6321:         break;
1.1.1.6   root     6322: #ifdef TARGET_NR_readdir
1.1       root     6323:     case TARGET_NR_readdir:
                   6324:         goto unimplemented;
1.1.1.6   root     6325: #endif
                   6326: #ifdef TARGET_NR_mmap
1.1       root     6327:     case TARGET_NR_mmap:
1.1.1.12  root     6328: #if (defined(TARGET_I386) && defined(TARGET_ABI32)) || defined(TARGET_ARM) || \
                   6329:     defined(TARGET_M68K) || defined(TARGET_CRIS) || defined(TARGET_MICROBLAZE) \
                   6330:     || defined(TARGET_S390X)
1.1       root     6331:         {
1.1.1.6   root     6332:             abi_ulong *v;
                   6333:             abi_ulong v1, v2, v3, v4, v5, v6;
                   6334:             if (!(v = lock_user(VERIFY_READ, arg1, 6 * sizeof(abi_ulong), 1)))
                   6335:                 goto efault;
1.1.1.13  root     6336:             v1 = tswapal(v[0]);
                   6337:             v2 = tswapal(v[1]);
                   6338:             v3 = tswapal(v[2]);
                   6339:             v4 = tswapal(v[3]);
                   6340:             v5 = tswapal(v[4]);
                   6341:             v6 = tswapal(v[5]);
1.1.1.3   root     6342:             unlock_user(v, arg1, 0);
1.1.1.6   root     6343:             ret = get_errno(target_mmap(v1, v2, v3,
1.1       root     6344:                                         target_to_host_bitmask(v4, mmap_flags_tbl),
                   6345:                                         v5, v6));
                   6346:         }
                   6347: #else
1.1.1.6   root     6348:         ret = get_errno(target_mmap(arg1, arg2, arg3,
                   6349:                                     target_to_host_bitmask(arg4, mmap_flags_tbl),
1.1       root     6350:                                     arg5,
                   6351:                                     arg6));
                   6352: #endif
                   6353:         break;
1.1.1.6   root     6354: #endif
1.1       root     6355: #ifdef TARGET_NR_mmap2
                   6356:     case TARGET_NR_mmap2:
1.1.1.7   root     6357: #ifndef MMAP_SHIFT
1.1       root     6358: #define MMAP_SHIFT 12
                   6359: #endif
1.1.1.6   root     6360:         ret = get_errno(target_mmap(arg1, arg2, arg3,
                   6361:                                     target_to_host_bitmask(arg4, mmap_flags_tbl),
1.1       root     6362:                                     arg5,
                   6363:                                     arg6 << MMAP_SHIFT));
                   6364:         break;
                   6365: #endif
                   6366:     case TARGET_NR_munmap:
                   6367:         ret = get_errno(target_munmap(arg1, arg2));
                   6368:         break;
                   6369:     case TARGET_NR_mprotect:
1.1.1.10  root     6370:         {
1.1.1.14! root     6371:             TaskState *ts = ((CPUArchState *)cpu_env)->opaque;
1.1.1.10  root     6372:             /* Special hack to detect libc making the stack executable.  */
                   6373:             if ((arg3 & PROT_GROWSDOWN)
                   6374:                 && arg1 >= ts->info->stack_limit
                   6375:                 && arg1 <= ts->info->start_stack) {
                   6376:                 arg3 &= ~PROT_GROWSDOWN;
                   6377:                 arg2 = arg2 + arg1 - ts->info->stack_limit;
                   6378:                 arg1 = ts->info->stack_limit;
                   6379:             }
                   6380:         }
1.1       root     6381:         ret = get_errno(target_mprotect(arg1, arg2, arg3));
                   6382:         break;
1.1.1.6   root     6383: #ifdef TARGET_NR_mremap
1.1       root     6384:     case TARGET_NR_mremap:
                   6385:         ret = get_errno(target_mremap(arg1, arg2, arg3, arg4, arg5));
                   6386:         break;
1.1.1.6   root     6387: #endif
1.1.1.3   root     6388:         /* ??? msync/mlock/munlock are broken for softmmu.  */
1.1.1.6   root     6389: #ifdef TARGET_NR_msync
1.1       root     6390:     case TARGET_NR_msync:
1.1.1.3   root     6391:         ret = get_errno(msync(g2h(arg1), arg2, arg3));
1.1       root     6392:         break;
1.1.1.6   root     6393: #endif
                   6394: #ifdef TARGET_NR_mlock
1.1       root     6395:     case TARGET_NR_mlock:
1.1.1.3   root     6396:         ret = get_errno(mlock(g2h(arg1), arg2));
1.1       root     6397:         break;
1.1.1.6   root     6398: #endif
                   6399: #ifdef TARGET_NR_munlock
1.1       root     6400:     case TARGET_NR_munlock:
1.1.1.3   root     6401:         ret = get_errno(munlock(g2h(arg1), arg2));
1.1       root     6402:         break;
1.1.1.6   root     6403: #endif
                   6404: #ifdef TARGET_NR_mlockall
1.1       root     6405:     case TARGET_NR_mlockall:
                   6406:         ret = get_errno(mlockall(arg1));
                   6407:         break;
1.1.1.6   root     6408: #endif
                   6409: #ifdef TARGET_NR_munlockall
1.1       root     6410:     case TARGET_NR_munlockall:
                   6411:         ret = get_errno(munlockall());
                   6412:         break;
1.1.1.6   root     6413: #endif
1.1       root     6414:     case TARGET_NR_truncate:
1.1.1.6   root     6415:         if (!(p = lock_user_string(arg1)))
                   6416:             goto efault;
1.1.1.3   root     6417:         ret = get_errno(truncate(p, arg2));
                   6418:         unlock_user(p, arg1, 0);
1.1       root     6419:         break;
                   6420:     case TARGET_NR_ftruncate:
                   6421:         ret = get_errno(ftruncate(arg1, arg2));
                   6422:         break;
                   6423:     case TARGET_NR_fchmod:
                   6424:         ret = get_errno(fchmod(arg1, arg2));
                   6425:         break;
1.1.1.6   root     6426: #if defined(TARGET_NR_fchmodat) && defined(__NR_fchmodat)
                   6427:     case TARGET_NR_fchmodat:
                   6428:         if (!(p = lock_user_string(arg2)))
                   6429:             goto efault;
1.1.1.8   root     6430:         ret = get_errno(sys_fchmodat(arg1, p, arg3));
1.1.1.6   root     6431:         unlock_user(p, arg2, 0);
                   6432:         break;
                   6433: #endif
1.1       root     6434:     case TARGET_NR_getpriority:
1.1.1.6   root     6435:         /* libc does special remapping of the return value of
                   6436:          * sys_getpriority() so it's just easiest to call
                   6437:          * sys_getpriority() directly rather than through libc. */
1.1.1.9   root     6438:         ret = get_errno(sys_getpriority(arg1, arg2));
1.1       root     6439:         break;
                   6440:     case TARGET_NR_setpriority:
                   6441:         ret = get_errno(setpriority(arg1, arg2, arg3));
                   6442:         break;
                   6443: #ifdef TARGET_NR_profil
                   6444:     case TARGET_NR_profil:
                   6445:         goto unimplemented;
                   6446: #endif
                   6447:     case TARGET_NR_statfs:
1.1.1.6   root     6448:         if (!(p = lock_user_string(arg1)))
                   6449:             goto efault;
1.1.1.3   root     6450:         ret = get_errno(statfs(path(p), &stfs));
                   6451:         unlock_user(p, arg1, 0);
1.1       root     6452:     convert_statfs:
                   6453:         if (!is_error(ret)) {
1.1.1.3   root     6454:             struct target_statfs *target_stfs;
1.1.1.6   root     6455: 
                   6456:             if (!lock_user_struct(VERIFY_WRITE, target_stfs, arg2, 0))
                   6457:                 goto efault;
                   6458:             __put_user(stfs.f_type, &target_stfs->f_type);
                   6459:             __put_user(stfs.f_bsize, &target_stfs->f_bsize);
                   6460:             __put_user(stfs.f_blocks, &target_stfs->f_blocks);
                   6461:             __put_user(stfs.f_bfree, &target_stfs->f_bfree);
                   6462:             __put_user(stfs.f_bavail, &target_stfs->f_bavail);
                   6463:             __put_user(stfs.f_files, &target_stfs->f_files);
                   6464:             __put_user(stfs.f_ffree, &target_stfs->f_ffree);
                   6465:             __put_user(stfs.f_fsid.__val[0], &target_stfs->f_fsid.val[0]);
                   6466:             __put_user(stfs.f_fsid.__val[1], &target_stfs->f_fsid.val[1]);
                   6467:             __put_user(stfs.f_namelen, &target_stfs->f_namelen);
1.1.1.3   root     6468:             unlock_user_struct(target_stfs, arg2, 1);
1.1       root     6469:         }
                   6470:         break;
                   6471:     case TARGET_NR_fstatfs:
1.1.1.2   root     6472:         ret = get_errno(fstatfs(arg1, &stfs));
1.1       root     6473:         goto convert_statfs;
1.1.1.2   root     6474: #ifdef TARGET_NR_statfs64
                   6475:     case TARGET_NR_statfs64:
1.1.1.6   root     6476:         if (!(p = lock_user_string(arg1)))
                   6477:             goto efault;
1.1.1.3   root     6478:         ret = get_errno(statfs(path(p), &stfs));
                   6479:         unlock_user(p, arg1, 0);
1.1.1.2   root     6480:     convert_statfs64:
                   6481:         if (!is_error(ret)) {
1.1.1.3   root     6482:             struct target_statfs64 *target_stfs;
1.1.1.6   root     6483: 
                   6484:             if (!lock_user_struct(VERIFY_WRITE, target_stfs, arg3, 0))
                   6485:                 goto efault;
                   6486:             __put_user(stfs.f_type, &target_stfs->f_type);
                   6487:             __put_user(stfs.f_bsize, &target_stfs->f_bsize);
                   6488:             __put_user(stfs.f_blocks, &target_stfs->f_blocks);
                   6489:             __put_user(stfs.f_bfree, &target_stfs->f_bfree);
                   6490:             __put_user(stfs.f_bavail, &target_stfs->f_bavail);
                   6491:             __put_user(stfs.f_files, &target_stfs->f_files);
                   6492:             __put_user(stfs.f_ffree, &target_stfs->f_ffree);
                   6493:             __put_user(stfs.f_fsid.__val[0], &target_stfs->f_fsid.val[0]);
                   6494:             __put_user(stfs.f_fsid.__val[1], &target_stfs->f_fsid.val[1]);
                   6495:             __put_user(stfs.f_namelen, &target_stfs->f_namelen);
                   6496:             unlock_user_struct(target_stfs, arg3, 1);
1.1.1.2   root     6497:         }
                   6498:         break;
                   6499:     case TARGET_NR_fstatfs64:
                   6500:         ret = get_errno(fstatfs(arg1, &stfs));
                   6501:         goto convert_statfs64;
                   6502: #endif
1.1       root     6503: #ifdef TARGET_NR_ioperm
                   6504:     case TARGET_NR_ioperm:
                   6505:         goto unimplemented;
                   6506: #endif
1.1.1.6   root     6507: #ifdef TARGET_NR_socketcall
1.1       root     6508:     case TARGET_NR_socketcall:
1.1.1.3   root     6509:         ret = do_socketcall(arg1, arg2);
1.1       root     6510:         break;
1.1.1.6   root     6511: #endif
1.1.1.4   root     6512: #ifdef TARGET_NR_accept
                   6513:     case TARGET_NR_accept:
1.1.1.5   root     6514:         ret = do_accept(arg1, arg2, arg3);
1.1.1.4   root     6515:         break;
                   6516: #endif
                   6517: #ifdef TARGET_NR_bind
                   6518:     case TARGET_NR_bind:
                   6519:         ret = do_bind(arg1, arg2, arg3);
                   6520:         break;
                   6521: #endif
                   6522: #ifdef TARGET_NR_connect
                   6523:     case TARGET_NR_connect:
                   6524:         ret = do_connect(arg1, arg2, arg3);
                   6525:         break;
                   6526: #endif
                   6527: #ifdef TARGET_NR_getpeername
                   6528:     case TARGET_NR_getpeername:
1.1.1.5   root     6529:         ret = do_getpeername(arg1, arg2, arg3);
1.1.1.4   root     6530:         break;
                   6531: #endif
                   6532: #ifdef TARGET_NR_getsockname
                   6533:     case TARGET_NR_getsockname:
1.1.1.5   root     6534:         ret = do_getsockname(arg1, arg2, arg3);
1.1.1.4   root     6535:         break;
                   6536: #endif
                   6537: #ifdef TARGET_NR_getsockopt
                   6538:     case TARGET_NR_getsockopt:
                   6539:         ret = do_getsockopt(arg1, arg2, arg3, arg4, arg5);
                   6540:         break;
                   6541: #endif
                   6542: #ifdef TARGET_NR_listen
                   6543:     case TARGET_NR_listen:
1.1.1.5   root     6544:         ret = get_errno(listen(arg1, arg2));
1.1.1.4   root     6545:         break;
                   6546: #endif
                   6547: #ifdef TARGET_NR_recv
                   6548:     case TARGET_NR_recv:
1.1.1.6   root     6549:         ret = do_recvfrom(arg1, arg2, arg3, arg4, 0, 0);
1.1.1.4   root     6550:         break;
                   6551: #endif
                   6552: #ifdef TARGET_NR_recvfrom
                   6553:     case TARGET_NR_recvfrom:
1.1.1.6   root     6554:         ret = do_recvfrom(arg1, arg2, arg3, arg4, arg5, arg6);
1.1.1.4   root     6555:         break;
                   6556: #endif
                   6557: #ifdef TARGET_NR_recvmsg
                   6558:     case TARGET_NR_recvmsg:
                   6559:         ret = do_sendrecvmsg(arg1, arg2, arg3, 0);
                   6560:         break;
                   6561: #endif
                   6562: #ifdef TARGET_NR_send
                   6563:     case TARGET_NR_send:
1.1.1.5   root     6564:         ret = do_sendto(arg1, arg2, arg3, arg4, 0, 0);
1.1.1.4   root     6565:         break;
                   6566: #endif
                   6567: #ifdef TARGET_NR_sendmsg
                   6568:     case TARGET_NR_sendmsg:
                   6569:         ret = do_sendrecvmsg(arg1, arg2, arg3, 1);
                   6570:         break;
                   6571: #endif
                   6572: #ifdef TARGET_NR_sendto
                   6573:     case TARGET_NR_sendto:
1.1.1.5   root     6574:         ret = do_sendto(arg1, arg2, arg3, arg4, arg5, arg6);
1.1.1.4   root     6575:         break;
                   6576: #endif
                   6577: #ifdef TARGET_NR_shutdown
                   6578:     case TARGET_NR_shutdown:
1.1.1.5   root     6579:         ret = get_errno(shutdown(arg1, arg2));
1.1.1.4   root     6580:         break;
                   6581: #endif
                   6582: #ifdef TARGET_NR_socket
                   6583:     case TARGET_NR_socket:
                   6584:         ret = do_socket(arg1, arg2, arg3);
                   6585:         break;
                   6586: #endif
                   6587: #ifdef TARGET_NR_socketpair
                   6588:     case TARGET_NR_socketpair:
1.1.1.5   root     6589:         ret = do_socketpair(arg1, arg2, arg3, arg4);
1.1.1.4   root     6590:         break;
                   6591: #endif
                   6592: #ifdef TARGET_NR_setsockopt
                   6593:     case TARGET_NR_setsockopt:
                   6594:         ret = do_setsockopt(arg1, arg2, arg3, arg4, (socklen_t) arg5);
                   6595:         break;
                   6596: #endif
1.1.1.6   root     6597: 
1.1       root     6598:     case TARGET_NR_syslog:
1.1.1.6   root     6599:         if (!(p = lock_user_string(arg2)))
                   6600:             goto efault;
                   6601:         ret = get_errno(sys_syslog((int)arg1, p, (int)arg3));
                   6602:         unlock_user(p, arg2, 0);
                   6603:         break;
                   6604: 
1.1       root     6605:     case TARGET_NR_setitimer:
                   6606:         {
                   6607:             struct itimerval value, ovalue, *pvalue;
                   6608: 
1.1.1.3   root     6609:             if (arg2) {
1.1       root     6610:                 pvalue = &value;
1.1.1.6   root     6611:                 if (copy_from_user_timeval(&pvalue->it_interval, arg2)
                   6612:                     || copy_from_user_timeval(&pvalue->it_value,
                   6613:                                               arg2 + sizeof(struct target_timeval)))
                   6614:                     goto efault;
1.1       root     6615:             } else {
                   6616:                 pvalue = NULL;
                   6617:             }
                   6618:             ret = get_errno(setitimer(arg1, pvalue, &ovalue));
1.1.1.3   root     6619:             if (!is_error(ret) && arg3) {
1.1.1.6   root     6620:                 if (copy_to_user_timeval(arg3,
                   6621:                                          &ovalue.it_interval)
                   6622:                     || copy_to_user_timeval(arg3 + sizeof(struct target_timeval),
                   6623:                                             &ovalue.it_value))
                   6624:                     goto efault;
1.1       root     6625:             }
                   6626:         }
                   6627:         break;
                   6628:     case TARGET_NR_getitimer:
                   6629:         {
                   6630:             struct itimerval value;
1.1.1.6   root     6631: 
1.1       root     6632:             ret = get_errno(getitimer(arg1, &value));
1.1.1.3   root     6633:             if (!is_error(ret) && arg2) {
1.1.1.6   root     6634:                 if (copy_to_user_timeval(arg2,
                   6635:                                          &value.it_interval)
                   6636:                     || copy_to_user_timeval(arg2 + sizeof(struct target_timeval),
                   6637:                                             &value.it_value))
                   6638:                     goto efault;
1.1       root     6639:             }
                   6640:         }
                   6641:         break;
                   6642:     case TARGET_NR_stat:
1.1.1.6   root     6643:         if (!(p = lock_user_string(arg1)))
                   6644:             goto efault;
1.1.1.3   root     6645:         ret = get_errno(stat(path(p), &st));
                   6646:         unlock_user(p, arg1, 0);
1.1       root     6647:         goto do_stat;
                   6648:     case TARGET_NR_lstat:
1.1.1.6   root     6649:         if (!(p = lock_user_string(arg1)))
                   6650:             goto efault;
1.1.1.3   root     6651:         ret = get_errno(lstat(path(p), &st));
                   6652:         unlock_user(p, arg1, 0);
1.1       root     6653:         goto do_stat;
                   6654:     case TARGET_NR_fstat:
                   6655:         {
                   6656:             ret = get_errno(fstat(arg1, &st));
                   6657:         do_stat:
                   6658:             if (!is_error(ret)) {
1.1.1.3   root     6659:                 struct target_stat *target_st;
1.1.1.6   root     6660: 
                   6661:                 if (!lock_user_struct(VERIFY_WRITE, target_st, arg2, 0))
                   6662:                     goto efault;
1.1.1.9   root     6663:                 memset(target_st, 0, sizeof(*target_st));
1.1.1.6   root     6664:                 __put_user(st.st_dev, &target_st->st_dev);
                   6665:                 __put_user(st.st_ino, &target_st->st_ino);
                   6666:                 __put_user(st.st_mode, &target_st->st_mode);
                   6667:                 __put_user(st.st_uid, &target_st->st_uid);
                   6668:                 __put_user(st.st_gid, &target_st->st_gid);
                   6669:                 __put_user(st.st_nlink, &target_st->st_nlink);
                   6670:                 __put_user(st.st_rdev, &target_st->st_rdev);
                   6671:                 __put_user(st.st_size, &target_st->st_size);
                   6672:                 __put_user(st.st_blksize, &target_st->st_blksize);
                   6673:                 __put_user(st.st_blocks, &target_st->st_blocks);
                   6674:                 __put_user(st.st_atime, &target_st->target_st_atime);
                   6675:                 __put_user(st.st_mtime, &target_st->target_st_mtime);
                   6676:                 __put_user(st.st_ctime, &target_st->target_st_ctime);
1.1.1.3   root     6677:                 unlock_user_struct(target_st, arg2, 1);
1.1       root     6678:             }
                   6679:         }
                   6680:         break;
                   6681: #ifdef TARGET_NR_olduname
                   6682:     case TARGET_NR_olduname:
                   6683:         goto unimplemented;
                   6684: #endif
                   6685: #ifdef TARGET_NR_iopl
                   6686:     case TARGET_NR_iopl:
                   6687:         goto unimplemented;
                   6688: #endif
                   6689:     case TARGET_NR_vhangup:
                   6690:         ret = get_errno(vhangup());
                   6691:         break;
                   6692: #ifdef TARGET_NR_idle
                   6693:     case TARGET_NR_idle:
                   6694:         goto unimplemented;
                   6695: #endif
                   6696: #ifdef TARGET_NR_syscall
                   6697:     case TARGET_NR_syscall:
1.1.1.12  root     6698:         ret = do_syscall(cpu_env, arg1 & 0xffff, arg2, arg3, arg4, arg5,
                   6699:                          arg6, arg7, arg8, 0);
                   6700:         break;
1.1       root     6701: #endif
                   6702:     case TARGET_NR_wait4:
                   6703:         {
                   6704:             int status;
1.1.1.6   root     6705:             abi_long status_ptr = arg2;
1.1       root     6706:             struct rusage rusage, *rusage_ptr;
1.1.1.6   root     6707:             abi_ulong target_rusage = arg4;
1.1       root     6708:             if (target_rusage)
                   6709:                 rusage_ptr = &rusage;
                   6710:             else
                   6711:                 rusage_ptr = NULL;
                   6712:             ret = get_errno(wait4(arg1, &status, arg3, rusage_ptr));
                   6713:             if (!is_error(ret)) {
1.1.1.14! root     6714:                 if (status_ptr && ret) {
1.1.1.8   root     6715:                     status = host_to_target_waitstatus(status);
1.1.1.6   root     6716:                     if (put_user_s32(status, status_ptr))
                   6717:                         goto efault;
1.1       root     6718:                 }
1.1.1.6   root     6719:                 if (target_rusage)
                   6720:                     host_to_target_rusage(target_rusage, &rusage);
1.1       root     6721:             }
                   6722:         }
                   6723:         break;
1.1.1.6   root     6724: #ifdef TARGET_NR_swapoff
1.1       root     6725:     case TARGET_NR_swapoff:
1.1.1.6   root     6726:         if (!(p = lock_user_string(arg1)))
                   6727:             goto efault;
1.1.1.3   root     6728:         ret = get_errno(swapoff(p));
                   6729:         unlock_user(p, arg1, 0);
1.1       root     6730:         break;
1.1.1.6   root     6731: #endif
1.1       root     6732:     case TARGET_NR_sysinfo:
                   6733:         {
1.1.1.3   root     6734:             struct target_sysinfo *target_value;
1.1       root     6735:             struct sysinfo value;
                   6736:             ret = get_errno(sysinfo(&value));
1.1.1.3   root     6737:             if (!is_error(ret) && arg1)
1.1       root     6738:             {
1.1.1.6   root     6739:                 if (!lock_user_struct(VERIFY_WRITE, target_value, arg1, 0))
                   6740:                     goto efault;
1.1       root     6741:                 __put_user(value.uptime, &target_value->uptime);
                   6742:                 __put_user(value.loads[0], &target_value->loads[0]);
                   6743:                 __put_user(value.loads[1], &target_value->loads[1]);
                   6744:                 __put_user(value.loads[2], &target_value->loads[2]);
                   6745:                 __put_user(value.totalram, &target_value->totalram);
                   6746:                 __put_user(value.freeram, &target_value->freeram);
                   6747:                 __put_user(value.sharedram, &target_value->sharedram);
                   6748:                 __put_user(value.bufferram, &target_value->bufferram);
                   6749:                 __put_user(value.totalswap, &target_value->totalswap);
                   6750:                 __put_user(value.freeswap, &target_value->freeswap);
                   6751:                 __put_user(value.procs, &target_value->procs);
                   6752:                 __put_user(value.totalhigh, &target_value->totalhigh);
                   6753:                 __put_user(value.freehigh, &target_value->freehigh);
                   6754:                 __put_user(value.mem_unit, &target_value->mem_unit);
1.1.1.3   root     6755:                 unlock_user_struct(target_value, arg1, 1);
1.1       root     6756:             }
                   6757:         }
                   6758:         break;
1.1.1.6   root     6759: #ifdef TARGET_NR_ipc
1.1       root     6760:     case TARGET_NR_ipc:
                   6761:        ret = do_ipc(arg1, arg2, arg3, arg4, arg5, arg6);
                   6762:        break;
1.1.1.6   root     6763: #endif
1.1.1.8   root     6764: #ifdef TARGET_NR_semget
                   6765:     case TARGET_NR_semget:
                   6766:         ret = get_errno(semget(arg1, arg2, arg3));
                   6767:         break;
                   6768: #endif
                   6769: #ifdef TARGET_NR_semop
                   6770:     case TARGET_NR_semop:
                   6771:         ret = get_errno(do_semop(arg1, arg2, arg3));
                   6772:         break;
                   6773: #endif
                   6774: #ifdef TARGET_NR_semctl
                   6775:     case TARGET_NR_semctl:
                   6776:         ret = do_semctl(arg1, arg2, arg3, (union target_semun)(abi_ulong)arg4);
                   6777:         break;
                   6778: #endif
1.1.1.7   root     6779: #ifdef TARGET_NR_msgctl
                   6780:     case TARGET_NR_msgctl:
                   6781:         ret = do_msgctl(arg1, arg2, arg3);
                   6782:         break;
                   6783: #endif
                   6784: #ifdef TARGET_NR_msgget
                   6785:     case TARGET_NR_msgget:
                   6786:         ret = get_errno(msgget(arg1, arg2));
                   6787:         break;
                   6788: #endif
                   6789: #ifdef TARGET_NR_msgrcv
                   6790:     case TARGET_NR_msgrcv:
                   6791:         ret = do_msgrcv(arg1, arg2, arg3, arg4, arg5);
                   6792:         break;
                   6793: #endif
                   6794: #ifdef TARGET_NR_msgsnd
                   6795:     case TARGET_NR_msgsnd:
                   6796:         ret = do_msgsnd(arg1, arg2, arg3, arg4);
                   6797:         break;
                   6798: #endif
1.1.1.8   root     6799: #ifdef TARGET_NR_shmget
                   6800:     case TARGET_NR_shmget:
                   6801:         ret = get_errno(shmget(arg1, arg2, arg3));
                   6802:         break;
                   6803: #endif
                   6804: #ifdef TARGET_NR_shmctl
                   6805:     case TARGET_NR_shmctl:
                   6806:         ret = do_shmctl(arg1, arg2, arg3);
                   6807:         break;
                   6808: #endif
                   6809: #ifdef TARGET_NR_shmat
                   6810:     case TARGET_NR_shmat:
                   6811:         ret = do_shmat(arg1, arg2, arg3);
                   6812:         break;
                   6813: #endif
                   6814: #ifdef TARGET_NR_shmdt
                   6815:     case TARGET_NR_shmdt:
                   6816:         ret = do_shmdt(arg1);
                   6817:         break;
                   6818: #endif
1.1       root     6819:     case TARGET_NR_fsync:
                   6820:         ret = get_errno(fsync(arg1));
                   6821:         break;
                   6822:     case TARGET_NR_clone:
1.1.1.10  root     6823: #if defined(TARGET_SH4) || defined(TARGET_ALPHA)
1.1.1.7   root     6824:         ret = get_errno(do_fork(cpu_env, arg1, arg2, arg3, arg5, arg4));
                   6825: #elif defined(TARGET_CRIS)
                   6826:         ret = get_errno(do_fork(cpu_env, arg2, arg1, arg3, arg4, arg5));
1.1.1.12  root     6827: #elif defined(TARGET_S390X)
                   6828:         ret = get_errno(do_fork(cpu_env, arg2, arg1, arg3, arg5, arg4));
1.1.1.7   root     6829: #else
                   6830:         ret = get_errno(do_fork(cpu_env, arg1, arg2, arg3, arg4, arg5));
                   6831: #endif
1.1       root     6832:         break;
                   6833: #ifdef __NR_exit_group
                   6834:         /* new thread calls */
                   6835:     case TARGET_NR_exit_group:
1.1.1.9   root     6836: #ifdef TARGET_GPROF
1.1.1.7   root     6837:         _mcleanup();
                   6838: #endif
1.1       root     6839:         gdb_exit(cpu_env, arg1);
                   6840:         ret = get_errno(exit_group(arg1));
                   6841:         break;
                   6842: #endif
                   6843:     case TARGET_NR_setdomainname:
1.1.1.6   root     6844:         if (!(p = lock_user_string(arg1)))
                   6845:             goto efault;
1.1.1.3   root     6846:         ret = get_errno(setdomainname(p, arg2));
                   6847:         unlock_user(p, arg1, 0);
1.1       root     6848:         break;
                   6849:     case TARGET_NR_uname:
                   6850:         /* no need to transcode because we use the linux syscall */
                   6851:         {
                   6852:             struct new_utsname * buf;
1.1.1.6   root     6853: 
                   6854:             if (!lock_user_struct(VERIFY_WRITE, buf, arg1, 0))
                   6855:                 goto efault;
1.1       root     6856:             ret = get_errno(sys_uname(buf));
                   6857:             if (!is_error(ret)) {
                   6858:                 /* Overrite the native machine name with whatever is being
                   6859:                    emulated. */
1.1.1.10  root     6860:                 strcpy (buf->machine, cpu_to_uname_machine(cpu_env));
1.1.1.4   root     6861:                 /* Allow the user to override the reported release.  */
                   6862:                 if (qemu_uname_release && *qemu_uname_release)
                   6863:                   strcpy (buf->release, qemu_uname_release);
1.1       root     6864:             }
1.1.1.3   root     6865:             unlock_user_struct(buf, arg1, 1);
1.1       root     6866:         }
                   6867:         break;
                   6868: #ifdef TARGET_I386
                   6869:     case TARGET_NR_modify_ldt:
1.1.1.6   root     6870:         ret = do_modify_ldt(cpu_env, arg1, arg2, arg3);
1.1       root     6871:         break;
1.1.1.6   root     6872: #if !defined(TARGET_X86_64)
1.1       root     6873:     case TARGET_NR_vm86old:
                   6874:         goto unimplemented;
                   6875:     case TARGET_NR_vm86:
1.1.1.3   root     6876:         ret = do_vm86(cpu_env, arg1, arg2);
1.1       root     6877:         break;
                   6878: #endif
1.1.1.6   root     6879: #endif
1.1       root     6880:     case TARGET_NR_adjtimex:
                   6881:         goto unimplemented;
1.1.1.6   root     6882: #ifdef TARGET_NR_create_module
1.1       root     6883:     case TARGET_NR_create_module:
1.1.1.6   root     6884: #endif
1.1       root     6885:     case TARGET_NR_init_module:
                   6886:     case TARGET_NR_delete_module:
1.1.1.6   root     6887: #ifdef TARGET_NR_get_kernel_syms
1.1       root     6888:     case TARGET_NR_get_kernel_syms:
1.1.1.6   root     6889: #endif
1.1       root     6890:         goto unimplemented;
                   6891:     case TARGET_NR_quotactl:
                   6892:         goto unimplemented;
                   6893:     case TARGET_NR_getpgid:
                   6894:         ret = get_errno(getpgid(arg1));
                   6895:         break;
                   6896:     case TARGET_NR_fchdir:
                   6897:         ret = get_errno(fchdir(arg1));
                   6898:         break;
1.1.1.6   root     6899: #ifdef TARGET_NR_bdflush /* not on x86_64 */
1.1       root     6900:     case TARGET_NR_bdflush:
                   6901:         goto unimplemented;
1.1.1.6   root     6902: #endif
                   6903: #ifdef TARGET_NR_sysfs
1.1       root     6904:     case TARGET_NR_sysfs:
                   6905:         goto unimplemented;
1.1.1.6   root     6906: #endif
1.1       root     6907:     case TARGET_NR_personality:
                   6908:         ret = get_errno(personality(arg1));
                   6909:         break;
1.1.1.6   root     6910: #ifdef TARGET_NR_afs_syscall
1.1       root     6911:     case TARGET_NR_afs_syscall:
                   6912:         goto unimplemented;
1.1.1.6   root     6913: #endif
                   6914: #ifdef TARGET_NR__llseek /* Not on alpha */
1.1       root     6915:     case TARGET_NR__llseek:
                   6916:         {
1.1.1.12  root     6917:             int64_t res;
1.1.1.10  root     6918: #if !defined(__NR_llseek)
1.1.1.12  root     6919:             res = lseek(arg1, ((uint64_t)arg2 << 32) | arg3, arg5);
                   6920:             if (res == -1) {
                   6921:                 ret = get_errno(res);
                   6922:             } else {
                   6923:                 ret = 0;
                   6924:             }
1.1       root     6925: #else
                   6926:             ret = get_errno(_llseek(arg1, arg2, arg3, &res, arg5));
                   6927: #endif
1.1.1.12  root     6928:             if ((ret == 0) && put_user_s64(res, arg4)) {
                   6929:                 goto efault;
                   6930:             }
1.1       root     6931:         }
                   6932:         break;
1.1.1.6   root     6933: #endif
1.1       root     6934:     case TARGET_NR_getdents:
1.1.1.9   root     6935: #if TARGET_ABI_BITS == 32 && HOST_LONG_BITS == 64
1.1       root     6936:         {
1.1.1.3   root     6937:             struct target_dirent *target_dirp;
1.1.1.7   root     6938:             struct linux_dirent *dirp;
1.1.1.6   root     6939:             abi_long count = arg3;
1.1       root     6940: 
                   6941:            dirp = malloc(count);
1.1.1.6   root     6942:            if (!dirp) {
                   6943:                 ret = -TARGET_ENOMEM;
                   6944:                 goto fail;
                   6945:             }
                   6946: 
1.1       root     6947:             ret = get_errno(sys_getdents(arg1, dirp, count));
                   6948:             if (!is_error(ret)) {
1.1.1.7   root     6949:                 struct linux_dirent *de;
1.1       root     6950:                struct target_dirent *tde;
                   6951:                 int len = ret;
                   6952:                 int reclen, treclen;
                   6953:                int count1, tnamelen;
                   6954: 
                   6955:                count1 = 0;
                   6956:                 de = dirp;
1.1.1.6   root     6957:                 if (!(target_dirp = lock_user(VERIFY_WRITE, arg2, count, 0)))
                   6958:                     goto efault;
1.1       root     6959:                tde = target_dirp;
                   6960:                 while (len > 0) {
                   6961:                     reclen = de->d_reclen;
1.1.1.6   root     6962:                    treclen = reclen - (2 * (sizeof(long) - sizeof(abi_long)));
1.1       root     6963:                     tde->d_reclen = tswap16(treclen);
1.1.1.13  root     6964:                     tde->d_ino = tswapal(de->d_ino);
                   6965:                     tde->d_off = tswapal(de->d_off);
1.1.1.6   root     6966:                    tnamelen = treclen - (2 * sizeof(abi_long) + 2);
1.1       root     6967:                    if (tnamelen > 256)
                   6968:                         tnamelen = 256;
                   6969:                     /* XXX: may not be correct */
1.1.1.7   root     6970:                     pstrcpy(tde->d_name, tnamelen, de->d_name);
                   6971:                     de = (struct linux_dirent *)((char *)de + reclen);
1.1       root     6972:                     len -= reclen;
1.1.1.6   root     6973:                     tde = (struct target_dirent *)((char *)tde + treclen);
1.1       root     6974:                    count1 += treclen;
                   6975:                 }
                   6976:                ret = count1;
1.1.1.6   root     6977:                 unlock_user(target_dirp, arg2, ret);
1.1       root     6978:             }
                   6979:            free(dirp);
                   6980:         }
                   6981: #else
                   6982:         {
1.1.1.7   root     6983:             struct linux_dirent *dirp;
1.1.1.6   root     6984:             abi_long count = arg3;
1.1       root     6985: 
1.1.1.6   root     6986:             if (!(dirp = lock_user(VERIFY_WRITE, arg2, count, 0)))
                   6987:                 goto efault;
1.1       root     6988:             ret = get_errno(sys_getdents(arg1, dirp, count));
                   6989:             if (!is_error(ret)) {
1.1.1.7   root     6990:                 struct linux_dirent *de;
1.1       root     6991:                 int len = ret;
                   6992:                 int reclen;
                   6993:                 de = dirp;
                   6994:                 while (len > 0) {
                   6995:                     reclen = de->d_reclen;
                   6996:                     if (reclen > len)
                   6997:                         break;
                   6998:                     de->d_reclen = tswap16(reclen);
                   6999:                     tswapls(&de->d_ino);
                   7000:                     tswapls(&de->d_off);
1.1.1.7   root     7001:                     de = (struct linux_dirent *)((char *)de + reclen);
1.1       root     7002:                     len -= reclen;
                   7003:                 }
                   7004:             }
1.1.1.3   root     7005:             unlock_user(dirp, arg2, ret);
1.1       root     7006:         }
                   7007: #endif
                   7008:         break;
1.1.1.6   root     7009: #if defined(TARGET_NR_getdents64) && defined(__NR_getdents64)
1.1       root     7010:     case TARGET_NR_getdents64:
                   7011:         {
1.1.1.7   root     7012:             struct linux_dirent64 *dirp;
1.1.1.6   root     7013:             abi_long count = arg3;
                   7014:             if (!(dirp = lock_user(VERIFY_WRITE, arg2, count, 0)))
                   7015:                 goto efault;
1.1       root     7016:             ret = get_errno(sys_getdents64(arg1, dirp, count));
                   7017:             if (!is_error(ret)) {
1.1.1.7   root     7018:                 struct linux_dirent64 *de;
1.1       root     7019:                 int len = ret;
                   7020:                 int reclen;
                   7021:                 de = dirp;
                   7022:                 while (len > 0) {
                   7023:                     reclen = de->d_reclen;
                   7024:                     if (reclen > len)
                   7025:                         break;
                   7026:                     de->d_reclen = tswap16(reclen);
1.1.1.6   root     7027:                     tswap64s((uint64_t *)&de->d_ino);
                   7028:                     tswap64s((uint64_t *)&de->d_off);
1.1.1.7   root     7029:                     de = (struct linux_dirent64 *)((char *)de + reclen);
1.1       root     7030:                     len -= reclen;
                   7031:                 }
                   7032:             }
1.1.1.3   root     7033:             unlock_user(dirp, arg2, ret);
1.1       root     7034:         }
                   7035:         break;
                   7036: #endif /* TARGET_NR_getdents64 */
1.1.1.12  root     7037: #if defined(TARGET_NR__newselect) || defined(TARGET_S390X)
                   7038: #ifdef TARGET_S390X
                   7039:     case TARGET_NR_select:
                   7040: #else
1.1       root     7041:     case TARGET_NR__newselect:
1.1.1.12  root     7042: #endif
1.1.1.3   root     7043:         ret = do_select(arg1, arg2, arg3, arg4, arg5);
1.1       root     7044:         break;
1.1.1.6   root     7045: #endif
1.1.1.12  root     7046: #if defined(TARGET_NR_poll) || defined(TARGET_NR_ppoll)
                   7047: # ifdef TARGET_NR_poll
1.1       root     7048:     case TARGET_NR_poll:
1.1.1.12  root     7049: # endif
                   7050: # ifdef TARGET_NR_ppoll
                   7051:     case TARGET_NR_ppoll:
                   7052: # endif
1.1       root     7053:         {
1.1.1.3   root     7054:             struct target_pollfd *target_pfd;
1.1       root     7055:             unsigned int nfds = arg2;
                   7056:             int timeout = arg3;
                   7057:             struct pollfd *pfd;
                   7058:             unsigned int i;
                   7059: 
1.1.1.6   root     7060:             target_pfd = lock_user(VERIFY_WRITE, arg1, sizeof(struct target_pollfd) * nfds, 1);
                   7061:             if (!target_pfd)
                   7062:                 goto efault;
1.1.1.12  root     7063: 
1.1       root     7064:             pfd = alloca(sizeof(struct pollfd) * nfds);
                   7065:             for(i = 0; i < nfds; i++) {
                   7066:                 pfd[i].fd = tswap32(target_pfd[i].fd);
                   7067:                 pfd[i].events = tswap16(target_pfd[i].events);
                   7068:             }
1.1.1.12  root     7069: 
                   7070: # ifdef TARGET_NR_ppoll
                   7071:             if (num == TARGET_NR_ppoll) {
                   7072:                 struct timespec _timeout_ts, *timeout_ts = &_timeout_ts;
                   7073:                 target_sigset_t *target_set;
                   7074:                 sigset_t _set, *set = &_set;
                   7075: 
                   7076:                 if (arg3) {
                   7077:                     if (target_to_host_timespec(timeout_ts, arg3)) {
                   7078:                         unlock_user(target_pfd, arg1, 0);
                   7079:                         goto efault;
                   7080:                     }
                   7081:                 } else {
                   7082:                     timeout_ts = NULL;
                   7083:                 }
                   7084: 
                   7085:                 if (arg4) {
                   7086:                     target_set = lock_user(VERIFY_READ, arg4, sizeof(target_sigset_t), 1);
                   7087:                     if (!target_set) {
                   7088:                         unlock_user(target_pfd, arg1, 0);
                   7089:                         goto efault;
                   7090:                     }
                   7091:                     target_to_host_sigset(set, target_set);
                   7092:                 } else {
                   7093:                     set = NULL;
                   7094:                 }
                   7095: 
                   7096:                 ret = get_errno(sys_ppoll(pfd, nfds, timeout_ts, set, _NSIG/8));
                   7097: 
                   7098:                 if (!is_error(ret) && arg3) {
                   7099:                     host_to_target_timespec(arg3, timeout_ts);
                   7100:                 }
                   7101:                 if (arg4) {
                   7102:                     unlock_user(target_set, arg4, 0);
                   7103:                 }
                   7104:             } else
                   7105: # endif
                   7106:                 ret = get_errno(poll(pfd, nfds, timeout));
                   7107: 
1.1       root     7108:             if (!is_error(ret)) {
                   7109:                 for(i = 0; i < nfds; i++) {
                   7110:                     target_pfd[i].revents = tswap16(pfd[i].revents);
                   7111:                 }
                   7112:             }
1.1.1.12  root     7113:             unlock_user(target_pfd, arg1, sizeof(struct target_pollfd) * nfds);
1.1       root     7114:         }
                   7115:         break;
1.1.1.6   root     7116: #endif
1.1       root     7117:     case TARGET_NR_flock:
                   7118:         /* NOTE: the flock constant seems to be the same for every
                   7119:            Linux platform */
                   7120:         ret = get_errno(flock(arg1, arg2));
                   7121:         break;
                   7122:     case TARGET_NR_readv:
                   7123:         {
                   7124:             int count = arg3;
                   7125:             struct iovec *vec;
                   7126: 
                   7127:             vec = alloca(count * sizeof(struct iovec));
1.1.1.7   root     7128:             if (lock_iovec(VERIFY_WRITE, vec, arg2, count, 0) < 0)
                   7129:                 goto efault;
1.1       root     7130:             ret = get_errno(readv(arg1, vec, count));
1.1.1.3   root     7131:             unlock_iovec(vec, arg2, count, 1);
1.1       root     7132:         }
                   7133:         break;
                   7134:     case TARGET_NR_writev:
                   7135:         {
                   7136:             int count = arg3;
                   7137:             struct iovec *vec;
                   7138: 
                   7139:             vec = alloca(count * sizeof(struct iovec));
1.1.1.7   root     7140:             if (lock_iovec(VERIFY_READ, vec, arg2, count, 1) < 0)
                   7141:                 goto efault;
1.1       root     7142:             ret = get_errno(writev(arg1, vec, count));
1.1.1.3   root     7143:             unlock_iovec(vec, arg2, count, 0);
1.1       root     7144:         }
                   7145:         break;
                   7146:     case TARGET_NR_getsid:
                   7147:         ret = get_errno(getsid(arg1));
                   7148:         break;
1.1.1.6   root     7149: #if defined(TARGET_NR_fdatasync) /* Not on alpha (osf_datasync ?) */
1.1       root     7150:     case TARGET_NR_fdatasync:
                   7151:         ret = get_errno(fdatasync(arg1));
                   7152:         break;
1.1.1.6   root     7153: #endif
1.1       root     7154:     case TARGET_NR__sysctl:
1.1.1.6   root     7155:         /* We don't implement this, but ENOTDIR is always a safe
1.1       root     7156:            return value. */
1.1.1.6   root     7157:         ret = -TARGET_ENOTDIR;
                   7158:         break;
1.1.1.12  root     7159:     case TARGET_NR_sched_getaffinity:
                   7160:         {
                   7161:             unsigned int mask_size;
                   7162:             unsigned long *mask;
                   7163: 
                   7164:             /*
                   7165:              * sched_getaffinity needs multiples of ulong, so need to take
                   7166:              * care of mismatches between target ulong and host ulong sizes.
                   7167:              */
                   7168:             if (arg2 & (sizeof(abi_ulong) - 1)) {
                   7169:                 ret = -TARGET_EINVAL;
                   7170:                 break;
                   7171:             }
                   7172:             mask_size = (arg2 + (sizeof(*mask) - 1)) & ~(sizeof(*mask) - 1);
                   7173: 
                   7174:             mask = alloca(mask_size);
                   7175:             ret = get_errno(sys_sched_getaffinity(arg1, mask_size, mask));
                   7176: 
                   7177:             if (!is_error(ret)) {
                   7178:                 if (copy_to_user(arg3, mask, ret)) {
                   7179:                     goto efault;
                   7180:                 }
                   7181:             }
                   7182:         }
                   7183:         break;
                   7184:     case TARGET_NR_sched_setaffinity:
                   7185:         {
                   7186:             unsigned int mask_size;
                   7187:             unsigned long *mask;
                   7188: 
                   7189:             /*
                   7190:              * sched_setaffinity needs multiples of ulong, so need to take
                   7191:              * care of mismatches between target ulong and host ulong sizes.
                   7192:              */
                   7193:             if (arg2 & (sizeof(abi_ulong) - 1)) {
                   7194:                 ret = -TARGET_EINVAL;
                   7195:                 break;
                   7196:             }
                   7197:             mask_size = (arg2 + (sizeof(*mask) - 1)) & ~(sizeof(*mask) - 1);
                   7198: 
                   7199:             mask = alloca(mask_size);
                   7200:             if (!lock_user_struct(VERIFY_READ, p, arg3, 1)) {
                   7201:                 goto efault;
                   7202:             }
                   7203:             memcpy(mask, p, arg2);
                   7204:             unlock_user_struct(p, arg2, 0);
                   7205: 
                   7206:             ret = get_errno(sys_sched_setaffinity(arg1, mask_size, mask));
                   7207:         }
                   7208:         break;
1.1       root     7209:     case TARGET_NR_sched_setparam:
                   7210:         {
1.1.1.3   root     7211:             struct sched_param *target_schp;
1.1       root     7212:             struct sched_param schp;
1.1.1.3   root     7213: 
1.1.1.6   root     7214:             if (!lock_user_struct(VERIFY_READ, target_schp, arg2, 1))
                   7215:                 goto efault;
1.1       root     7216:             schp.sched_priority = tswap32(target_schp->sched_priority);
1.1.1.3   root     7217:             unlock_user_struct(target_schp, arg2, 0);
1.1       root     7218:             ret = get_errno(sched_setparam(arg1, &schp));
                   7219:         }
                   7220:         break;
                   7221:     case TARGET_NR_sched_getparam:
                   7222:         {
1.1.1.3   root     7223:             struct sched_param *target_schp;
1.1       root     7224:             struct sched_param schp;
                   7225:             ret = get_errno(sched_getparam(arg1, &schp));
                   7226:             if (!is_error(ret)) {
1.1.1.6   root     7227:                 if (!lock_user_struct(VERIFY_WRITE, target_schp, arg2, 0))
                   7228:                     goto efault;
1.1       root     7229:                 target_schp->sched_priority = tswap32(schp.sched_priority);
1.1.1.3   root     7230:                 unlock_user_struct(target_schp, arg2, 1);
1.1       root     7231:             }
                   7232:         }
                   7233:         break;
                   7234:     case TARGET_NR_sched_setscheduler:
                   7235:         {
1.1.1.3   root     7236:             struct sched_param *target_schp;
1.1       root     7237:             struct sched_param schp;
1.1.1.6   root     7238:             if (!lock_user_struct(VERIFY_READ, target_schp, arg3, 1))
                   7239:                 goto efault;
1.1       root     7240:             schp.sched_priority = tswap32(target_schp->sched_priority);
1.1.1.3   root     7241:             unlock_user_struct(target_schp, arg3, 0);
1.1       root     7242:             ret = get_errno(sched_setscheduler(arg1, arg2, &schp));
                   7243:         }
                   7244:         break;
                   7245:     case TARGET_NR_sched_getscheduler:
                   7246:         ret = get_errno(sched_getscheduler(arg1));
                   7247:         break;
                   7248:     case TARGET_NR_sched_yield:
                   7249:         ret = get_errno(sched_yield());
                   7250:         break;
                   7251:     case TARGET_NR_sched_get_priority_max:
                   7252:         ret = get_errno(sched_get_priority_max(arg1));
                   7253:         break;
                   7254:     case TARGET_NR_sched_get_priority_min:
                   7255:         ret = get_errno(sched_get_priority_min(arg1));
                   7256:         break;
                   7257:     case TARGET_NR_sched_rr_get_interval:
                   7258:         {
                   7259:             struct timespec ts;
                   7260:             ret = get_errno(sched_rr_get_interval(arg1, &ts));
                   7261:             if (!is_error(ret)) {
1.1.1.3   root     7262:                 host_to_target_timespec(arg2, &ts);
1.1       root     7263:             }
                   7264:         }
                   7265:         break;
                   7266:     case TARGET_NR_nanosleep:
                   7267:         {
                   7268:             struct timespec req, rem;
1.1.1.3   root     7269:             target_to_host_timespec(&req, arg1);
1.1       root     7270:             ret = get_errno(nanosleep(&req, &rem));
1.1.1.3   root     7271:             if (is_error(ret) && arg2) {
                   7272:                 host_to_target_timespec(arg2, &rem);
1.1       root     7273:             }
                   7274:         }
                   7275:         break;
1.1.1.6   root     7276: #ifdef TARGET_NR_query_module
1.1       root     7277:     case TARGET_NR_query_module:
                   7278:         goto unimplemented;
1.1.1.6   root     7279: #endif
                   7280: #ifdef TARGET_NR_nfsservctl
1.1       root     7281:     case TARGET_NR_nfsservctl:
                   7282:         goto unimplemented;
1.1.1.6   root     7283: #endif
1.1       root     7284:     case TARGET_NR_prctl:
1.1.1.14! root     7285:         switch (arg1) {
        !          7286:         case PR_GET_PDEATHSIG:
        !          7287:         {
        !          7288:             int deathsig;
        !          7289:             ret = get_errno(prctl(arg1, &deathsig, arg3, arg4, arg5));
        !          7290:             if (!is_error(ret) && arg2
        !          7291:                 && put_user_ual(deathsig, arg2)) {
        !          7292:                 goto efault;
        !          7293:             }
        !          7294:             break;
        !          7295:         }
        !          7296: #ifdef PR_GET_NAME
        !          7297:         case PR_GET_NAME:
        !          7298:         {
        !          7299:             void *name = lock_user(VERIFY_WRITE, arg2, 16, 1);
        !          7300:             if (!name) {
        !          7301:                 goto efault;
        !          7302:             }
        !          7303:             ret = get_errno(prctl(arg1, (unsigned long)name,
        !          7304:                                   arg3, arg4, arg5));
        !          7305:             unlock_user(name, arg2, 16);
        !          7306:             break;
        !          7307:         }
        !          7308:         case PR_SET_NAME:
        !          7309:         {
        !          7310:             void *name = lock_user(VERIFY_READ, arg2, 16, 1);
        !          7311:             if (!name) {
        !          7312:                 goto efault;
1.1.1.6   root     7313:             }
1.1.1.14! root     7314:             ret = get_errno(prctl(arg1, (unsigned long)name,
        !          7315:                                   arg3, arg4, arg5));
        !          7316:             unlock_user(name, arg2, 0);
        !          7317:             break;
        !          7318:         }
        !          7319: #endif
        !          7320:         default:
        !          7321:             /* Most prctl options have no pointer arguments */
        !          7322:             ret = get_errno(prctl(arg1, arg2, arg3, arg4, arg5));
        !          7323:             break;
        !          7324:         }
1.1.1.6   root     7325:         break;
                   7326: #ifdef TARGET_NR_arch_prctl
                   7327:     case TARGET_NR_arch_prctl:
                   7328: #if defined(TARGET_I386) && !defined(TARGET_ABI32)
                   7329:         ret = do_arch_prctl(cpu_env, arg1, arg2);
                   7330:         break;
                   7331: #else
1.1       root     7332:         goto unimplemented;
1.1.1.6   root     7333: #endif
                   7334: #endif
1.1       root     7335: #ifdef TARGET_NR_pread
                   7336:     case TARGET_NR_pread:
1.1.1.12  root     7337:         if (regpairs_aligned(cpu_env))
1.1.1.7   root     7338:             arg4 = arg5;
1.1.1.6   root     7339:         if (!(p = lock_user(VERIFY_WRITE, arg2, arg3, 0)))
                   7340:             goto efault;
1.1.1.3   root     7341:         ret = get_errno(pread(arg1, p, arg3, arg4));
                   7342:         unlock_user(p, arg2, ret);
1.1       root     7343:         break;
                   7344:     case TARGET_NR_pwrite:
1.1.1.12  root     7345:         if (regpairs_aligned(cpu_env))
1.1.1.7   root     7346:             arg4 = arg5;
1.1.1.6   root     7347:         if (!(p = lock_user(VERIFY_READ, arg2, arg3, 1)))
                   7348:             goto efault;
1.1.1.3   root     7349:         ret = get_errno(pwrite(arg1, p, arg3, arg4));
                   7350:         unlock_user(p, arg2, 0);
1.1       root     7351:         break;
                   7352: #endif
1.1.1.7   root     7353: #ifdef TARGET_NR_pread64
                   7354:     case TARGET_NR_pread64:
                   7355:         if (!(p = lock_user(VERIFY_WRITE, arg2, arg3, 0)))
                   7356:             goto efault;
                   7357:         ret = get_errno(pread64(arg1, p, arg3, target_offset64(arg4, arg5)));
                   7358:         unlock_user(p, arg2, ret);
                   7359:         break;
                   7360:     case TARGET_NR_pwrite64:
                   7361:         if (!(p = lock_user(VERIFY_READ, arg2, arg3, 1)))
                   7362:             goto efault;
                   7363:         ret = get_errno(pwrite64(arg1, p, arg3, target_offset64(arg4, arg5)));
                   7364:         unlock_user(p, arg2, 0);
                   7365:         break;
                   7366: #endif
1.1       root     7367:     case TARGET_NR_getcwd:
1.1.1.6   root     7368:         if (!(p = lock_user(VERIFY_WRITE, arg1, arg2, 0)))
                   7369:             goto efault;
1.1.1.3   root     7370:         ret = get_errno(sys_getcwd1(p, arg2));
                   7371:         unlock_user(p, arg1, ret);
1.1       root     7372:         break;
                   7373:     case TARGET_NR_capget:
                   7374:         goto unimplemented;
                   7375:     case TARGET_NR_capset:
                   7376:         goto unimplemented;
                   7377:     case TARGET_NR_sigaltstack:
1.1.1.6   root     7378: #if defined(TARGET_I386) || defined(TARGET_ARM) || defined(TARGET_MIPS) || \
1.1.1.9   root     7379:     defined(TARGET_SPARC) || defined(TARGET_PPC) || defined(TARGET_ALPHA) || \
1.1.1.12  root     7380:     defined(TARGET_M68K) || defined(TARGET_S390X)
1.1.1.14! root     7381:         ret = do_sigaltstack(arg1, arg2, get_sp_from_cpustate((CPUArchState *)cpu_env));
1.1.1.6   root     7382:         break;
                   7383: #else
1.1       root     7384:         goto unimplemented;
1.1.1.6   root     7385: #endif
1.1       root     7386:     case TARGET_NR_sendfile:
                   7387:         goto unimplemented;
                   7388: #ifdef TARGET_NR_getpmsg
                   7389:     case TARGET_NR_getpmsg:
                   7390:         goto unimplemented;
                   7391: #endif
                   7392: #ifdef TARGET_NR_putpmsg
                   7393:     case TARGET_NR_putpmsg:
                   7394:         goto unimplemented;
                   7395: #endif
1.1.1.2   root     7396: #ifdef TARGET_NR_vfork
1.1       root     7397:     case TARGET_NR_vfork:
1.1.1.7   root     7398:         ret = get_errno(do_fork(cpu_env, CLONE_VFORK | CLONE_VM | SIGCHLD,
                   7399:                         0, 0, 0, 0));
1.1       root     7400:         break;
1.1.1.2   root     7401: #endif
1.1       root     7402: #ifdef TARGET_NR_ugetrlimit
                   7403:     case TARGET_NR_ugetrlimit:
                   7404:     {
                   7405:        struct rlimit rlim;
1.1.1.12  root     7406:        int resource = target_to_host_resource(arg1);
                   7407:        ret = get_errno(getrlimit(resource, &rlim));
1.1       root     7408:        if (!is_error(ret)) {
1.1.1.3   root     7409:            struct target_rlimit *target_rlim;
1.1.1.6   root     7410:             if (!lock_user_struct(VERIFY_WRITE, target_rlim, arg2, 0))
                   7411:                 goto efault;
1.1.1.10  root     7412:            target_rlim->rlim_cur = host_to_target_rlim(rlim.rlim_cur);
                   7413:            target_rlim->rlim_max = host_to_target_rlim(rlim.rlim_max);
1.1.1.3   root     7414:             unlock_user_struct(target_rlim, arg2, 1);
1.1       root     7415:        }
                   7416:        break;
                   7417:     }
                   7418: #endif
                   7419: #ifdef TARGET_NR_truncate64
                   7420:     case TARGET_NR_truncate64:
1.1.1.6   root     7421:         if (!(p = lock_user_string(arg1)))
                   7422:             goto efault;
1.1.1.3   root     7423:        ret = target_truncate64(cpu_env, p, arg2, arg3, arg4);
                   7424:         unlock_user(p, arg1, 0);
1.1       root     7425:        break;
                   7426: #endif
                   7427: #ifdef TARGET_NR_ftruncate64
                   7428:     case TARGET_NR_ftruncate64:
1.1.1.3   root     7429:        ret = target_ftruncate64(cpu_env, arg1, arg2, arg3, arg4);
1.1       root     7430:        break;
                   7431: #endif
                   7432: #ifdef TARGET_NR_stat64
                   7433:     case TARGET_NR_stat64:
1.1.1.6   root     7434:         if (!(p = lock_user_string(arg1)))
                   7435:             goto efault;
1.1.1.3   root     7436:         ret = get_errno(stat(path(p), &st));
                   7437:         unlock_user(p, arg1, 0);
1.1.1.7   root     7438:         if (!is_error(ret))
                   7439:             ret = host_to_target_stat64(cpu_env, arg2, &st);
                   7440:         break;
1.1       root     7441: #endif
                   7442: #ifdef TARGET_NR_lstat64
                   7443:     case TARGET_NR_lstat64:
1.1.1.6   root     7444:         if (!(p = lock_user_string(arg1)))
                   7445:             goto efault;
1.1.1.3   root     7446:         ret = get_errno(lstat(path(p), &st));
                   7447:         unlock_user(p, arg1, 0);
1.1.1.7   root     7448:         if (!is_error(ret))
                   7449:             ret = host_to_target_stat64(cpu_env, arg2, &st);
                   7450:         break;
1.1       root     7451: #endif
                   7452: #ifdef TARGET_NR_fstat64
                   7453:     case TARGET_NR_fstat64:
1.1.1.7   root     7454:         ret = get_errno(fstat(arg1, &st));
                   7455:         if (!is_error(ret))
                   7456:             ret = host_to_target_stat64(cpu_env, arg2, &st);
                   7457:         break;
1.1       root     7458: #endif
1.1.1.8   root     7459: #if (defined(TARGET_NR_fstatat64) || defined(TARGET_NR_newfstatat)) && \
                   7460:         (defined(__NR_fstatat64) || defined(__NR_newfstatat))
                   7461: #ifdef TARGET_NR_fstatat64
1.1.1.7   root     7462:     case TARGET_NR_fstatat64:
1.1.1.8   root     7463: #endif
                   7464: #ifdef TARGET_NR_newfstatat
                   7465:     case TARGET_NR_newfstatat:
                   7466: #endif
1.1.1.7   root     7467:         if (!(p = lock_user_string(arg2)))
                   7468:             goto efault;
1.1.1.8   root     7469: #ifdef __NR_fstatat64
1.1.1.7   root     7470:         ret = get_errno(sys_fstatat64(arg1, path(p), &st, arg4));
1.1.1.8   root     7471: #else
                   7472:         ret = get_errno(sys_newfstatat(arg1, path(p), &st, arg4));
                   7473: #endif
1.1.1.7   root     7474:         if (!is_error(ret))
                   7475:             ret = host_to_target_stat64(cpu_env, arg3, &st);
1.1       root     7476:         break;
                   7477: #endif
                   7478:     case TARGET_NR_lchown:
1.1.1.6   root     7479:         if (!(p = lock_user_string(arg1)))
                   7480:             goto efault;
1.1.1.3   root     7481:         ret = get_errno(lchown(p, low2highuid(arg2), low2highgid(arg3)));
                   7482:         unlock_user(p, arg1, 0);
1.1       root     7483:         break;
1.1.1.12  root     7484: #ifdef TARGET_NR_getuid
1.1       root     7485:     case TARGET_NR_getuid:
                   7486:         ret = get_errno(high2lowuid(getuid()));
                   7487:         break;
1.1.1.12  root     7488: #endif
                   7489: #ifdef TARGET_NR_getgid
1.1       root     7490:     case TARGET_NR_getgid:
                   7491:         ret = get_errno(high2lowgid(getgid()));
                   7492:         break;
1.1.1.12  root     7493: #endif
                   7494: #ifdef TARGET_NR_geteuid
1.1       root     7495:     case TARGET_NR_geteuid:
                   7496:         ret = get_errno(high2lowuid(geteuid()));
                   7497:         break;
1.1.1.12  root     7498: #endif
                   7499: #ifdef TARGET_NR_getegid
1.1       root     7500:     case TARGET_NR_getegid:
                   7501:         ret = get_errno(high2lowgid(getegid()));
                   7502:         break;
1.1.1.12  root     7503: #endif
1.1       root     7504:     case TARGET_NR_setreuid:
                   7505:         ret = get_errno(setreuid(low2highuid(arg1), low2highuid(arg2)));
                   7506:         break;
                   7507:     case TARGET_NR_setregid:
                   7508:         ret = get_errno(setregid(low2highgid(arg1), low2highgid(arg2)));
                   7509:         break;
                   7510:     case TARGET_NR_getgroups:
                   7511:         {
                   7512:             int gidsetsize = arg1;
1.1.1.12  root     7513:             target_id *target_grouplist;
1.1       root     7514:             gid_t *grouplist;
                   7515:             int i;
                   7516: 
                   7517:             grouplist = alloca(gidsetsize * sizeof(gid_t));
                   7518:             ret = get_errno(getgroups(gidsetsize, grouplist));
1.1.1.7   root     7519:             if (gidsetsize == 0)
                   7520:                 break;
1.1       root     7521:             if (!is_error(ret)) {
1.1.1.6   root     7522:                 target_grouplist = lock_user(VERIFY_WRITE, arg2, gidsetsize * 2, 0);
                   7523:                 if (!target_grouplist)
                   7524:                     goto efault;
1.1.1.7   root     7525:                 for(i = 0;i < ret; i++)
1.1.1.12  root     7526:                     target_grouplist[i] = tswapid(high2lowgid(grouplist[i]));
1.1.1.3   root     7527:                 unlock_user(target_grouplist, arg2, gidsetsize * 2);
1.1       root     7528:             }
                   7529:         }
                   7530:         break;
                   7531:     case TARGET_NR_setgroups:
                   7532:         {
                   7533:             int gidsetsize = arg1;
1.1.1.12  root     7534:             target_id *target_grouplist;
1.1       root     7535:             gid_t *grouplist;
                   7536:             int i;
                   7537: 
                   7538:             grouplist = alloca(gidsetsize * sizeof(gid_t));
1.1.1.6   root     7539:             target_grouplist = lock_user(VERIFY_READ, arg2, gidsetsize * 2, 1);
                   7540:             if (!target_grouplist) {
                   7541:                 ret = -TARGET_EFAULT;
                   7542:                 goto fail;
                   7543:             }
1.1       root     7544:             for(i = 0;i < gidsetsize; i++)
1.1.1.12  root     7545:                 grouplist[i] = low2highgid(tswapid(target_grouplist[i]));
1.1.1.3   root     7546:             unlock_user(target_grouplist, arg2, 0);
1.1       root     7547:             ret = get_errno(setgroups(gidsetsize, grouplist));
                   7548:         }
                   7549:         break;
                   7550:     case TARGET_NR_fchown:
                   7551:         ret = get_errno(fchown(arg1, low2highuid(arg2), low2highgid(arg3)));
                   7552:         break;
1.1.1.6   root     7553: #if defined(TARGET_NR_fchownat) && defined(__NR_fchownat)
                   7554:     case TARGET_NR_fchownat:
                   7555:         if (!(p = lock_user_string(arg2))) 
                   7556:             goto efault;
                   7557:         ret = get_errno(sys_fchownat(arg1, p, low2highuid(arg3), low2highgid(arg4), arg5));
                   7558:         unlock_user(p, arg2, 0);
                   7559:         break;
                   7560: #endif
1.1       root     7561: #ifdef TARGET_NR_setresuid
                   7562:     case TARGET_NR_setresuid:
1.1.1.6   root     7563:         ret = get_errno(setresuid(low2highuid(arg1),
                   7564:                                   low2highuid(arg2),
1.1       root     7565:                                   low2highuid(arg3)));
                   7566:         break;
                   7567: #endif
                   7568: #ifdef TARGET_NR_getresuid
                   7569:     case TARGET_NR_getresuid:
                   7570:         {
1.1.1.3   root     7571:             uid_t ruid, euid, suid;
1.1       root     7572:             ret = get_errno(getresuid(&ruid, &euid, &suid));
                   7573:             if (!is_error(ret)) {
1.1.1.6   root     7574:                 if (put_user_u16(high2lowuid(ruid), arg1)
                   7575:                     || put_user_u16(high2lowuid(euid), arg2)
                   7576:                     || put_user_u16(high2lowuid(suid), arg3))
                   7577:                     goto efault;
1.1       root     7578:             }
                   7579:         }
                   7580:         break;
                   7581: #endif
                   7582: #ifdef TARGET_NR_getresgid
                   7583:     case TARGET_NR_setresgid:
1.1.1.6   root     7584:         ret = get_errno(setresgid(low2highgid(arg1),
                   7585:                                   low2highgid(arg2),
1.1       root     7586:                                   low2highgid(arg3)));
                   7587:         break;
                   7588: #endif
                   7589: #ifdef TARGET_NR_getresgid
                   7590:     case TARGET_NR_getresgid:
                   7591:         {
1.1.1.3   root     7592:             gid_t rgid, egid, sgid;
1.1       root     7593:             ret = get_errno(getresgid(&rgid, &egid, &sgid));
                   7594:             if (!is_error(ret)) {
1.1.1.6   root     7595:                 if (put_user_u16(high2lowgid(rgid), arg1)
                   7596:                     || put_user_u16(high2lowgid(egid), arg2)
                   7597:                     || put_user_u16(high2lowgid(sgid), arg3))
                   7598:                     goto efault;
1.1       root     7599:             }
                   7600:         }
                   7601:         break;
                   7602: #endif
                   7603:     case TARGET_NR_chown:
1.1.1.6   root     7604:         if (!(p = lock_user_string(arg1)))
                   7605:             goto efault;
1.1.1.3   root     7606:         ret = get_errno(chown(p, low2highuid(arg2), low2highgid(arg3)));
                   7607:         unlock_user(p, arg1, 0);
1.1       root     7608:         break;
                   7609:     case TARGET_NR_setuid:
                   7610:         ret = get_errno(setuid(low2highuid(arg1)));
                   7611:         break;
                   7612:     case TARGET_NR_setgid:
                   7613:         ret = get_errno(setgid(low2highgid(arg1)));
                   7614:         break;
                   7615:     case TARGET_NR_setfsuid:
                   7616:         ret = get_errno(setfsuid(arg1));
                   7617:         break;
                   7618:     case TARGET_NR_setfsgid:
                   7619:         ret = get_errno(setfsgid(arg1));
                   7620:         break;
                   7621: 
                   7622: #ifdef TARGET_NR_lchown32
                   7623:     case TARGET_NR_lchown32:
1.1.1.6   root     7624:         if (!(p = lock_user_string(arg1)))
                   7625:             goto efault;
1.1.1.3   root     7626:         ret = get_errno(lchown(p, arg2, arg3));
                   7627:         unlock_user(p, arg1, 0);
1.1       root     7628:         break;
                   7629: #endif
                   7630: #ifdef TARGET_NR_getuid32
                   7631:     case TARGET_NR_getuid32:
                   7632:         ret = get_errno(getuid());
                   7633:         break;
                   7634: #endif
1.1.1.7   root     7635: 
                   7636: #if defined(TARGET_NR_getxuid) && defined(TARGET_ALPHA)
                   7637:    /* Alpha specific */
                   7638:     case TARGET_NR_getxuid:
1.1.1.10  root     7639:          {
                   7640:             uid_t euid;
                   7641:             euid=geteuid();
                   7642:             ((CPUAlphaState *)cpu_env)->ir[IR_A4]=euid;
                   7643:          }
1.1.1.7   root     7644:         ret = get_errno(getuid());
                   7645:         break;
                   7646: #endif
                   7647: #if defined(TARGET_NR_getxgid) && defined(TARGET_ALPHA)
                   7648:    /* Alpha specific */
                   7649:     case TARGET_NR_getxgid:
1.1.1.10  root     7650:          {
                   7651:             uid_t egid;
                   7652:             egid=getegid();
                   7653:             ((CPUAlphaState *)cpu_env)->ir[IR_A4]=egid;
                   7654:          }
1.1.1.7   root     7655:         ret = get_errno(getgid());
                   7656:         break;
                   7657: #endif
1.1.1.10  root     7658: #if defined(TARGET_NR_osf_getsysinfo) && defined(TARGET_ALPHA)
                   7659:     /* Alpha specific */
                   7660:     case TARGET_NR_osf_getsysinfo:
                   7661:         ret = -TARGET_EOPNOTSUPP;
                   7662:         switch (arg1) {
                   7663:           case TARGET_GSI_IEEE_FP_CONTROL:
                   7664:             {
                   7665:                 uint64_t swcr, fpcr = cpu_alpha_load_fpcr (cpu_env);
                   7666: 
                   7667:                 /* Copied from linux ieee_fpcr_to_swcr.  */
                   7668:                 swcr = (fpcr >> 35) & SWCR_STATUS_MASK;
                   7669:                 swcr |= (fpcr >> 36) & SWCR_MAP_DMZ;
                   7670:                 swcr |= (~fpcr >> 48) & (SWCR_TRAP_ENABLE_INV
                   7671:                                         | SWCR_TRAP_ENABLE_DZE
                   7672:                                         | SWCR_TRAP_ENABLE_OVF);
                   7673:                 swcr |= (~fpcr >> 57) & (SWCR_TRAP_ENABLE_UNF
                   7674:                                         | SWCR_TRAP_ENABLE_INE);
                   7675:                 swcr |= (fpcr >> 47) & SWCR_MAP_UMZ;
                   7676:                 swcr |= (~fpcr >> 41) & SWCR_TRAP_ENABLE_DNO;
                   7677: 
                   7678:                 if (put_user_u64 (swcr, arg2))
                   7679:                         goto efault;
                   7680:                 ret = 0;
                   7681:             }
                   7682:             break;
                   7683: 
                   7684:           /* case GSI_IEEE_STATE_AT_SIGNAL:
                   7685:              -- Not implemented in linux kernel.
                   7686:              case GSI_UACPROC:
                   7687:              -- Retrieves current unaligned access state; not much used.
                   7688:              case GSI_PROC_TYPE:
                   7689:              -- Retrieves implver information; surely not used.
                   7690:              case GSI_GET_HWRPB:
                   7691:              -- Grabs a copy of the HWRPB; surely not used.
                   7692:           */
                   7693:         }
                   7694:         break;
                   7695: #endif
                   7696: #if defined(TARGET_NR_osf_setsysinfo) && defined(TARGET_ALPHA)
                   7697:     /* Alpha specific */
                   7698:     case TARGET_NR_osf_setsysinfo:
                   7699:         ret = -TARGET_EOPNOTSUPP;
                   7700:         switch (arg1) {
                   7701:           case TARGET_SSI_IEEE_FP_CONTROL:
                   7702:           case TARGET_SSI_IEEE_RAISE_EXCEPTION:
                   7703:             {
                   7704:                 uint64_t swcr, fpcr, orig_fpcr;
                   7705: 
                   7706:                 if (get_user_u64 (swcr, arg2))
                   7707:                     goto efault;
                   7708:                 orig_fpcr = cpu_alpha_load_fpcr (cpu_env);
                   7709:                 fpcr = orig_fpcr & FPCR_DYN_MASK;
                   7710: 
                   7711:                 /* Copied from linux ieee_swcr_to_fpcr.  */
                   7712:                 fpcr |= (swcr & SWCR_STATUS_MASK) << 35;
                   7713:                 fpcr |= (swcr & SWCR_MAP_DMZ) << 36;
                   7714:                 fpcr |= (~swcr & (SWCR_TRAP_ENABLE_INV
                   7715:                                   | SWCR_TRAP_ENABLE_DZE
                   7716:                                   | SWCR_TRAP_ENABLE_OVF)) << 48;
                   7717:                 fpcr |= (~swcr & (SWCR_TRAP_ENABLE_UNF
                   7718:                                   | SWCR_TRAP_ENABLE_INE)) << 57;
                   7719:                 fpcr |= (swcr & SWCR_MAP_UMZ ? FPCR_UNDZ | FPCR_UNFD : 0);
                   7720:                 fpcr |= (~swcr & SWCR_TRAP_ENABLE_DNO) << 41;
                   7721: 
                   7722:                 cpu_alpha_store_fpcr (cpu_env, fpcr);
                   7723:                 ret = 0;
                   7724: 
                   7725:                 if (arg1 == TARGET_SSI_IEEE_RAISE_EXCEPTION) {
                   7726:                     /* Old exceptions are not signaled.  */
                   7727:                     fpcr &= ~(orig_fpcr & FPCR_STATUS_MASK);
                   7728: 
                   7729:                     /* If any exceptions set by this call, and are unmasked,
                   7730:                        send a signal.  */
                   7731:                     /* ??? FIXME */
                   7732:                 }
                   7733:             }
                   7734:             break;
                   7735: 
                   7736:           /* case SSI_NVPAIRS:
                   7737:              -- Used with SSIN_UACPROC to enable unaligned accesses.
                   7738:              case SSI_IEEE_STATE_AT_SIGNAL:
                   7739:              case SSI_IEEE_IGNORE_STATE_AT_SIGNAL:
                   7740:              -- Not implemented in linux kernel
                   7741:           */
                   7742:         }
                   7743:         break;
                   7744: #endif
                   7745: #ifdef TARGET_NR_osf_sigprocmask
                   7746:     /* Alpha specific.  */
                   7747:     case TARGET_NR_osf_sigprocmask:
                   7748:         {
                   7749:             abi_ulong mask;
1.1.1.12  root     7750:             int how;
1.1.1.10  root     7751:             sigset_t set, oldset;
                   7752: 
                   7753:             switch(arg1) {
                   7754:             case TARGET_SIG_BLOCK:
                   7755:                 how = SIG_BLOCK;
                   7756:                 break;
                   7757:             case TARGET_SIG_UNBLOCK:
                   7758:                 how = SIG_UNBLOCK;
                   7759:                 break;
                   7760:             case TARGET_SIG_SETMASK:
                   7761:                 how = SIG_SETMASK;
                   7762:                 break;
                   7763:             default:
                   7764:                 ret = -TARGET_EINVAL;
                   7765:                 goto fail;
                   7766:             }
                   7767:             mask = arg2;
                   7768:             target_to_host_old_sigset(&set, &mask);
1.1.1.12  root     7769:             sigprocmask(how, &set, &oldset);
1.1.1.10  root     7770:             host_to_target_old_sigset(&mask, &oldset);
                   7771:             ret = mask;
                   7772:         }
                   7773:         break;
                   7774: #endif
1.1.1.7   root     7775: 
1.1       root     7776: #ifdef TARGET_NR_getgid32
                   7777:     case TARGET_NR_getgid32:
                   7778:         ret = get_errno(getgid());
                   7779:         break;
                   7780: #endif
                   7781: #ifdef TARGET_NR_geteuid32
                   7782:     case TARGET_NR_geteuid32:
                   7783:         ret = get_errno(geteuid());
                   7784:         break;
                   7785: #endif
                   7786: #ifdef TARGET_NR_getegid32
                   7787:     case TARGET_NR_getegid32:
                   7788:         ret = get_errno(getegid());
                   7789:         break;
                   7790: #endif
                   7791: #ifdef TARGET_NR_setreuid32
                   7792:     case TARGET_NR_setreuid32:
                   7793:         ret = get_errno(setreuid(arg1, arg2));
                   7794:         break;
                   7795: #endif
                   7796: #ifdef TARGET_NR_setregid32
                   7797:     case TARGET_NR_setregid32:
                   7798:         ret = get_errno(setregid(arg1, arg2));
                   7799:         break;
                   7800: #endif
                   7801: #ifdef TARGET_NR_getgroups32
                   7802:     case TARGET_NR_getgroups32:
                   7803:         {
                   7804:             int gidsetsize = arg1;
1.1.1.3   root     7805:             uint32_t *target_grouplist;
1.1       root     7806:             gid_t *grouplist;
                   7807:             int i;
                   7808: 
                   7809:             grouplist = alloca(gidsetsize * sizeof(gid_t));
                   7810:             ret = get_errno(getgroups(gidsetsize, grouplist));
1.1.1.7   root     7811:             if (gidsetsize == 0)
                   7812:                 break;
1.1       root     7813:             if (!is_error(ret)) {
1.1.1.6   root     7814:                 target_grouplist = lock_user(VERIFY_WRITE, arg2, gidsetsize * 4, 0);
                   7815:                 if (!target_grouplist) {
                   7816:                     ret = -TARGET_EFAULT;
                   7817:                     goto fail;
                   7818:                 }
1.1.1.7   root     7819:                 for(i = 0;i < ret; i++)
1.1.1.3   root     7820:                     target_grouplist[i] = tswap32(grouplist[i]);
                   7821:                 unlock_user(target_grouplist, arg2, gidsetsize * 4);
1.1       root     7822:             }
                   7823:         }
                   7824:         break;
                   7825: #endif
                   7826: #ifdef TARGET_NR_setgroups32
                   7827:     case TARGET_NR_setgroups32:
                   7828:         {
                   7829:             int gidsetsize = arg1;
1.1.1.3   root     7830:             uint32_t *target_grouplist;
1.1       root     7831:             gid_t *grouplist;
                   7832:             int i;
1.1.1.6   root     7833: 
1.1       root     7834:             grouplist = alloca(gidsetsize * sizeof(gid_t));
1.1.1.6   root     7835:             target_grouplist = lock_user(VERIFY_READ, arg2, gidsetsize * 4, 1);
                   7836:             if (!target_grouplist) {
                   7837:                 ret = -TARGET_EFAULT;
                   7838:                 goto fail;
                   7839:             }
1.1       root     7840:             for(i = 0;i < gidsetsize; i++)
1.1.1.3   root     7841:                 grouplist[i] = tswap32(target_grouplist[i]);
                   7842:             unlock_user(target_grouplist, arg2, 0);
1.1       root     7843:             ret = get_errno(setgroups(gidsetsize, grouplist));
                   7844:         }
                   7845:         break;
                   7846: #endif
                   7847: #ifdef TARGET_NR_fchown32
                   7848:     case TARGET_NR_fchown32:
                   7849:         ret = get_errno(fchown(arg1, arg2, arg3));
                   7850:         break;
                   7851: #endif
                   7852: #ifdef TARGET_NR_setresuid32
                   7853:     case TARGET_NR_setresuid32:
                   7854:         ret = get_errno(setresuid(arg1, arg2, arg3));
                   7855:         break;
                   7856: #endif
                   7857: #ifdef TARGET_NR_getresuid32
                   7858:     case TARGET_NR_getresuid32:
                   7859:         {
1.1.1.3   root     7860:             uid_t ruid, euid, suid;
1.1       root     7861:             ret = get_errno(getresuid(&ruid, &euid, &suid));
                   7862:             if (!is_error(ret)) {
1.1.1.6   root     7863:                 if (put_user_u32(ruid, arg1)
                   7864:                     || put_user_u32(euid, arg2)
                   7865:                     || put_user_u32(suid, arg3))
                   7866:                     goto efault;
1.1       root     7867:             }
                   7868:         }
                   7869:         break;
                   7870: #endif
                   7871: #ifdef TARGET_NR_setresgid32
                   7872:     case TARGET_NR_setresgid32:
                   7873:         ret = get_errno(setresgid(arg1, arg2, arg3));
                   7874:         break;
                   7875: #endif
                   7876: #ifdef TARGET_NR_getresgid32
                   7877:     case TARGET_NR_getresgid32:
                   7878:         {
1.1.1.3   root     7879:             gid_t rgid, egid, sgid;
1.1       root     7880:             ret = get_errno(getresgid(&rgid, &egid, &sgid));
                   7881:             if (!is_error(ret)) {
1.1.1.6   root     7882:                 if (put_user_u32(rgid, arg1)
                   7883:                     || put_user_u32(egid, arg2)
                   7884:                     || put_user_u32(sgid, arg3))
                   7885:                     goto efault;
1.1       root     7886:             }
                   7887:         }
                   7888:         break;
                   7889: #endif
                   7890: #ifdef TARGET_NR_chown32
                   7891:     case TARGET_NR_chown32:
1.1.1.6   root     7892:         if (!(p = lock_user_string(arg1)))
                   7893:             goto efault;
1.1.1.3   root     7894:         ret = get_errno(chown(p, arg2, arg3));
                   7895:         unlock_user(p, arg1, 0);
1.1       root     7896:         break;
                   7897: #endif
                   7898: #ifdef TARGET_NR_setuid32
                   7899:     case TARGET_NR_setuid32:
                   7900:         ret = get_errno(setuid(arg1));
                   7901:         break;
                   7902: #endif
                   7903: #ifdef TARGET_NR_setgid32
                   7904:     case TARGET_NR_setgid32:
                   7905:         ret = get_errno(setgid(arg1));
                   7906:         break;
                   7907: #endif
                   7908: #ifdef TARGET_NR_setfsuid32
                   7909:     case TARGET_NR_setfsuid32:
                   7910:         ret = get_errno(setfsuid(arg1));
                   7911:         break;
                   7912: #endif
                   7913: #ifdef TARGET_NR_setfsgid32
                   7914:     case TARGET_NR_setfsgid32:
                   7915:         ret = get_errno(setfsgid(arg1));
                   7916:         break;
                   7917: #endif
                   7918: 
                   7919:     case TARGET_NR_pivot_root:
                   7920:         goto unimplemented;
                   7921: #ifdef TARGET_NR_mincore
                   7922:     case TARGET_NR_mincore:
1.1.1.7   root     7923:         {
                   7924:             void *a;
                   7925:             ret = -TARGET_EFAULT;
                   7926:             if (!(a = lock_user(VERIFY_READ, arg1,arg2, 0)))
                   7927:                 goto efault;
                   7928:             if (!(p = lock_user_string(arg3)))
                   7929:                 goto mincore_fail;
                   7930:             ret = get_errno(mincore(a, arg2, p));
                   7931:             unlock_user(p, arg3, ret);
                   7932:             mincore_fail:
                   7933:             unlock_user(a, arg1, 0);
                   7934:         }
                   7935:         break;
                   7936: #endif
                   7937: #ifdef TARGET_NR_arm_fadvise64_64
                   7938:     case TARGET_NR_arm_fadvise64_64:
                   7939:        {
                   7940:                /*
                   7941:                 * arm_fadvise64_64 looks like fadvise64_64 but
                   7942:                 * with different argument order
                   7943:                 */
                   7944:                abi_long temp;
                   7945:                temp = arg3;
                   7946:                arg3 = arg4;
                   7947:                arg4 = temp;
                   7948:        }
                   7949: #endif
1.1.1.9   root     7950: #if defined(TARGET_NR_fadvise64_64) || defined(TARGET_NR_arm_fadvise64_64) || defined(TARGET_NR_fadvise64)
1.1.1.7   root     7951: #ifdef TARGET_NR_fadvise64_64
                   7952:     case TARGET_NR_fadvise64_64:
                   7953: #endif
1.1.1.9   root     7954: #ifdef TARGET_NR_fadvise64
                   7955:     case TARGET_NR_fadvise64:
                   7956: #endif
                   7957: #ifdef TARGET_S390X
                   7958:         switch (arg4) {
                   7959:         case 4: arg4 = POSIX_FADV_NOREUSE + 1; break; /* make sure it's an invalid value */
                   7960:         case 5: arg4 = POSIX_FADV_NOREUSE + 2; break; /* ditto */
                   7961:         case 6: arg4 = POSIX_FADV_DONTNEED; break;
                   7962:         case 7: arg4 = POSIX_FADV_NOREUSE; break;
                   7963:         default: break;
                   7964:         }
                   7965: #endif
                   7966:         ret = -posix_fadvise(arg1, arg2, arg3, arg4);
1.1.1.7   root     7967:        break;
1.1       root     7968: #endif
                   7969: #ifdef TARGET_NR_madvise
                   7970:     case TARGET_NR_madvise:
1.1.1.3   root     7971:         /* A straight passthrough may not be safe because qemu sometimes
                   7972:            turns private flie-backed mappings into anonymous mappings.
                   7973:            This will break MADV_DONTNEED.
                   7974:            This is a hint, so ignoring and returning success is ok.  */
                   7975:         ret = get_errno(0);
                   7976:         break;
1.1       root     7977: #endif
1.1.1.6   root     7978: #if TARGET_ABI_BITS == 32
1.1       root     7979:     case TARGET_NR_fcntl64:
                   7980:     {
1.1.1.6   root     7981:        int cmd;
1.1       root     7982:        struct flock64 fl;
1.1.1.3   root     7983:        struct target_flock64 *target_fl;
                   7984: #ifdef TARGET_ARM
                   7985:        struct target_eabi_flock64 *target_efl;
                   7986: #endif
1.1       root     7987: 
1.1.1.8   root     7988:        cmd = target_to_host_fcntl_cmd(arg2);
1.1.1.14! root     7989:         if (cmd == -TARGET_EINVAL) {
        !          7990:             ret = cmd;
        !          7991:             break;
        !          7992:         }
1.1.1.6   root     7993: 
1.1       root     7994:         switch(arg2) {
1.1.1.6   root     7995:         case TARGET_F_GETLK64:
                   7996: #ifdef TARGET_ARM
                   7997:             if (((CPUARMState *)cpu_env)->eabi) {
                   7998:                 if (!lock_user_struct(VERIFY_READ, target_efl, arg3, 1)) 
                   7999:                     goto efault;
                   8000:                 fl.l_type = tswap16(target_efl->l_type);
                   8001:                 fl.l_whence = tswap16(target_efl->l_whence);
                   8002:                 fl.l_start = tswap64(target_efl->l_start);
                   8003:                 fl.l_len = tswap64(target_efl->l_len);
1.1.1.9   root     8004:                 fl.l_pid = tswap32(target_efl->l_pid);
1.1.1.6   root     8005:                 unlock_user_struct(target_efl, arg3, 0);
                   8006:             } else
                   8007: #endif
                   8008:             {
                   8009:                 if (!lock_user_struct(VERIFY_READ, target_fl, arg3, 1)) 
                   8010:                     goto efault;
                   8011:                 fl.l_type = tswap16(target_fl->l_type);
                   8012:                 fl.l_whence = tswap16(target_fl->l_whence);
                   8013:                 fl.l_start = tswap64(target_fl->l_start);
                   8014:                 fl.l_len = tswap64(target_fl->l_len);
1.1.1.9   root     8015:                 fl.l_pid = tswap32(target_fl->l_pid);
1.1.1.6   root     8016:                 unlock_user_struct(target_fl, arg3, 0);
                   8017:             }
                   8018:             ret = get_errno(fcntl(arg1, cmd, &fl));
1.1       root     8019:            if (ret == 0) {
1.1.1.3   root     8020: #ifdef TARGET_ARM
                   8021:                 if (((CPUARMState *)cpu_env)->eabi) {
1.1.1.6   root     8022:                     if (!lock_user_struct(VERIFY_WRITE, target_efl, arg3, 0)) 
                   8023:                         goto efault;
1.1.1.3   root     8024:                     target_efl->l_type = tswap16(fl.l_type);
                   8025:                     target_efl->l_whence = tswap16(fl.l_whence);
                   8026:                     target_efl->l_start = tswap64(fl.l_start);
                   8027:                     target_efl->l_len = tswap64(fl.l_len);
1.1.1.9   root     8028:                     target_efl->l_pid = tswap32(fl.l_pid);
1.1.1.3   root     8029:                     unlock_user_struct(target_efl, arg3, 1);
                   8030:                 } else
                   8031: #endif
                   8032:                 {
1.1.1.6   root     8033:                     if (!lock_user_struct(VERIFY_WRITE, target_fl, arg3, 0)) 
                   8034:                         goto efault;
1.1.1.3   root     8035:                     target_fl->l_type = tswap16(fl.l_type);
                   8036:                     target_fl->l_whence = tswap16(fl.l_whence);
                   8037:                     target_fl->l_start = tswap64(fl.l_start);
                   8038:                     target_fl->l_len = tswap64(fl.l_len);
1.1.1.9   root     8039:                     target_fl->l_pid = tswap32(fl.l_pid);
1.1.1.3   root     8040:                     unlock_user_struct(target_fl, arg3, 1);
                   8041:                 }
1.1       root     8042:            }
                   8043:            break;
                   8044: 
1.1.1.6   root     8045:         case TARGET_F_SETLK64:
                   8046:         case TARGET_F_SETLKW64:
1.1.1.3   root     8047: #ifdef TARGET_ARM
                   8048:             if (((CPUARMState *)cpu_env)->eabi) {
1.1.1.6   root     8049:                 if (!lock_user_struct(VERIFY_READ, target_efl, arg3, 1)) 
                   8050:                     goto efault;
1.1.1.3   root     8051:                 fl.l_type = tswap16(target_efl->l_type);
                   8052:                 fl.l_whence = tswap16(target_efl->l_whence);
                   8053:                 fl.l_start = tswap64(target_efl->l_start);
                   8054:                 fl.l_len = tswap64(target_efl->l_len);
1.1.1.9   root     8055:                 fl.l_pid = tswap32(target_efl->l_pid);
1.1.1.3   root     8056:                 unlock_user_struct(target_efl, arg3, 0);
                   8057:             } else
                   8058: #endif
                   8059:             {
1.1.1.6   root     8060:                 if (!lock_user_struct(VERIFY_READ, target_fl, arg3, 1)) 
                   8061:                     goto efault;
1.1.1.3   root     8062:                 fl.l_type = tswap16(target_fl->l_type);
                   8063:                 fl.l_whence = tswap16(target_fl->l_whence);
                   8064:                 fl.l_start = tswap64(target_fl->l_start);
                   8065:                 fl.l_len = tswap64(target_fl->l_len);
1.1.1.9   root     8066:                 fl.l_pid = tswap32(target_fl->l_pid);
1.1.1.3   root     8067:                 unlock_user_struct(target_fl, arg3, 0);
                   8068:             }
1.1.1.6   root     8069:             ret = get_errno(fcntl(arg1, cmd, &fl));
1.1       root     8070:            break;
                   8071:         default:
1.1.1.8   root     8072:             ret = do_fcntl(arg1, arg2, arg3);
1.1       root     8073:             break;
                   8074:         }
                   8075:        break;
                   8076:     }
                   8077: #endif
1.1.1.5   root     8078: #ifdef TARGET_NR_cacheflush
                   8079:     case TARGET_NR_cacheflush:
                   8080:         /* self-modifying code is handled automatically, so nothing needed */
                   8081:         ret = 0;
                   8082:         break;
                   8083: #endif
1.1       root     8084: #ifdef TARGET_NR_security
                   8085:     case TARGET_NR_security:
                   8086:         goto unimplemented;
                   8087: #endif
                   8088: #ifdef TARGET_NR_getpagesize
                   8089:     case TARGET_NR_getpagesize:
                   8090:         ret = TARGET_PAGE_SIZE;
                   8091:         break;
                   8092: #endif
                   8093:     case TARGET_NR_gettid:
                   8094:         ret = get_errno(gettid());
                   8095:         break;
1.1.1.6   root     8096: #ifdef TARGET_NR_readahead
1.1       root     8097:     case TARGET_NR_readahead:
1.1.1.7   root     8098: #if TARGET_ABI_BITS == 32
1.1.1.12  root     8099:         if (regpairs_aligned(cpu_env)) {
1.1.1.7   root     8100:             arg2 = arg3;
                   8101:             arg3 = arg4;
                   8102:             arg4 = arg5;
                   8103:         }
                   8104:         ret = get_errno(readahead(arg1, ((off64_t)arg3 << 32) | arg2, arg4));
                   8105: #else
                   8106:         ret = get_errno(readahead(arg1, arg2, arg3));
                   8107: #endif
                   8108:         break;
1.1.1.6   root     8109: #endif
1.1.1.13  root     8110: #ifdef CONFIG_ATTR
1.1       root     8111: #ifdef TARGET_NR_setxattr
                   8112:     case TARGET_NR_listxattr:
                   8113:     case TARGET_NR_llistxattr:
1.1.1.14! root     8114:     {
        !          8115:         void *p, *b = 0;
        !          8116:         if (arg2) {
        !          8117:             b = lock_user(VERIFY_WRITE, arg2, arg3, 0);
        !          8118:             if (!b) {
        !          8119:                 ret = -TARGET_EFAULT;
        !          8120:                 break;
        !          8121:             }
        !          8122:         }
        !          8123:         p = lock_user_string(arg1);
        !          8124:         if (p) {
        !          8125:             if (num == TARGET_NR_listxattr) {
        !          8126:                 ret = get_errno(listxattr(p, b, arg3));
        !          8127:             } else {
        !          8128:                 ret = get_errno(llistxattr(p, b, arg3));
        !          8129:             }
        !          8130:         } else {
        !          8131:             ret = -TARGET_EFAULT;
        !          8132:         }
        !          8133:         unlock_user(p, arg1, 0);
        !          8134:         unlock_user(b, arg2, arg3);
        !          8135:         break;
        !          8136:     }
1.1       root     8137:     case TARGET_NR_flistxattr:
1.1.1.14! root     8138:     {
        !          8139:         void *b = 0;
        !          8140:         if (arg2) {
        !          8141:             b = lock_user(VERIFY_WRITE, arg2, arg3, 0);
        !          8142:             if (!b) {
        !          8143:                 ret = -TARGET_EFAULT;
        !          8144:                 break;
        !          8145:             }
        !          8146:         }
        !          8147:         ret = get_errno(flistxattr(arg1, b, arg3));
        !          8148:         unlock_user(b, arg2, arg3);
1.1.1.8   root     8149:         break;
1.1.1.14! root     8150:     }
1.1.1.13  root     8151:     case TARGET_NR_setxattr:
1.1.1.14! root     8152:     case TARGET_NR_lsetxattr:
1.1.1.13  root     8153:         {
1.1.1.14! root     8154:             void *p, *n, *v = 0;
        !          8155:             if (arg3) {
        !          8156:                 v = lock_user(VERIFY_READ, arg3, arg4, 1);
        !          8157:                 if (!v) {
        !          8158:                     ret = -TARGET_EFAULT;
        !          8159:                     break;
        !          8160:                 }
        !          8161:             }
1.1.1.13  root     8162:             p = lock_user_string(arg1);
                   8163:             n = lock_user_string(arg2);
1.1.1.14! root     8164:             if (p && n) {
        !          8165:                 if (num == TARGET_NR_setxattr) {
        !          8166:                     ret = get_errno(setxattr(p, n, v, arg4, arg5));
        !          8167:                 } else {
        !          8168:                     ret = get_errno(lsetxattr(p, n, v, arg4, arg5));
        !          8169:                 }
1.1.1.13  root     8170:             } else {
                   8171:                 ret = -TARGET_EFAULT;
                   8172:             }
                   8173:             unlock_user(p, arg1, 0);
                   8174:             unlock_user(n, arg2, 0);
                   8175:             unlock_user(v, arg3, 0);
                   8176:         }
                   8177:         break;
1.1.1.14! root     8178:     case TARGET_NR_fsetxattr:
        !          8179:         {
        !          8180:             void *n, *v = 0;
        !          8181:             if (arg3) {
        !          8182:                 v = lock_user(VERIFY_READ, arg3, arg4, 1);
        !          8183:                 if (!v) {
        !          8184:                     ret = -TARGET_EFAULT;
        !          8185:                     break;
        !          8186:                 }
        !          8187:             }
        !          8188:             n = lock_user_string(arg2);
        !          8189:             if (n) {
        !          8190:                 ret = get_errno(fsetxattr(arg1, n, v, arg4, arg5));
        !          8191:             } else {
        !          8192:                 ret = -TARGET_EFAULT;
        !          8193:             }
        !          8194:             unlock_user(n, arg2, 0);
        !          8195:             unlock_user(v, arg3, 0);
        !          8196:         }
        !          8197:         break;
1.1.1.13  root     8198:     case TARGET_NR_getxattr:
1.1.1.14! root     8199:     case TARGET_NR_lgetxattr:
1.1.1.13  root     8200:         {
1.1.1.14! root     8201:             void *p, *n, *v = 0;
        !          8202:             if (arg3) {
        !          8203:                 v = lock_user(VERIFY_WRITE, arg3, arg4, 0);
        !          8204:                 if (!v) {
        !          8205:                     ret = -TARGET_EFAULT;
        !          8206:                     break;
        !          8207:                 }
        !          8208:             }
1.1.1.13  root     8209:             p = lock_user_string(arg1);
                   8210:             n = lock_user_string(arg2);
1.1.1.14! root     8211:             if (p && n) {
        !          8212:                 if (num == TARGET_NR_getxattr) {
        !          8213:                     ret = get_errno(getxattr(p, n, v, arg4));
        !          8214:                 } else {
        !          8215:                     ret = get_errno(lgetxattr(p, n, v, arg4));
        !          8216:                 }
1.1.1.13  root     8217:             } else {
                   8218:                 ret = -TARGET_EFAULT;
                   8219:             }
                   8220:             unlock_user(p, arg1, 0);
                   8221:             unlock_user(n, arg2, 0);
                   8222:             unlock_user(v, arg3, arg4);
                   8223:         }
                   8224:         break;
1.1.1.14! root     8225:     case TARGET_NR_fgetxattr:
        !          8226:         {
        !          8227:             void *n, *v = 0;
        !          8228:             if (arg3) {
        !          8229:                 v = lock_user(VERIFY_WRITE, arg3, arg4, 0);
        !          8230:                 if (!v) {
        !          8231:                     ret = -TARGET_EFAULT;
        !          8232:                     break;
        !          8233:                 }
        !          8234:             }
        !          8235:             n = lock_user_string(arg2);
        !          8236:             if (n) {
        !          8237:                 ret = get_errno(fgetxattr(arg1, n, v, arg4));
        !          8238:             } else {
        !          8239:                 ret = -TARGET_EFAULT;
        !          8240:             }
        !          8241:             unlock_user(n, arg2, 0);
        !          8242:             unlock_user(v, arg3, arg4);
        !          8243:         }
        !          8244:         break;
1.1.1.13  root     8245:     case TARGET_NR_removexattr:
1.1.1.14! root     8246:     case TARGET_NR_lremovexattr:
1.1.1.13  root     8247:         {
                   8248:             void *p, *n;
                   8249:             p = lock_user_string(arg1);
                   8250:             n = lock_user_string(arg2);
                   8251:             if (p && n) {
1.1.1.14! root     8252:                 if (num == TARGET_NR_removexattr) {
        !          8253:                     ret = get_errno(removexattr(p, n));
        !          8254:                 } else {
        !          8255:                     ret = get_errno(lremovexattr(p, n));
        !          8256:                 }
1.1.1.13  root     8257:             } else {
                   8258:                 ret = -TARGET_EFAULT;
                   8259:             }
                   8260:             unlock_user(p, arg1, 0);
                   8261:             unlock_user(n, arg2, 0);
                   8262:         }
                   8263:         break;
1.1.1.14! root     8264:     case TARGET_NR_fremovexattr:
        !          8265:         {
        !          8266:             void *n;
        !          8267:             n = lock_user_string(arg2);
        !          8268:             if (n) {
        !          8269:                 ret = get_errno(fremovexattr(arg1, n));
        !          8270:             } else {
        !          8271:                 ret = -TARGET_EFAULT;
        !          8272:             }
        !          8273:             unlock_user(n, arg2, 0);
        !          8274:         }
        !          8275:         break;
1.1       root     8276: #endif
1.1.1.13  root     8277: #endif /* CONFIG_ATTR */
1.1       root     8278: #ifdef TARGET_NR_set_thread_area
                   8279:     case TARGET_NR_set_thread_area:
1.1.1.6   root     8280: #if defined(TARGET_MIPS)
                   8281:       ((CPUMIPSState *) cpu_env)->tls_value = arg1;
                   8282:       ret = 0;
                   8283:       break;
1.1.1.7   root     8284: #elif defined(TARGET_CRIS)
                   8285:       if (arg1 & 0xff)
                   8286:           ret = -TARGET_EINVAL;
                   8287:       else {
                   8288:           ((CPUCRISState *) cpu_env)->pregs[PR_PID] = arg1;
                   8289:           ret = 0;
                   8290:       }
                   8291:       break;
1.1.1.6   root     8292: #elif defined(TARGET_I386) && defined(TARGET_ABI32)
                   8293:       ret = do_set_thread_area(cpu_env, arg1);
                   8294:       break;
                   8295: #else
                   8296:       goto unimplemented_nowarn;
                   8297: #endif
                   8298: #endif
                   8299: #ifdef TARGET_NR_get_thread_area
1.1       root     8300:     case TARGET_NR_get_thread_area:
1.1.1.6   root     8301: #if defined(TARGET_I386) && defined(TARGET_ABI32)
                   8302:         ret = do_get_thread_area(cpu_env, arg1);
                   8303: #else
1.1       root     8304:         goto unimplemented_nowarn;
                   8305: #endif
1.1.1.6   root     8306: #endif
1.1.1.4   root     8307: #ifdef TARGET_NR_getdomainname
                   8308:     case TARGET_NR_getdomainname:
                   8309:         goto unimplemented_nowarn;
                   8310: #endif
1.1.1.6   root     8311: 
                   8312: #ifdef TARGET_NR_clock_gettime
                   8313:     case TARGET_NR_clock_gettime:
                   8314:     {
                   8315:         struct timespec ts;
                   8316:         ret = get_errno(clock_gettime(arg1, &ts));
                   8317:         if (!is_error(ret)) {
                   8318:             host_to_target_timespec(arg2, &ts);
                   8319:         }
                   8320:         break;
                   8321:     }
                   8322: #endif
                   8323: #ifdef TARGET_NR_clock_getres
                   8324:     case TARGET_NR_clock_getres:
                   8325:     {
                   8326:         struct timespec ts;
                   8327:         ret = get_errno(clock_getres(arg1, &ts));
                   8328:         if (!is_error(ret)) {
                   8329:             host_to_target_timespec(arg2, &ts);
                   8330:         }
                   8331:         break;
                   8332:     }
                   8333: #endif
1.1.1.7   root     8334: #ifdef TARGET_NR_clock_nanosleep
                   8335:     case TARGET_NR_clock_nanosleep:
                   8336:     {
                   8337:         struct timespec ts;
                   8338:         target_to_host_timespec(&ts, arg3);
                   8339:         ret = get_errno(clock_nanosleep(arg1, arg2, &ts, arg4 ? &ts : NULL));
                   8340:         if (arg4)
                   8341:             host_to_target_timespec(arg4, &ts);
                   8342:         break;
                   8343:     }
                   8344: #endif
1.1.1.6   root     8345: 
                   8346: #if defined(TARGET_NR_set_tid_address) && defined(__NR_set_tid_address)
                   8347:     case TARGET_NR_set_tid_address:
                   8348:         ret = get_errno(set_tid_address((int *)g2h(arg1)));
                   8349:         break;
                   8350: #endif
                   8351: 
                   8352: #if defined(TARGET_NR_tkill) && defined(__NR_tkill)
                   8353:     case TARGET_NR_tkill:
1.1.1.7   root     8354:         ret = get_errno(sys_tkill((int)arg1, target_to_host_signal(arg2)));
1.1.1.6   root     8355:         break;
                   8356: #endif
                   8357: 
                   8358: #if defined(TARGET_NR_tgkill) && defined(__NR_tgkill)
                   8359:     case TARGET_NR_tgkill:
1.1.1.7   root     8360:        ret = get_errno(sys_tgkill((int)arg1, (int)arg2,
                   8361:                         target_to_host_signal(arg3)));
1.1.1.6   root     8362:        break;
                   8363: #endif
                   8364: 
                   8365: #ifdef TARGET_NR_set_robust_list
                   8366:     case TARGET_NR_set_robust_list:
                   8367:        goto unimplemented_nowarn;
                   8368: #endif
                   8369: 
                   8370: #if defined(TARGET_NR_utimensat) && defined(__NR_utimensat)
                   8371:     case TARGET_NR_utimensat:
                   8372:         {
1.1.1.8   root     8373:             struct timespec *tsp, ts[2];
                   8374:             if (!arg3) {
                   8375:                 tsp = NULL;
                   8376:             } else {
                   8377:                 target_to_host_timespec(ts, arg3);
                   8378:                 target_to_host_timespec(ts+1, arg3+sizeof(struct target_timespec));
                   8379:                 tsp = ts;
                   8380:             }
1.1.1.6   root     8381:             if (!arg2)
1.1.1.8   root     8382:                 ret = get_errno(sys_utimensat(arg1, NULL, tsp, arg4));
1.1.1.6   root     8383:             else {
                   8384:                 if (!(p = lock_user_string(arg2))) {
                   8385:                     ret = -TARGET_EFAULT;
                   8386:                     goto fail;
                   8387:                 }
1.1.1.8   root     8388:                 ret = get_errno(sys_utimensat(arg1, path(p), tsp, arg4));
1.1.1.6   root     8389:                 unlock_user(p, arg2, 0);
                   8390:             }
                   8391:         }
                   8392:        break;
                   8393: #endif
1.1.1.9   root     8394: #if defined(CONFIG_USE_NPTL)
1.1.1.7   root     8395:     case TARGET_NR_futex:
                   8396:         ret = do_futex(arg1, arg2, arg3, arg4, arg5, arg6);
                   8397:         break;
                   8398: #endif
1.1.1.8   root     8399: #if defined(TARGET_NR_inotify_init) && defined(__NR_inotify_init)
1.1.1.7   root     8400:     case TARGET_NR_inotify_init:
                   8401:         ret = get_errno(sys_inotify_init());
                   8402:         break;
                   8403: #endif
1.1.1.10  root     8404: #ifdef CONFIG_INOTIFY1
                   8405: #if defined(TARGET_NR_inotify_init1) && defined(__NR_inotify_init1)
                   8406:     case TARGET_NR_inotify_init1:
                   8407:         ret = get_errno(sys_inotify_init1(arg1));
                   8408:         break;
                   8409: #endif
                   8410: #endif
1.1.1.8   root     8411: #if defined(TARGET_NR_inotify_add_watch) && defined(__NR_inotify_add_watch)
1.1.1.7   root     8412:     case TARGET_NR_inotify_add_watch:
                   8413:         p = lock_user_string(arg2);
                   8414:         ret = get_errno(sys_inotify_add_watch(arg1, path(p), arg3));
                   8415:         unlock_user(p, arg2, 0);
                   8416:         break;
                   8417: #endif
1.1.1.8   root     8418: #if defined(TARGET_NR_inotify_rm_watch) && defined(__NR_inotify_rm_watch)
1.1.1.7   root     8419:     case TARGET_NR_inotify_rm_watch:
                   8420:         ret = get_errno(sys_inotify_rm_watch(arg1, arg2));
                   8421:         break;
                   8422: #endif
1.1.1.6   root     8423: 
1.1.1.9   root     8424: #if defined(TARGET_NR_mq_open) && defined(__NR_mq_open)
1.1.1.8   root     8425:     case TARGET_NR_mq_open:
                   8426:         {
                   8427:             struct mq_attr posix_mq_attr;
                   8428: 
                   8429:             p = lock_user_string(arg1 - 1);
                   8430:             if (arg4 != 0)
                   8431:                 copy_from_user_mq_attr (&posix_mq_attr, arg4);
                   8432:             ret = get_errno(mq_open(p, arg2, arg3, &posix_mq_attr));
                   8433:             unlock_user (p, arg1, 0);
                   8434:         }
                   8435:         break;
                   8436: 
                   8437:     case TARGET_NR_mq_unlink:
                   8438:         p = lock_user_string(arg1 - 1);
                   8439:         ret = get_errno(mq_unlink(p));
                   8440:         unlock_user (p, arg1, 0);
                   8441:         break;
                   8442: 
                   8443:     case TARGET_NR_mq_timedsend:
                   8444:         {
                   8445:             struct timespec ts;
                   8446: 
                   8447:             p = lock_user (VERIFY_READ, arg2, arg3, 1);
                   8448:             if (arg5 != 0) {
                   8449:                 target_to_host_timespec(&ts, arg5);
                   8450:                 ret = get_errno(mq_timedsend(arg1, p, arg3, arg4, &ts));
                   8451:                 host_to_target_timespec(arg5, &ts);
                   8452:             }
                   8453:             else
                   8454:                 ret = get_errno(mq_send(arg1, p, arg3, arg4));
                   8455:             unlock_user (p, arg2, arg3);
                   8456:         }
                   8457:         break;
                   8458: 
                   8459:     case TARGET_NR_mq_timedreceive:
                   8460:         {
                   8461:             struct timespec ts;
                   8462:             unsigned int prio;
                   8463: 
                   8464:             p = lock_user (VERIFY_READ, arg2, arg3, 1);
                   8465:             if (arg5 != 0) {
                   8466:                 target_to_host_timespec(&ts, arg5);
                   8467:                 ret = get_errno(mq_timedreceive(arg1, p, arg3, &prio, &ts));
                   8468:                 host_to_target_timespec(arg5, &ts);
                   8469:             }
                   8470:             else
                   8471:                 ret = get_errno(mq_receive(arg1, p, arg3, &prio));
                   8472:             unlock_user (p, arg2, arg3);
                   8473:             if (arg4 != 0)
                   8474:                 put_user_u32(prio, arg4);
                   8475:         }
                   8476:         break;
                   8477: 
                   8478:     /* Not implemented for now... */
                   8479: /*     case TARGET_NR_mq_notify: */
                   8480: /*         break; */
                   8481: 
                   8482:     case TARGET_NR_mq_getsetattr:
                   8483:         {
                   8484:             struct mq_attr posix_mq_attr_in, posix_mq_attr_out;
                   8485:             ret = 0;
                   8486:             if (arg3 != 0) {
                   8487:                 ret = mq_getattr(arg1, &posix_mq_attr_out);
                   8488:                 copy_to_user_mq_attr(arg3, &posix_mq_attr_out);
                   8489:             }
                   8490:             if (arg2 != 0) {
                   8491:                 copy_from_user_mq_attr(&posix_mq_attr_in, arg2);
                   8492:                 ret |= mq_setattr(arg1, &posix_mq_attr_in, &posix_mq_attr_out);
                   8493:             }
                   8494: 
                   8495:         }
                   8496:         break;
                   8497: #endif
                   8498: 
                   8499: #ifdef CONFIG_SPLICE
                   8500: #ifdef TARGET_NR_tee
                   8501:     case TARGET_NR_tee:
                   8502:         {
                   8503:             ret = get_errno(tee(arg1,arg2,arg3,arg4));
                   8504:         }
                   8505:         break;
                   8506: #endif
                   8507: #ifdef TARGET_NR_splice
                   8508:     case TARGET_NR_splice:
                   8509:         {
                   8510:             loff_t loff_in, loff_out;
                   8511:             loff_t *ploff_in = NULL, *ploff_out = NULL;
                   8512:             if(arg2) {
                   8513:                 get_user_u64(loff_in, arg2);
                   8514:                 ploff_in = &loff_in;
                   8515:             }
                   8516:             if(arg4) {
                   8517:                 get_user_u64(loff_out, arg2);
                   8518:                 ploff_out = &loff_out;
                   8519:             }
                   8520:             ret = get_errno(splice(arg1, ploff_in, arg3, ploff_out, arg5, arg6));
                   8521:         }
                   8522:         break;
                   8523: #endif
                   8524: #ifdef TARGET_NR_vmsplice
                   8525:        case TARGET_NR_vmsplice:
                   8526:         {
                   8527:             int count = arg3;
                   8528:             struct iovec *vec;
                   8529: 
                   8530:             vec = alloca(count * sizeof(struct iovec));
                   8531:             if (lock_iovec(VERIFY_READ, vec, arg2, count, 1) < 0)
                   8532:                 goto efault;
                   8533:             ret = get_errno(vmsplice(arg1, vec, count, arg4));
                   8534:             unlock_iovec(vec, arg2, count, 0);
                   8535:         }
                   8536:         break;
                   8537: #endif
                   8538: #endif /* CONFIG_SPLICE */
1.1.1.9   root     8539: #ifdef CONFIG_EVENTFD
                   8540: #if defined(TARGET_NR_eventfd)
                   8541:     case TARGET_NR_eventfd:
                   8542:         ret = get_errno(eventfd(arg1, 0));
                   8543:         break;
                   8544: #endif
                   8545: #if defined(TARGET_NR_eventfd2)
                   8546:     case TARGET_NR_eventfd2:
                   8547:         ret = get_errno(eventfd(arg1, arg2));
                   8548:         break;
                   8549: #endif
                   8550: #endif /* CONFIG_EVENTFD  */
                   8551: #if defined(CONFIG_FALLOCATE) && defined(TARGET_NR_fallocate)
                   8552:     case TARGET_NR_fallocate:
1.1.1.14! root     8553: #if TARGET_ABI_BITS == 32
        !          8554:         ret = get_errno(fallocate(arg1, arg2, target_offset64(arg3, arg4),
        !          8555:                                   target_offset64(arg5, arg6)));
        !          8556: #else
1.1.1.9   root     8557:         ret = get_errno(fallocate(arg1, arg2, arg3, arg4));
1.1.1.14! root     8558: #endif
1.1.1.9   root     8559:         break;
                   8560: #endif
1.1.1.11  root     8561: #if defined(CONFIG_SYNC_FILE_RANGE)
                   8562: #if defined(TARGET_NR_sync_file_range)
                   8563:     case TARGET_NR_sync_file_range:
                   8564: #if TARGET_ABI_BITS == 32
1.1.1.12  root     8565: #if defined(TARGET_MIPS)
                   8566:         ret = get_errno(sync_file_range(arg1, target_offset64(arg3, arg4),
                   8567:                                         target_offset64(arg5, arg6), arg7));
                   8568: #else
1.1.1.11  root     8569:         ret = get_errno(sync_file_range(arg1, target_offset64(arg2, arg3),
                   8570:                                         target_offset64(arg4, arg5), arg6));
1.1.1.12  root     8571: #endif /* !TARGET_MIPS */
1.1.1.11  root     8572: #else
                   8573:         ret = get_errno(sync_file_range(arg1, arg2, arg3, arg4));
                   8574: #endif
                   8575:         break;
                   8576: #endif
                   8577: #if defined(TARGET_NR_sync_file_range2)
                   8578:     case TARGET_NR_sync_file_range2:
                   8579:         /* This is like sync_file_range but the arguments are reordered */
                   8580: #if TARGET_ABI_BITS == 32
                   8581:         ret = get_errno(sync_file_range(arg1, target_offset64(arg3, arg4),
                   8582:                                         target_offset64(arg5, arg6), arg2));
                   8583: #else
                   8584:         ret = get_errno(sync_file_range(arg1, arg3, arg4, arg2));
                   8585: #endif
                   8586:         break;
                   8587: #endif
                   8588: #endif
1.1.1.12  root     8589: #if defined(CONFIG_EPOLL)
                   8590: #if defined(TARGET_NR_epoll_create)
                   8591:     case TARGET_NR_epoll_create:
                   8592:         ret = get_errno(epoll_create(arg1));
                   8593:         break;
                   8594: #endif
                   8595: #if defined(TARGET_NR_epoll_create1) && defined(CONFIG_EPOLL_CREATE1)
                   8596:     case TARGET_NR_epoll_create1:
                   8597:         ret = get_errno(epoll_create1(arg1));
                   8598:         break;
                   8599: #endif
                   8600: #if defined(TARGET_NR_epoll_ctl)
                   8601:     case TARGET_NR_epoll_ctl:
                   8602:     {
                   8603:         struct epoll_event ep;
                   8604:         struct epoll_event *epp = 0;
                   8605:         if (arg4) {
                   8606:             struct target_epoll_event *target_ep;
                   8607:             if (!lock_user_struct(VERIFY_READ, target_ep, arg4, 1)) {
                   8608:                 goto efault;
                   8609:             }
                   8610:             ep.events = tswap32(target_ep->events);
                   8611:             /* The epoll_data_t union is just opaque data to the kernel,
                   8612:              * so we transfer all 64 bits across and need not worry what
                   8613:              * actual data type it is.
                   8614:              */
                   8615:             ep.data.u64 = tswap64(target_ep->data.u64);
                   8616:             unlock_user_struct(target_ep, arg4, 0);
                   8617:             epp = &ep;
                   8618:         }
                   8619:         ret = get_errno(epoll_ctl(arg1, arg2, arg3, epp));
                   8620:         break;
                   8621:     }
                   8622: #endif
                   8623: 
                   8624: #if defined(TARGET_NR_epoll_pwait) && defined(CONFIG_EPOLL_PWAIT)
                   8625: #define IMPLEMENT_EPOLL_PWAIT
                   8626: #endif
                   8627: #if defined(TARGET_NR_epoll_wait) || defined(IMPLEMENT_EPOLL_PWAIT)
                   8628: #if defined(TARGET_NR_epoll_wait)
                   8629:     case TARGET_NR_epoll_wait:
                   8630: #endif
                   8631: #if defined(IMPLEMENT_EPOLL_PWAIT)
                   8632:     case TARGET_NR_epoll_pwait:
                   8633: #endif
                   8634:     {
                   8635:         struct target_epoll_event *target_ep;
                   8636:         struct epoll_event *ep;
                   8637:         int epfd = arg1;
                   8638:         int maxevents = arg3;
                   8639:         int timeout = arg4;
                   8640: 
                   8641:         target_ep = lock_user(VERIFY_WRITE, arg2,
                   8642:                               maxevents * sizeof(struct target_epoll_event), 1);
                   8643:         if (!target_ep) {
                   8644:             goto efault;
                   8645:         }
                   8646: 
                   8647:         ep = alloca(maxevents * sizeof(struct epoll_event));
                   8648: 
                   8649:         switch (num) {
                   8650: #if defined(IMPLEMENT_EPOLL_PWAIT)
                   8651:         case TARGET_NR_epoll_pwait:
                   8652:         {
                   8653:             target_sigset_t *target_set;
                   8654:             sigset_t _set, *set = &_set;
                   8655: 
                   8656:             if (arg5) {
                   8657:                 target_set = lock_user(VERIFY_READ, arg5,
                   8658:                                        sizeof(target_sigset_t), 1);
                   8659:                 if (!target_set) {
                   8660:                     unlock_user(target_ep, arg2, 0);
                   8661:                     goto efault;
                   8662:                 }
                   8663:                 target_to_host_sigset(set, target_set);
                   8664:                 unlock_user(target_set, arg5, 0);
                   8665:             } else {
                   8666:                 set = NULL;
                   8667:             }
                   8668: 
                   8669:             ret = get_errno(epoll_pwait(epfd, ep, maxevents, timeout, set));
                   8670:             break;
                   8671:         }
                   8672: #endif
                   8673: #if defined(TARGET_NR_epoll_wait)
                   8674:         case TARGET_NR_epoll_wait:
                   8675:             ret = get_errno(epoll_wait(epfd, ep, maxevents, timeout));
                   8676:             break;
                   8677: #endif
                   8678:         default:
                   8679:             ret = -TARGET_ENOSYS;
                   8680:         }
                   8681:         if (!is_error(ret)) {
                   8682:             int i;
                   8683:             for (i = 0; i < ret; i++) {
                   8684:                 target_ep[i].events = tswap32(ep[i].events);
                   8685:                 target_ep[i].data.u64 = tswap64(ep[i].data.u64);
                   8686:             }
                   8687:         }
                   8688:         unlock_user(target_ep, arg2, ret * sizeof(struct target_epoll_event));
                   8689:         break;
                   8690:     }
                   8691: #endif
                   8692: #endif
                   8693: #ifdef TARGET_NR_prlimit64
                   8694:     case TARGET_NR_prlimit64:
                   8695:     {
                   8696:         /* args: pid, resource number, ptr to new rlimit, ptr to old rlimit */
                   8697:         struct target_rlimit64 *target_rnew, *target_rold;
                   8698:         struct host_rlimit64 rnew, rold, *rnewp = 0;
                   8699:         if (arg3) {
                   8700:             if (!lock_user_struct(VERIFY_READ, target_rnew, arg3, 1)) {
                   8701:                 goto efault;
                   8702:             }
                   8703:             rnew.rlim_cur = tswap64(target_rnew->rlim_cur);
                   8704:             rnew.rlim_max = tswap64(target_rnew->rlim_max);
                   8705:             unlock_user_struct(target_rnew, arg3, 0);
                   8706:             rnewp = &rnew;
                   8707:         }
                   8708: 
                   8709:         ret = get_errno(sys_prlimit64(arg1, arg2, rnewp, arg4 ? &rold : 0));
                   8710:         if (!is_error(ret) && arg4) {
                   8711:             if (!lock_user_struct(VERIFY_WRITE, target_rold, arg4, 1)) {
                   8712:                 goto efault;
                   8713:             }
                   8714:             target_rold->rlim_cur = tswap64(rold.rlim_cur);
                   8715:             target_rold->rlim_max = tswap64(rold.rlim_max);
                   8716:             unlock_user_struct(target_rold, arg4, 1);
                   8717:         }
                   8718:         break;
                   8719:     }
                   8720: #endif
1.1       root     8721:     default:
                   8722:     unimplemented:
                   8723:         gemu_log("qemu: Unsupported syscall: %d\n", num);
1.1.1.6   root     8724: #if defined(TARGET_NR_setxattr) || defined(TARGET_NR_get_thread_area) || defined(TARGET_NR_getdomainname) || defined(TARGET_NR_set_robust_list)
1.1       root     8725:     unimplemented_nowarn:
                   8726: #endif
1.1.1.6   root     8727:         ret = -TARGET_ENOSYS;
1.1       root     8728:         break;
                   8729:     }
1.1.1.6   root     8730: fail:
1.1       root     8731: #ifdef DEBUG
1.1.1.8   root     8732:     gemu_log(" = " TARGET_ABI_FMT_ld "\n", ret);
1.1       root     8733: #endif
1.1.1.6   root     8734:     if(do_strace)
                   8735:         print_syscall_ret(num, ret);
1.1       root     8736:     return ret;
1.1.1.6   root     8737: efault:
                   8738:     ret = -TARGET_EFAULT;
                   8739:     goto fail;
1.1       root     8740: }

unix.superglobalmegacorp.com

This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.