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

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
                     17:  *  along with this program; if not, write to the Free Software
1.1.1.7 ! root       18:  *  Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston,
        !            19:  *  MA 02110-1301, USA.
1.1       root       20:  */
                     21: #include <stdlib.h>
                     22: #include <stdio.h>
                     23: #include <stdarg.h>
                     24: #include <string.h>
                     25: #include <elf.h>
                     26: #include <endian.h>
                     27: #include <errno.h>
                     28: #include <unistd.h>
                     29: #include <fcntl.h>
                     30: #include <time.h>
1.1.1.7 ! root       31: #include <limits.h>
1.1       root       32: #include <sys/types.h>
1.1.1.6   root       33: #include <sys/ipc.h>
                     34: #include <sys/msg.h>
1.1       root       35: #include <sys/wait.h>
                     36: #include <sys/time.h>
                     37: #include <sys/stat.h>
                     38: #include <sys/mount.h>
1.1.1.6   root       39: #include <sys/prctl.h>
1.1       root       40: #include <sys/resource.h>
                     41: #include <sys/mman.h>
                     42: #include <sys/swap.h>
                     43: #include <signal.h>
                     44: #include <sched.h>
                     45: #include <sys/socket.h>
                     46: #include <sys/uio.h>
                     47: #include <sys/poll.h>
                     48: #include <sys/times.h>
                     49: #include <sys/shm.h>
1.1.1.5   root       50: #include <sys/sem.h>
1.1.1.2   root       51: #include <sys/statfs.h>
1.1       root       52: #include <utime.h>
                     53: #include <sys/sysinfo.h>
                     54: //#include <sys/user.h>
                     55: #include <netinet/ip.h>
                     56: #include <netinet/tcp.h>
1.1.1.7 ! root       57: #include <qemu-common.h>
        !            58: #ifdef HAVE_GPROF
        !            59: #include <sys/gmon.h>
        !            60: #endif
1.1       root       61: 
                     62: #define termios host_termios
                     63: #define winsize host_winsize
                     64: #define termio host_termio
                     65: #define sgttyb host_sgttyb /* same as target */
                     66: #define tchars host_tchars /* same as target */
                     67: #define ltchars host_ltchars /* same as target */
                     68: 
                     69: #include <linux/termios.h>
                     70: #include <linux/unistd.h>
                     71: #include <linux/utsname.h>
                     72: #include <linux/cdrom.h>
                     73: #include <linux/hdreg.h>
                     74: #include <linux/soundcard.h>
                     75: #include <linux/kd.h>
1.1.1.7 ! root       76: #include <linux/mtio.h>
        !            77: #include "linux_loop.h"
1.1       root       78: 
                     79: #include "qemu.h"
1.1.1.7 ! root       80: #include "qemu-common.h"
        !            81: 
        !            82: #if defined(USE_NPTL)
        !            83: #include <linux/futex.h>
        !            84: #define CLONE_NPTL_FLAGS2 (CLONE_SETTLS | \
        !            85:     CLONE_PARENT_SETTID | CLONE_CHILD_SETTID | CLONE_CHILD_CLEARTID)
        !            86: #else
        !            87: /* XXX: Hardcode the above values.  */
        !            88: #define CLONE_NPTL_FLAGS2 0
        !            89: #endif
1.1       root       90: 
                     91: //#define DEBUG
                     92: 
1.1.1.5   root       93: #if defined(TARGET_I386) || defined(TARGET_ARM) || defined(TARGET_SPARC) \
1.1.1.6   root       94:     || defined(TARGET_M68K) || defined(TARGET_SH4) || defined(TARGET_CRIS)
1.1       root       95: /* 16 bit uid wrappers emulation */
                     96: #define USE_UID16
                     97: #endif
                     98: 
                     99: //#include <linux/msdos_fs.h>
1.1.1.7 ! root      100: #define        VFAT_IOCTL_READDIR_BOTH         _IOR('r', 1, struct linux_dirent [2])
        !           101: #define        VFAT_IOCTL_READDIR_SHORT        _IOR('r', 2, struct linux_dirent [2])
1.1       root      102: 
                    103: 
                    104: #undef _syscall0
                    105: #undef _syscall1
                    106: #undef _syscall2
                    107: #undef _syscall3
                    108: #undef _syscall4
                    109: #undef _syscall5
1.1.1.4   root      110: #undef _syscall6
1.1       root      111: 
1.1.1.4   root      112: #define _syscall0(type,name)           \
1.1.1.7 ! root      113: static type name (void)                        \
1.1.1.4   root      114: {                                      \
                    115:        return syscall(__NR_##name);    \
                    116: }
                    117: 
                    118: #define _syscall1(type,name,type1,arg1)                \
1.1.1.7 ! root      119: static type name (type1 arg1)                  \
1.1.1.4   root      120: {                                              \
                    121:        return syscall(__NR_##name, arg1);      \
                    122: }
                    123: 
                    124: #define _syscall2(type,name,type1,arg1,type2,arg2)     \
1.1.1.7 ! root      125: static type name (type1 arg1,type2 arg2)               \
1.1.1.4   root      126: {                                                      \
                    127:        return syscall(__NR_##name, arg1, arg2);        \
                    128: }
                    129: 
                    130: #define _syscall3(type,name,type1,arg1,type2,arg2,type3,arg3)  \
1.1.1.7 ! root      131: static type name (type1 arg1,type2 arg2,type3 arg3)            \
1.1.1.4   root      132: {                                                              \
                    133:        return syscall(__NR_##name, arg1, arg2, arg3);          \
                    134: }
                    135: 
                    136: #define _syscall4(type,name,type1,arg1,type2,arg2,type3,arg3,type4,arg4)       \
1.1.1.7 ! root      137: static type name (type1 arg1,type2 arg2,type3 arg3,type4 arg4)                 \
1.1.1.4   root      138: {                                                                              \
                    139:        return syscall(__NR_##name, arg1, arg2, arg3, arg4);                    \
1.1       root      140: }
1.1.1.4   root      141: 
                    142: #define _syscall5(type,name,type1,arg1,type2,arg2,type3,arg3,type4,arg4,       \
                    143:                  type5,arg5)                                                   \
1.1.1.7 ! root      144: static type name (type1 arg1,type2 arg2,type3 arg3,type4 arg4,type5 arg5)      \
1.1.1.4   root      145: {                                                                              \
                    146:        return syscall(__NR_##name, arg1, arg2, arg3, arg4, arg5);              \
                    147: }
                    148: 
                    149: 
                    150: #define _syscall6(type,name,type1,arg1,type2,arg2,type3,arg3,type4,arg4,       \
                    151:                  type5,arg5,type6,arg6)                                        \
1.1.1.7 ! root      152: static type name (type1 arg1,type2 arg2,type3 arg3,type4 arg4,type5 arg5,      \
        !           153:                   type6 arg6)                                                  \
1.1.1.4   root      154: {                                                                              \
                    155:        return syscall(__NR_##name, arg1, arg2, arg3, arg4, arg5, arg6);        \
                    156: }
                    157: 
1.1       root      158: 
1.1.1.7 ! root      159: #define __NR_sys_exit __NR_exit
1.1       root      160: #define __NR_sys_uname __NR_uname
1.1.1.6   root      161: #define __NR_sys_faccessat __NR_faccessat
                    162: #define __NR_sys_fchmodat __NR_fchmodat
                    163: #define __NR_sys_fchownat __NR_fchownat
1.1.1.7 ! root      164: #define __NR_sys_fstatat64 __NR_fstatat64
        !           165: #define __NR_sys_futimesat __NR_futimesat
1.1       root      166: #define __NR_sys_getcwd1 __NR_getcwd
                    167: #define __NR_sys_getdents __NR_getdents
                    168: #define __NR_sys_getdents64 __NR_getdents64
1.1.1.6   root      169: #define __NR_sys_getpriority __NR_getpriority
                    170: #define __NR_sys_linkat __NR_linkat
                    171: #define __NR_sys_mkdirat __NR_mkdirat
                    172: #define __NR_sys_mknodat __NR_mknodat
                    173: #define __NR_sys_openat __NR_openat
                    174: #define __NR_sys_readlinkat __NR_readlinkat
                    175: #define __NR_sys_renameat __NR_renameat
1.1       root      176: #define __NR_sys_rt_sigqueueinfo __NR_rt_sigqueueinfo
1.1.1.6   root      177: #define __NR_sys_symlinkat __NR_symlinkat
                    178: #define __NR_sys_syslog __NR_syslog
                    179: #define __NR_sys_tgkill __NR_tgkill
                    180: #define __NR_sys_tkill __NR_tkill
                    181: #define __NR_sys_unlinkat __NR_unlinkat
                    182: #define __NR_sys_utimensat __NR_utimensat
1.1.1.7 ! root      183: #define __NR_sys_futex __NR_futex
        !           184: #define __NR_sys_inotify_init __NR_inotify_init
        !           185: #define __NR_sys_inotify_add_watch __NR_inotify_add_watch
        !           186: #define __NR_sys_inotify_rm_watch __NR_inotify_rm_watch
1.1       root      187: 
                    188: #if defined(__alpha__) || defined (__ia64__) || defined(__x86_64__)
                    189: #define __NR__llseek __NR_lseek
                    190: #endif
                    191: 
                    192: #ifdef __NR_gettid
                    193: _syscall0(int, gettid)
                    194: #else
1.1.1.6   root      195: /* This is a replacement for the host gettid() and must return a host
                    196:    errno. */
1.1       root      197: static int gettid(void) {
                    198:     return -ENOSYS;
                    199: }
                    200: #endif
1.1.1.7 ! root      201: _syscall1(int,sys_exit,int,status)
1.1       root      202: _syscall1(int,sys_uname,struct new_utsname *,buf)
1.1.1.6   root      203: #if defined(TARGET_NR_faccessat) && defined(__NR_faccessat)
                    204: _syscall4(int,sys_faccessat,int,dirfd,const char *,pathname,int,mode,int,flags)
                    205: #endif
                    206: #if defined(TARGET_NR_fchmodat) && defined(__NR_fchmodat)
                    207: _syscall4(int,sys_fchmodat,int,dirfd,const char *,pathname,
                    208:           mode_t,mode,int,flags)
                    209: #endif
1.1.1.7 ! root      210: #if defined(TARGET_NR_fchownat) && defined(__NR_fchownat) && defined(USE_UID16)
1.1.1.6   root      211: _syscall5(int,sys_fchownat,int,dirfd,const char *,pathname,
                    212:           uid_t,owner,gid_t,group,int,flags)
                    213: #endif
1.1.1.7 ! root      214: #if defined(TARGET_NR_fstatat64) && defined(__NR_fstatat64)
        !           215: _syscall4(int,sys_fstatat64,int,dirfd,const char *,pathname,
        !           216:           struct stat *,buf,int,flags)
        !           217: #endif
        !           218: #if defined(TARGET_NR_futimesat) && defined(__NR_futimesat)
        !           219: _syscall3(int,sys_futimesat,int,dirfd,const char *,pathname,
        !           220:          const struct timeval *,times)
        !           221: #endif
1.1       root      222: _syscall2(int,sys_getcwd1,char *,buf,size_t,size)
1.1.1.7 ! root      223: #if TARGET_ABI_BITS == 32
        !           224: _syscall3(int, sys_getdents, uint, fd, struct linux_dirent *, dirp, uint, count);
        !           225: #endif
1.1.1.6   root      226: #if defined(TARGET_NR_getdents64) && defined(__NR_getdents64)
1.1.1.7 ! root      227: _syscall3(int, sys_getdents64, uint, fd, struct linux_dirent64 *, dirp, uint, count);
1.1.1.6   root      228: #endif
                    229: _syscall2(int, sys_getpriority, int, which, int, who);
1.1.1.7 ! root      230: #if !defined (__x86_64__)
1.1       root      231: _syscall5(int, _llseek,  uint,  fd, ulong, hi, ulong, lo,
                    232:           loff_t *, res, uint, wh);
1.1.1.7 ! root      233: #endif
1.1.1.6   root      234: #if defined(TARGET_NR_linkat) && defined(__NR_linkat)
                    235: _syscall5(int,sys_linkat,int,olddirfd,const char *,oldpath,
                    236:          int,newdirfd,const char *,newpath,int,flags)
                    237: #endif
                    238: #if defined(TARGET_NR_mkdirat) && defined(__NR_mkdirat)
                    239: _syscall3(int,sys_mkdirat,int,dirfd,const char *,pathname,mode_t,mode)
                    240: #endif
                    241: #if defined(TARGET_NR_mknodat) && defined(__NR_mknodat)
                    242: _syscall4(int,sys_mknodat,int,dirfd,const char *,pathname,
                    243:           mode_t,mode,dev_t,dev)
                    244: #endif
                    245: #if defined(TARGET_NR_openat) && defined(__NR_openat)
                    246: _syscall4(int,sys_openat,int,dirfd,const char *,pathname,int,flags,mode_t,mode)
                    247: #endif
                    248: #if defined(TARGET_NR_readlinkat) && defined(__NR_readlinkat)
                    249: _syscall4(int,sys_readlinkat,int,dirfd,const char *,pathname,
                    250:           char *,buf,size_t,bufsize)
                    251: #endif
                    252: #if defined(TARGET_NR_renameat) && defined(__NR_renameat)
                    253: _syscall4(int,sys_renameat,int,olddirfd,const char *,oldpath,
                    254:           int,newdirfd,const char *,newpath)
                    255: #endif
1.1       root      256: _syscall3(int,sys_rt_sigqueueinfo,int,pid,int,sig,siginfo_t *,uinfo)
1.1.1.6   root      257: #if defined(TARGET_NR_symlinkat) && defined(__NR_symlinkat)
                    258: _syscall3(int,sys_symlinkat,const char *,oldpath,
                    259:           int,newdirfd,const char *,newpath)
                    260: #endif
                    261: _syscall3(int,sys_syslog,int,type,char*,bufp,int,len)
                    262: #if defined(TARGET_NR_tgkill) && defined(__NR_tgkill)
                    263: _syscall3(int,sys_tgkill,int,tgid,int,pid,int,sig)
                    264: #endif
                    265: #if defined(TARGET_NR_tkill) && defined(__NR_tkill)
                    266: _syscall2(int,sys_tkill,int,tid,int,sig)
                    267: #endif
1.1       root      268: #ifdef __NR_exit_group
                    269: _syscall1(int,exit_group,int,error_code)
                    270: #endif
1.1.1.6   root      271: #if defined(TARGET_NR_set_tid_address) && defined(__NR_set_tid_address)
                    272: _syscall1(int,set_tid_address,int *,tidptr)
                    273: #endif
                    274: #if defined(TARGET_NR_unlinkat) && defined(__NR_unlinkat)
                    275: _syscall3(int,sys_unlinkat,int,dirfd,const char *,pathname,int,flags)
                    276: #endif
                    277: #if defined(TARGET_NR_utimensat) && defined(__NR_utimensat)
                    278: _syscall4(int,sys_utimensat,int,dirfd,const char *,pathname,
                    279:           const struct timespec *,tsp,int,flags)
                    280: #endif
1.1.1.7 ! root      281: #if defined(TARGET_NR_inotify_init) && defined(__NR_inotify_init)
        !           282: _syscall0(int,sys_inotify_init)
        !           283: #endif
        !           284: #if defined(TARGET_NR_inotify_add_watch) && defined(__NR_inotify_add_watch)
        !           285: _syscall3(int,sys_inotify_add_watch,int,fd,const char *,pathname,uint32_t,mask)
        !           286: #endif
        !           287: #if defined(TARGET_NR_inotify_rm_watch) && defined(__NR_inotify_rm_watch)
        !           288: _syscall2(int,sys_inotify_rm_watch,int,fd,uint32_t,wd)
        !           289: #endif
        !           290: #if defined(USE_NPTL)
        !           291: #if defined(TARGET_NR_futex) && defined(__NR_futex)
        !           292: _syscall6(int,sys_futex,int *,uaddr,int,op,int,val,
        !           293:           const struct timespec *,timeout,int *,uaddr2,int,val3)
        !           294: #endif
        !           295: #endif
1.1       root      296: 
                    297: extern int personality(int);
                    298: extern int flock(int, int);
                    299: extern int setfsuid(int);
                    300: extern int setfsgid(int);
                    301: extern int setgroups(int, gid_t *);
                    302: 
1.1.1.6   root      303: #define ERRNO_TABLE_SIZE 1200
                    304: 
                    305: /* target_to_host_errno_table[] is initialized from
                    306:  * host_to_target_errno_table[] in syscall_init(). */
                    307: static uint16_t target_to_host_errno_table[ERRNO_TABLE_SIZE] = {
                    308: };
                    309: 
                    310: /*
                    311:  * This list is the union of errno values overridden in asm-<arch>/errno.h
                    312:  * minus the errnos that are not actually generic to all archs.
                    313:  */
                    314: static uint16_t host_to_target_errno_table[ERRNO_TABLE_SIZE] = {
                    315:     [EIDRM]            = TARGET_EIDRM,
                    316:     [ECHRNG]           = TARGET_ECHRNG,
                    317:     [EL2NSYNC]         = TARGET_EL2NSYNC,
                    318:     [EL3HLT]           = TARGET_EL3HLT,
                    319:     [EL3RST]           = TARGET_EL3RST,
                    320:     [ELNRNG]           = TARGET_ELNRNG,
                    321:     [EUNATCH]          = TARGET_EUNATCH,
                    322:     [ENOCSI]           = TARGET_ENOCSI,
                    323:     [EL2HLT]           = TARGET_EL2HLT,
                    324:     [EDEADLK]          = TARGET_EDEADLK,
                    325:     [ENOLCK]           = TARGET_ENOLCK,
                    326:     [EBADE]            = TARGET_EBADE,
                    327:     [EBADR]            = TARGET_EBADR,
                    328:     [EXFULL]           = TARGET_EXFULL,
                    329:     [ENOANO]           = TARGET_ENOANO,
                    330:     [EBADRQC]          = TARGET_EBADRQC,
                    331:     [EBADSLT]          = TARGET_EBADSLT,
                    332:     [EBFONT]           = TARGET_EBFONT,
                    333:     [ENOSTR]           = TARGET_ENOSTR,
                    334:     [ENODATA]          = TARGET_ENODATA,
                    335:     [ETIME]            = TARGET_ETIME,
                    336:     [ENOSR]            = TARGET_ENOSR,
                    337:     [ENONET]           = TARGET_ENONET,
                    338:     [ENOPKG]           = TARGET_ENOPKG,
                    339:     [EREMOTE]          = TARGET_EREMOTE,
                    340:     [ENOLINK]          = TARGET_ENOLINK,
                    341:     [EADV]             = TARGET_EADV,
                    342:     [ESRMNT]           = TARGET_ESRMNT,
                    343:     [ECOMM]            = TARGET_ECOMM,
                    344:     [EPROTO]           = TARGET_EPROTO,
                    345:     [EDOTDOT]          = TARGET_EDOTDOT,
                    346:     [EMULTIHOP]                = TARGET_EMULTIHOP,
                    347:     [EBADMSG]          = TARGET_EBADMSG,
                    348:     [ENAMETOOLONG]     = TARGET_ENAMETOOLONG,
                    349:     [EOVERFLOW]                = TARGET_EOVERFLOW,
                    350:     [ENOTUNIQ]         = TARGET_ENOTUNIQ,
                    351:     [EBADFD]           = TARGET_EBADFD,
                    352:     [EREMCHG]          = TARGET_EREMCHG,
                    353:     [ELIBACC]          = TARGET_ELIBACC,
                    354:     [ELIBBAD]          = TARGET_ELIBBAD,
                    355:     [ELIBSCN]          = TARGET_ELIBSCN,
                    356:     [ELIBMAX]          = TARGET_ELIBMAX,
                    357:     [ELIBEXEC]         = TARGET_ELIBEXEC,
                    358:     [EILSEQ]           = TARGET_EILSEQ,
                    359:     [ENOSYS]           = TARGET_ENOSYS,
                    360:     [ELOOP]            = TARGET_ELOOP,
                    361:     [ERESTART]         = TARGET_ERESTART,
                    362:     [ESTRPIPE]         = TARGET_ESTRPIPE,
                    363:     [ENOTEMPTY]                = TARGET_ENOTEMPTY,
                    364:     [EUSERS]           = TARGET_EUSERS,
                    365:     [ENOTSOCK]         = TARGET_ENOTSOCK,
                    366:     [EDESTADDRREQ]     = TARGET_EDESTADDRREQ,
                    367:     [EMSGSIZE]         = TARGET_EMSGSIZE,
                    368:     [EPROTOTYPE]       = TARGET_EPROTOTYPE,
                    369:     [ENOPROTOOPT]      = TARGET_ENOPROTOOPT,
                    370:     [EPROTONOSUPPORT]  = TARGET_EPROTONOSUPPORT,
                    371:     [ESOCKTNOSUPPORT]  = TARGET_ESOCKTNOSUPPORT,
                    372:     [EOPNOTSUPP]       = TARGET_EOPNOTSUPP,
                    373:     [EPFNOSUPPORT]     = TARGET_EPFNOSUPPORT,
                    374:     [EAFNOSUPPORT]     = TARGET_EAFNOSUPPORT,
                    375:     [EADDRINUSE]       = TARGET_EADDRINUSE,
                    376:     [EADDRNOTAVAIL]    = TARGET_EADDRNOTAVAIL,
                    377:     [ENETDOWN]         = TARGET_ENETDOWN,
                    378:     [ENETUNREACH]      = TARGET_ENETUNREACH,
                    379:     [ENETRESET]                = TARGET_ENETRESET,
                    380:     [ECONNABORTED]     = TARGET_ECONNABORTED,
                    381:     [ECONNRESET]       = TARGET_ECONNRESET,
                    382:     [ENOBUFS]          = TARGET_ENOBUFS,
                    383:     [EISCONN]          = TARGET_EISCONN,
                    384:     [ENOTCONN]         = TARGET_ENOTCONN,
                    385:     [EUCLEAN]          = TARGET_EUCLEAN,
                    386:     [ENOTNAM]          = TARGET_ENOTNAM,
                    387:     [ENAVAIL]          = TARGET_ENAVAIL,
                    388:     [EISNAM]           = TARGET_EISNAM,
                    389:     [EREMOTEIO]                = TARGET_EREMOTEIO,
                    390:     [ESHUTDOWN]                = TARGET_ESHUTDOWN,
                    391:     [ETOOMANYREFS]     = TARGET_ETOOMANYREFS,
                    392:     [ETIMEDOUT]                = TARGET_ETIMEDOUT,
                    393:     [ECONNREFUSED]     = TARGET_ECONNREFUSED,
                    394:     [EHOSTDOWN]                = TARGET_EHOSTDOWN,
                    395:     [EHOSTUNREACH]     = TARGET_EHOSTUNREACH,
                    396:     [EALREADY]         = TARGET_EALREADY,
                    397:     [EINPROGRESS]      = TARGET_EINPROGRESS,
                    398:     [ESTALE]           = TARGET_ESTALE,
                    399:     [ECANCELED]                = TARGET_ECANCELED,
                    400:     [ENOMEDIUM]                = TARGET_ENOMEDIUM,
                    401:     [EMEDIUMTYPE]      = TARGET_EMEDIUMTYPE,
                    402: #ifdef ENOKEY
                    403:     [ENOKEY]           = TARGET_ENOKEY,
                    404: #endif
                    405: #ifdef EKEYEXPIRED
                    406:     [EKEYEXPIRED]      = TARGET_EKEYEXPIRED,
                    407: #endif
                    408: #ifdef EKEYREVOKED
                    409:     [EKEYREVOKED]      = TARGET_EKEYREVOKED,
                    410: #endif
                    411: #ifdef EKEYREJECTED
                    412:     [EKEYREJECTED]     = TARGET_EKEYREJECTED,
                    413: #endif
                    414: #ifdef EOWNERDEAD
                    415:     [EOWNERDEAD]       = TARGET_EOWNERDEAD,
                    416: #endif
                    417: #ifdef ENOTRECOVERABLE
                    418:     [ENOTRECOVERABLE]  = TARGET_ENOTRECOVERABLE,
                    419: #endif
                    420: };
                    421: 
                    422: static inline int host_to_target_errno(int err)
                    423: {
                    424:     if(host_to_target_errno_table[err])
                    425:         return host_to_target_errno_table[err];
                    426:     return err;
                    427: }
                    428: 
                    429: static inline int target_to_host_errno(int err)
                    430: {
                    431:     if (target_to_host_errno_table[err])
                    432:         return target_to_host_errno_table[err];
                    433:     return err;
                    434: }
                    435: 
                    436: static inline abi_long get_errno(abi_long ret)
1.1       root      437: {
                    438:     if (ret == -1)
1.1.1.6   root      439:         return -host_to_target_errno(errno);
1.1       root      440:     else
                    441:         return ret;
                    442: }
                    443: 
1.1.1.6   root      444: static inline int is_error(abi_long ret)
                    445: {
                    446:     return (abi_ulong)ret >= (abi_ulong)(-4096);
                    447: }
                    448: 
                    449: char *target_strerror(int err)
1.1       root      450: {
1.1.1.6   root      451:     return strerror(target_to_host_errno(err));
1.1       root      452: }
                    453: 
1.1.1.6   root      454: static abi_ulong target_brk;
                    455: static abi_ulong target_original_brk;
1.1       root      456: 
1.1.1.6   root      457: void target_set_brk(abi_ulong new_brk)
1.1       root      458: {
1.1.1.6   root      459:     target_original_brk = target_brk = HOST_PAGE_ALIGN(new_brk);
1.1       root      460: }
                    461: 
1.1.1.6   root      462: /* do_brk() must return target values and target errnos. */
                    463: abi_long do_brk(abi_ulong new_brk)
1.1       root      464: {
1.1.1.6   root      465:     abi_ulong brk_page;
                    466:     abi_long mapped_addr;
1.1       root      467:     int        new_alloc_size;
                    468: 
                    469:     if (!new_brk)
1.1.1.3   root      470:         return target_brk;
1.1       root      471:     if (new_brk < target_original_brk)
1.1.1.7 ! root      472:         return target_brk;
1.1.1.6   root      473: 
1.1.1.3   root      474:     brk_page = HOST_PAGE_ALIGN(target_brk);
1.1       root      475: 
                    476:     /* If the new brk is less than this, set it and we're done... */
                    477:     if (new_brk < brk_page) {
                    478:        target_brk = new_brk;
1.1.1.3   root      479:        return target_brk;
1.1       root      480:     }
                    481: 
                    482:     /* We need to allocate more memory after the brk... */
                    483:     new_alloc_size = HOST_PAGE_ALIGN(new_brk - brk_page + 1);
1.1.1.6   root      484:     mapped_addr = get_errno(target_mmap(brk_page, new_alloc_size,
1.1       root      485:                                         PROT_READ|PROT_WRITE,
                    486:                                         MAP_ANON|MAP_FIXED|MAP_PRIVATE, 0, 0));
1.1.1.7 ! root      487: 
        !           488:     if (!is_error(mapped_addr))
1.1       root      489:        target_brk = new_brk;
1.1.1.7 ! root      490:     
        !           491:     return target_brk;
1.1       root      492: }
                    493: 
1.1.1.6   root      494: static inline abi_long copy_from_user_fdset(fd_set *fds,
                    495:                                             abi_ulong target_fds_addr,
                    496:                                             int n)
1.1       root      497: {
1.1.1.6   root      498:     int i, nw, j, k;
                    499:     abi_ulong b, *target_fds;
                    500: 
                    501:     nw = (n + TARGET_ABI_BITS - 1) / TARGET_ABI_BITS;
                    502:     if (!(target_fds = lock_user(VERIFY_READ,
                    503:                                  target_fds_addr,
                    504:                                  sizeof(abi_ulong) * nw,
                    505:                                  1)))
                    506:         return -TARGET_EFAULT;
                    507: 
                    508:     FD_ZERO(fds);
                    509:     k = 0;
                    510:     for (i = 0; i < nw; i++) {
                    511:         /* grab the abi_ulong */
                    512:         __get_user(b, &target_fds[i]);
                    513:         for (j = 0; j < TARGET_ABI_BITS; j++) {
                    514:             /* check the bit inside the abi_ulong */
                    515:             if ((b >> j) & 1)
                    516:                 FD_SET(k, fds);
                    517:             k++;
1.1       root      518:         }
                    519:     }
1.1.1.6   root      520: 
                    521:     unlock_user(target_fds, target_fds_addr, 0);
                    522: 
                    523:     return 0;
1.1       root      524: }
                    525: 
1.1.1.6   root      526: static inline abi_long copy_to_user_fdset(abi_ulong target_fds_addr,
                    527:                                           const fd_set *fds,
                    528:                                           int n)
1.1       root      529: {
                    530:     int i, nw, j, k;
1.1.1.6   root      531:     abi_long v;
                    532:     abi_ulong *target_fds;
1.1       root      533: 
1.1.1.6   root      534:     nw = (n + TARGET_ABI_BITS - 1) / TARGET_ABI_BITS;
                    535:     if (!(target_fds = lock_user(VERIFY_WRITE,
                    536:                                  target_fds_addr,
                    537:                                  sizeof(abi_ulong) * nw,
                    538:                                  0)))
                    539:         return -TARGET_EFAULT;
                    540: 
                    541:     k = 0;
                    542:     for (i = 0; i < nw; i++) {
                    543:         v = 0;
                    544:         for (j = 0; j < TARGET_ABI_BITS; j++) {
                    545:             v |= ((FD_ISSET(k, fds) != 0) << j);
                    546:             k++;
1.1       root      547:         }
1.1.1.6   root      548:         __put_user(v, &target_fds[i]);
1.1       root      549:     }
1.1.1.6   root      550: 
                    551:     unlock_user(target_fds, target_fds_addr, sizeof(abi_ulong) * nw);
                    552: 
                    553:     return 0;
1.1       root      554: }
                    555: 
                    556: #if defined(__alpha__)
                    557: #define HOST_HZ 1024
                    558: #else
                    559: #define HOST_HZ 100
                    560: #endif
                    561: 
1.1.1.6   root      562: static inline abi_long host_to_target_clock_t(long ticks)
1.1       root      563: {
                    564: #if HOST_HZ == TARGET_HZ
                    565:     return ticks;
                    566: #else
                    567:     return ((int64_t)ticks * TARGET_HZ) / HOST_HZ;
                    568: #endif
                    569: }
                    570: 
1.1.1.6   root      571: static inline abi_long host_to_target_rusage(abi_ulong target_addr,
                    572:                                              const struct rusage *rusage)
1.1       root      573: {
1.1.1.3   root      574:     struct target_rusage *target_rusage;
                    575: 
1.1.1.6   root      576:     if (!lock_user_struct(VERIFY_WRITE, target_rusage, target_addr, 0))
                    577:         return -TARGET_EFAULT;
1.1       root      578:     target_rusage->ru_utime.tv_sec = tswapl(rusage->ru_utime.tv_sec);
                    579:     target_rusage->ru_utime.tv_usec = tswapl(rusage->ru_utime.tv_usec);
                    580:     target_rusage->ru_stime.tv_sec = tswapl(rusage->ru_stime.tv_sec);
                    581:     target_rusage->ru_stime.tv_usec = tswapl(rusage->ru_stime.tv_usec);
                    582:     target_rusage->ru_maxrss = tswapl(rusage->ru_maxrss);
                    583:     target_rusage->ru_ixrss = tswapl(rusage->ru_ixrss);
                    584:     target_rusage->ru_idrss = tswapl(rusage->ru_idrss);
                    585:     target_rusage->ru_isrss = tswapl(rusage->ru_isrss);
                    586:     target_rusage->ru_minflt = tswapl(rusage->ru_minflt);
                    587:     target_rusage->ru_majflt = tswapl(rusage->ru_majflt);
                    588:     target_rusage->ru_nswap = tswapl(rusage->ru_nswap);
                    589:     target_rusage->ru_inblock = tswapl(rusage->ru_inblock);
                    590:     target_rusage->ru_oublock = tswapl(rusage->ru_oublock);
                    591:     target_rusage->ru_msgsnd = tswapl(rusage->ru_msgsnd);
                    592:     target_rusage->ru_msgrcv = tswapl(rusage->ru_msgrcv);
                    593:     target_rusage->ru_nsignals = tswapl(rusage->ru_nsignals);
                    594:     target_rusage->ru_nvcsw = tswapl(rusage->ru_nvcsw);
                    595:     target_rusage->ru_nivcsw = tswapl(rusage->ru_nivcsw);
1.1.1.3   root      596:     unlock_user_struct(target_rusage, target_addr, 1);
1.1.1.6   root      597: 
                    598:     return 0;
1.1       root      599: }
                    600: 
1.1.1.6   root      601: static inline abi_long copy_from_user_timeval(struct timeval *tv,
                    602:                                               abi_ulong target_tv_addr)
1.1       root      603: {
1.1.1.3   root      604:     struct target_timeval *target_tv;
                    605: 
1.1.1.6   root      606:     if (!lock_user_struct(VERIFY_READ, target_tv, target_tv_addr, 1))
                    607:         return -TARGET_EFAULT;
                    608: 
                    609:     __get_user(tv->tv_sec, &target_tv->tv_sec);
                    610:     __get_user(tv->tv_usec, &target_tv->tv_usec);
                    611: 
                    612:     unlock_user_struct(target_tv, target_tv_addr, 0);
                    613: 
                    614:     return 0;
1.1       root      615: }
                    616: 
1.1.1.6   root      617: static inline abi_long copy_to_user_timeval(abi_ulong target_tv_addr,
                    618:                                             const struct timeval *tv)
1.1       root      619: {
1.1.1.3   root      620:     struct target_timeval *target_tv;
                    621: 
1.1.1.6   root      622:     if (!lock_user_struct(VERIFY_WRITE, target_tv, target_tv_addr, 0))
                    623:         return -TARGET_EFAULT;
                    624: 
                    625:     __put_user(tv->tv_sec, &target_tv->tv_sec);
                    626:     __put_user(tv->tv_usec, &target_tv->tv_usec);
                    627: 
                    628:     unlock_user_struct(target_tv, target_tv_addr, 1);
                    629: 
                    630:     return 0;
1.1       root      631: }
                    632: 
                    633: 
1.1.1.6   root      634: /* do_select() must return target values and target errnos. */
                    635: static abi_long do_select(int n,
                    636:                           abi_ulong rfd_addr, abi_ulong wfd_addr,
                    637:                           abi_ulong efd_addr, abi_ulong target_tv_addr)
1.1       root      638: {
                    639:     fd_set rfds, wfds, efds;
                    640:     fd_set *rfds_ptr, *wfds_ptr, *efds_ptr;
                    641:     struct timeval tv, *tv_ptr;
1.1.1.6   root      642:     abi_long ret;
1.1       root      643: 
1.1.1.6   root      644:     if (rfd_addr) {
                    645:         if (copy_from_user_fdset(&rfds, rfd_addr, n))
                    646:             return -TARGET_EFAULT;
                    647:         rfds_ptr = &rfds;
1.1.1.3   root      648:     } else {
                    649:         rfds_ptr = NULL;
                    650:     }
1.1.1.6   root      651:     if (wfd_addr) {
                    652:         if (copy_from_user_fdset(&wfds, wfd_addr, n))
                    653:             return -TARGET_EFAULT;
                    654:         wfds_ptr = &wfds;
1.1.1.3   root      655:     } else {
                    656:         wfds_ptr = NULL;
                    657:     }
1.1.1.6   root      658:     if (efd_addr) {
                    659:         if (copy_from_user_fdset(&efds, efd_addr, n))
                    660:             return -TARGET_EFAULT;
                    661:         efds_ptr = &efds;
1.1.1.3   root      662:     } else {
                    663:         efds_ptr = NULL;
                    664:     }
1.1.1.6   root      665: 
                    666:     if (target_tv_addr) {
                    667:         if (copy_from_user_timeval(&tv, target_tv_addr))
                    668:             return -TARGET_EFAULT;
1.1       root      669:         tv_ptr = &tv;
                    670:     } else {
                    671:         tv_ptr = NULL;
                    672:     }
1.1.1.6   root      673: 
1.1       root      674:     ret = get_errno(select(n, rfds_ptr, wfds_ptr, efds_ptr, tv_ptr));
1.1.1.3   root      675: 
1.1.1.6   root      676:     if (!is_error(ret)) {
                    677:         if (rfd_addr && copy_to_user_fdset(rfd_addr, &rfds, n))
                    678:             return -TARGET_EFAULT;
                    679:         if (wfd_addr && copy_to_user_fdset(wfd_addr, &wfds, n))
                    680:             return -TARGET_EFAULT;
                    681:         if (efd_addr && copy_to_user_fdset(efd_addr, &efds, n))
                    682:             return -TARGET_EFAULT;
1.1       root      683: 
1.1.1.6   root      684:         if (target_tv_addr && copy_to_user_timeval(target_tv_addr, &tv))
                    685:             return -TARGET_EFAULT;
1.1       root      686:     }
1.1.1.3   root      687: 
1.1       root      688:     return ret;
                    689: }
                    690: 
1.1.1.6   root      691: static inline abi_long target_to_host_sockaddr(struct sockaddr *addr,
                    692:                                                abi_ulong target_addr,
                    693:                                                socklen_t len)
1.1       root      694: {
1.1.1.3   root      695:     struct target_sockaddr *target_saddr;
                    696: 
1.1.1.6   root      697:     target_saddr = lock_user(VERIFY_READ, target_addr, len, 1);
                    698:     if (!target_saddr)
                    699:         return -TARGET_EFAULT;
1.1.1.3   root      700:     memcpy(addr, target_saddr, len);
                    701:     addr->sa_family = tswap16(target_saddr->sa_family);
                    702:     unlock_user(target_saddr, target_addr, 0);
1.1.1.6   root      703: 
                    704:     return 0;
1.1       root      705: }
                    706: 
1.1.1.6   root      707: static inline abi_long host_to_target_sockaddr(abi_ulong target_addr,
                    708:                                                struct sockaddr *addr,
                    709:                                                socklen_t len)
1.1       root      710: {
1.1.1.3   root      711:     struct target_sockaddr *target_saddr;
                    712: 
1.1.1.6   root      713:     target_saddr = lock_user(VERIFY_WRITE, target_addr, len, 0);
                    714:     if (!target_saddr)
                    715:         return -TARGET_EFAULT;
1.1.1.3   root      716:     memcpy(target_saddr, addr, len);
                    717:     target_saddr->sa_family = tswap16(addr->sa_family);
                    718:     unlock_user(target_saddr, target_addr, len);
1.1.1.6   root      719: 
                    720:     return 0;
1.1       root      721: }
                    722: 
1.1.1.3   root      723: /* ??? Should this also swap msgh->name?  */
1.1.1.6   root      724: static inline abi_long target_to_host_cmsg(struct msghdr *msgh,
                    725:                                            struct target_msghdr *target_msgh)
1.1       root      726: {
                    727:     struct cmsghdr *cmsg = CMSG_FIRSTHDR(msgh);
1.1.1.6   root      728:     abi_long msg_controllen;
                    729:     abi_ulong target_cmsg_addr;
                    730:     struct target_cmsghdr *target_cmsg;
1.1       root      731:     socklen_t space = 0;
1.1.1.6   root      732:     
                    733:     msg_controllen = tswapl(target_msgh->msg_controllen);
                    734:     if (msg_controllen < sizeof (struct target_cmsghdr)) 
                    735:         goto the_end;
                    736:     target_cmsg_addr = tswapl(target_msgh->msg_control);
                    737:     target_cmsg = lock_user(VERIFY_READ, target_cmsg_addr, msg_controllen, 1);
                    738:     if (!target_cmsg)
                    739:         return -TARGET_EFAULT;
1.1       root      740: 
                    741:     while (cmsg && target_cmsg) {
                    742:         void *data = CMSG_DATA(cmsg);
                    743:         void *target_data = TARGET_CMSG_DATA(target_cmsg);
                    744: 
1.1.1.6   root      745:         int len = tswapl(target_cmsg->cmsg_len)
1.1       root      746:                   - TARGET_CMSG_ALIGN(sizeof (struct target_cmsghdr));
                    747: 
                    748:         space += CMSG_SPACE(len);
                    749:         if (space > msgh->msg_controllen) {
                    750:             space -= CMSG_SPACE(len);
1.1.1.2   root      751:             gemu_log("Host cmsg overflow\n");
1.1       root      752:             break;
                    753:         }
                    754: 
                    755:         cmsg->cmsg_level = tswap32(target_cmsg->cmsg_level);
                    756:         cmsg->cmsg_type = tswap32(target_cmsg->cmsg_type);
                    757:         cmsg->cmsg_len = CMSG_LEN(len);
                    758: 
1.1.1.4   root      759:         if (cmsg->cmsg_level != TARGET_SOL_SOCKET || cmsg->cmsg_type != SCM_RIGHTS) {
1.1       root      760:             gemu_log("Unsupported ancillary data: %d/%d\n", cmsg->cmsg_level, cmsg->cmsg_type);
                    761:             memcpy(data, target_data, len);
                    762:         } else {
                    763:             int *fd = (int *)data;
                    764:             int *target_fd = (int *)target_data;
                    765:             int i, numfds = len / sizeof(int);
                    766: 
                    767:             for (i = 0; i < numfds; i++)
                    768:                 fd[i] = tswap32(target_fd[i]);
                    769:         }
                    770: 
                    771:         cmsg = CMSG_NXTHDR(msgh, cmsg);
                    772:         target_cmsg = TARGET_CMSG_NXTHDR(target_msgh, target_cmsg);
                    773:     }
1.1.1.6   root      774:     unlock_user(target_cmsg, target_cmsg_addr, 0);
                    775:  the_end:
1.1       root      776:     msgh->msg_controllen = space;
1.1.1.6   root      777:     return 0;
1.1       root      778: }
                    779: 
1.1.1.3   root      780: /* ??? Should this also swap msgh->name?  */
1.1.1.6   root      781: static inline abi_long host_to_target_cmsg(struct target_msghdr *target_msgh,
                    782:                                            struct msghdr *msgh)
1.1       root      783: {
                    784:     struct cmsghdr *cmsg = CMSG_FIRSTHDR(msgh);
1.1.1.6   root      785:     abi_long msg_controllen;
                    786:     abi_ulong target_cmsg_addr;
                    787:     struct target_cmsghdr *target_cmsg;
1.1       root      788:     socklen_t space = 0;
                    789: 
1.1.1.6   root      790:     msg_controllen = tswapl(target_msgh->msg_controllen);
                    791:     if (msg_controllen < sizeof (struct target_cmsghdr)) 
                    792:         goto the_end;
                    793:     target_cmsg_addr = tswapl(target_msgh->msg_control);
                    794:     target_cmsg = lock_user(VERIFY_WRITE, target_cmsg_addr, msg_controllen, 0);
                    795:     if (!target_cmsg)
                    796:         return -TARGET_EFAULT;
                    797: 
1.1       root      798:     while (cmsg && target_cmsg) {
                    799:         void *data = CMSG_DATA(cmsg);
                    800:         void *target_data = TARGET_CMSG_DATA(target_cmsg);
                    801: 
                    802:         int len = cmsg->cmsg_len - CMSG_ALIGN(sizeof (struct cmsghdr));
                    803: 
                    804:         space += TARGET_CMSG_SPACE(len);
1.1.1.6   root      805:         if (space > msg_controllen) {
1.1       root      806:             space -= TARGET_CMSG_SPACE(len);
1.1.1.2   root      807:             gemu_log("Target cmsg overflow\n");
1.1       root      808:             break;
                    809:         }
                    810: 
                    811:         target_cmsg->cmsg_level = tswap32(cmsg->cmsg_level);
                    812:         target_cmsg->cmsg_type = tswap32(cmsg->cmsg_type);
                    813:         target_cmsg->cmsg_len = tswapl(TARGET_CMSG_LEN(len));
                    814: 
1.1.1.4   root      815:         if (cmsg->cmsg_level != TARGET_SOL_SOCKET || cmsg->cmsg_type != SCM_RIGHTS) {
1.1       root      816:             gemu_log("Unsupported ancillary data: %d/%d\n", cmsg->cmsg_level, cmsg->cmsg_type);
                    817:             memcpy(target_data, data, len);
                    818:         } else {
                    819:             int *fd = (int *)data;
                    820:             int *target_fd = (int *)target_data;
                    821:             int i, numfds = len / sizeof(int);
                    822: 
                    823:             for (i = 0; i < numfds; i++)
                    824:                 target_fd[i] = tswap32(fd[i]);
                    825:         }
                    826: 
                    827:         cmsg = CMSG_NXTHDR(msgh, cmsg);
                    828:         target_cmsg = TARGET_CMSG_NXTHDR(target_msgh, target_cmsg);
                    829:     }
1.1.1.6   root      830:     unlock_user(target_cmsg, target_cmsg_addr, space);
                    831:  the_end:
                    832:     target_msgh->msg_controllen = tswapl(space);
                    833:     return 0;
1.1       root      834: }
                    835: 
1.1.1.6   root      836: /* do_setsockopt() Must return target values and target errnos. */
                    837: static abi_long do_setsockopt(int sockfd, int level, int optname,
                    838:                               abi_ulong optval_addr, socklen_t optlen)
1.1       root      839: {
1.1.1.6   root      840:     abi_long ret;
                    841:     int val;
                    842: 
1.1       root      843:     switch(level) {
                    844:     case SOL_TCP:
                    845:         /* TCP options all take an 'int' value.  */
                    846:         if (optlen < sizeof(uint32_t))
1.1.1.6   root      847:             return -TARGET_EINVAL;
                    848: 
                    849:         if (get_user_u32(val, optval_addr))
                    850:             return -TARGET_EFAULT;
1.1       root      851:         ret = get_errno(setsockopt(sockfd, level, optname, &val, sizeof(val)));
                    852:         break;
                    853:     case SOL_IP:
                    854:         switch(optname) {
                    855:         case IP_TOS:
                    856:         case IP_TTL:
                    857:         case IP_HDRINCL:
                    858:         case IP_ROUTER_ALERT:
                    859:         case IP_RECVOPTS:
                    860:         case IP_RETOPTS:
                    861:         case IP_PKTINFO:
                    862:         case IP_MTU_DISCOVER:
                    863:         case IP_RECVERR:
                    864:         case IP_RECVTOS:
                    865: #ifdef IP_FREEBIND
                    866:         case IP_FREEBIND:
                    867: #endif
                    868:         case IP_MULTICAST_TTL:
                    869:         case IP_MULTICAST_LOOP:
                    870:             val = 0;
                    871:             if (optlen >= sizeof(uint32_t)) {
1.1.1.6   root      872:                 if (get_user_u32(val, optval_addr))
                    873:                     return -TARGET_EFAULT;
1.1       root      874:             } else if (optlen >= 1) {
1.1.1.6   root      875:                 if (get_user_u8(val, optval_addr))
                    876:                     return -TARGET_EFAULT;
1.1       root      877:             }
                    878:             ret = get_errno(setsockopt(sockfd, level, optname, &val, sizeof(val)));
                    879:             break;
                    880:         default:
                    881:             goto unimplemented;
                    882:         }
                    883:         break;
1.1.1.4   root      884:     case TARGET_SOL_SOCKET:
1.1       root      885:         switch (optname) {
                    886:             /* Options with 'int' argument.  */
1.1.1.4   root      887:         case TARGET_SO_DEBUG:
                    888:                optname = SO_DEBUG;
                    889:                break;
                    890:         case TARGET_SO_REUSEADDR:
                    891:                optname = SO_REUSEADDR;
                    892:                break;
                    893:         case TARGET_SO_TYPE:
                    894:                optname = SO_TYPE;
                    895:                break;
                    896:         case TARGET_SO_ERROR:
                    897:                optname = SO_ERROR;
                    898:                break;
                    899:         case TARGET_SO_DONTROUTE:
                    900:                optname = SO_DONTROUTE;
                    901:                break;
                    902:         case TARGET_SO_BROADCAST:
                    903:                optname = SO_BROADCAST;
                    904:                break;
                    905:         case TARGET_SO_SNDBUF:
                    906:                optname = SO_SNDBUF;
                    907:                break;
                    908:         case TARGET_SO_RCVBUF:
                    909:                optname = SO_RCVBUF;
                    910:                break;
                    911:         case TARGET_SO_KEEPALIVE:
                    912:                optname = SO_KEEPALIVE;
                    913:                break;
                    914:         case TARGET_SO_OOBINLINE:
                    915:                optname = SO_OOBINLINE;
                    916:                break;
                    917:         case TARGET_SO_NO_CHECK:
                    918:                optname = SO_NO_CHECK;
                    919:                break;
                    920:         case TARGET_SO_PRIORITY:
                    921:                optname = SO_PRIORITY;
                    922:                break;
1.1       root      923: #ifdef SO_BSDCOMPAT
1.1.1.4   root      924:         case TARGET_SO_BSDCOMPAT:
                    925:                optname = SO_BSDCOMPAT;
                    926:                break;
1.1       root      927: #endif
1.1.1.4   root      928:         case TARGET_SO_PASSCRED:
                    929:                optname = SO_PASSCRED;
                    930:                break;
                    931:         case TARGET_SO_TIMESTAMP:
                    932:                optname = SO_TIMESTAMP;
                    933:                break;
                    934:         case TARGET_SO_RCVLOWAT:
                    935:                optname = SO_RCVLOWAT;
                    936:                break;
                    937:         case TARGET_SO_RCVTIMEO:
                    938:                optname = SO_RCVTIMEO;
                    939:                break;
                    940:         case TARGET_SO_SNDTIMEO:
                    941:                optname = SO_SNDTIMEO;
                    942:                break;
1.1       root      943:             break;
                    944:         default:
                    945:             goto unimplemented;
                    946:         }
1.1.1.4   root      947:        if (optlen < sizeof(uint32_t))
1.1.1.6   root      948:             return -TARGET_EINVAL;
1.1.1.4   root      949: 
1.1.1.6   root      950:        if (get_user_u32(val, optval_addr))
                    951:             return -TARGET_EFAULT;
1.1.1.4   root      952:        ret = get_errno(setsockopt(sockfd, SOL_SOCKET, optname, &val, sizeof(val)));
1.1       root      953:         break;
                    954:     default:
                    955:     unimplemented:
                    956:         gemu_log("Unsupported setsockopt level=%d optname=%d \n", level, optname);
1.1.1.6   root      957:         ret = -TARGET_ENOPROTOOPT;
1.1       root      958:     }
                    959:     return ret;
                    960: }
                    961: 
1.1.1.6   root      962: /* do_getsockopt() Must return target values and target errnos. */
                    963: static abi_long do_getsockopt(int sockfd, int level, int optname,
                    964:                               abi_ulong optval_addr, abi_ulong optlen)
1.1       root      965: {
1.1.1.6   root      966:     abi_long ret;
1.1.1.7 ! root      967:     int len, val;
        !           968:     socklen_t lv;
1.1       root      969: 
                    970:     switch(level) {
1.1.1.4   root      971:     case TARGET_SOL_SOCKET:
                    972:        level = SOL_SOCKET;
1.1       root      973:        switch (optname) {
1.1.1.4   root      974:        case TARGET_SO_LINGER:
                    975:        case TARGET_SO_RCVTIMEO:
                    976:        case TARGET_SO_SNDTIMEO:
                    977:        case TARGET_SO_PEERCRED:
                    978:        case TARGET_SO_PEERNAME:
1.1       root      979:            /* These don't just return a single integer */
                    980:            goto unimplemented;
                    981:         default:
                    982:             goto int_case;
                    983:         }
                    984:         break;
                    985:     case SOL_TCP:
                    986:         /* TCP options all take an 'int' value.  */
                    987:     int_case:
1.1.1.6   root      988:         if (get_user_u32(len, optlen))
                    989:             return -TARGET_EFAULT;
1.1       root      990:         if (len < 0)
1.1.1.6   root      991:             return -TARGET_EINVAL;
1.1       root      992:         lv = sizeof(int);
                    993:         ret = get_errno(getsockopt(sockfd, level, optname, &val, &lv));
                    994:         if (ret < 0)
                    995:             return ret;
                    996:         val = tswap32(val);
                    997:         if (len > lv)
                    998:             len = lv;
1.1.1.6   root      999:         if (len == 4) {
                   1000:             if (put_user_u32(val, optval_addr))
                   1001:                 return -TARGET_EFAULT;
                   1002:         } else {
                   1003:             if (put_user_u8(val, optval_addr))
                   1004:                 return -TARGET_EFAULT;
                   1005:        }
                   1006:         if (put_user_u32(len, optlen))
                   1007:             return -TARGET_EFAULT;
1.1       root     1008:         break;
                   1009:     case SOL_IP:
                   1010:         switch(optname) {
                   1011:         case IP_TOS:
                   1012:         case IP_TTL:
                   1013:         case IP_HDRINCL:
                   1014:         case IP_ROUTER_ALERT:
                   1015:         case IP_RECVOPTS:
                   1016:         case IP_RETOPTS:
                   1017:         case IP_PKTINFO:
                   1018:         case IP_MTU_DISCOVER:
                   1019:         case IP_RECVERR:
                   1020:         case IP_RECVTOS:
                   1021: #ifdef IP_FREEBIND
                   1022:         case IP_FREEBIND:
                   1023: #endif
                   1024:         case IP_MULTICAST_TTL:
                   1025:         case IP_MULTICAST_LOOP:
1.1.1.6   root     1026:             if (get_user_u32(len, optlen))
                   1027:                 return -TARGET_EFAULT;
1.1       root     1028:             if (len < 0)
1.1.1.6   root     1029:                 return -TARGET_EINVAL;
1.1       root     1030:             lv = sizeof(int);
                   1031:             ret = get_errno(getsockopt(sockfd, level, optname, &val, &lv));
                   1032:             if (ret < 0)
                   1033:                 return ret;
                   1034:             if (len < sizeof(int) && len > 0 && val >= 0 && val < 255) {
                   1035:                 len = 1;
1.1.1.6   root     1036:                 if (put_user_u32(len, optlen)
                   1037:                     || put_user_u8(val, optval_addr))
                   1038:                     return -TARGET_EFAULT;
1.1       root     1039:             } else {
                   1040:                 if (len > sizeof(int))
                   1041:                     len = sizeof(int);
1.1.1.6   root     1042:                 if (put_user_u32(len, optlen)
                   1043:                     || put_user_u32(val, optval_addr))
                   1044:                     return -TARGET_EFAULT;
1.1       root     1045:             }
                   1046:             break;
                   1047:         default:
1.1.1.6   root     1048:             ret = -TARGET_ENOPROTOOPT;
                   1049:             break;
1.1       root     1050:         }
                   1051:         break;
                   1052:     default:
                   1053:     unimplemented:
                   1054:         gemu_log("getsockopt level=%d optname=%d not yet supported\n",
                   1055:                  level, optname);
1.1.1.6   root     1056:         ret = -TARGET_EOPNOTSUPP;
1.1       root     1057:         break;
                   1058:     }
                   1059:     return ret;
                   1060: }
                   1061: 
1.1.1.6   root     1062: /* FIXME
                   1063:  * lock_iovec()/unlock_iovec() have a return code of 0 for success where
                   1064:  * other lock functions have a return code of 0 for failure.
                   1065:  */
                   1066: static abi_long lock_iovec(int type, struct iovec *vec, abi_ulong target_addr,
                   1067:                            int count, int copy)
1.1.1.3   root     1068: {
                   1069:     struct target_iovec *target_vec;
1.1.1.6   root     1070:     abi_ulong base;
1.1.1.7 ! root     1071:     int i;
1.1.1.3   root     1072: 
1.1.1.6   root     1073:     target_vec = lock_user(VERIFY_READ, target_addr, count * sizeof(struct target_iovec), 1);
                   1074:     if (!target_vec)
                   1075:         return -TARGET_EFAULT;
1.1.1.3   root     1076:     for(i = 0;i < count; i++) {
                   1077:         base = tswapl(target_vec[i].iov_base);
                   1078:         vec[i].iov_len = tswapl(target_vec[i].iov_len);
1.1.1.7 ! root     1079:         if (vec[i].iov_len != 0) {
        !          1080:             vec[i].iov_base = lock_user(type, base, vec[i].iov_len, copy);
        !          1081:             /* Don't check lock_user return value. We must call writev even
        !          1082:                if a element has invalid base address. */
        !          1083:         } else {
        !          1084:             /* zero length pointer is ignored */
        !          1085:             vec[i].iov_base = NULL;
        !          1086:         }
1.1.1.6   root     1087:     }
                   1088:     unlock_user (target_vec, target_addr, 0);
                   1089:     return 0;
1.1.1.3   root     1090: }
                   1091: 
1.1.1.6   root     1092: static abi_long unlock_iovec(struct iovec *vec, abi_ulong target_addr,
                   1093:                              int count, int copy)
1.1.1.3   root     1094: {
                   1095:     struct target_iovec *target_vec;
1.1.1.6   root     1096:     abi_ulong base;
1.1.1.3   root     1097:     int i;
                   1098: 
1.1.1.6   root     1099:     target_vec = lock_user(VERIFY_READ, target_addr, count * sizeof(struct target_iovec), 1);
                   1100:     if (!target_vec)
                   1101:         return -TARGET_EFAULT;
1.1.1.3   root     1102:     for(i = 0;i < count; i++) {
1.1.1.7 ! root     1103:         if (target_vec[i].iov_base) {
        !          1104:             base = tswapl(target_vec[i].iov_base);
        !          1105:             unlock_user(vec[i].iov_base, base, copy ? vec[i].iov_len : 0);
        !          1106:         }
1.1.1.3   root     1107:     }
                   1108:     unlock_user (target_vec, target_addr, 0);
1.1.1.6   root     1109: 
                   1110:     return 0;
1.1.1.3   root     1111: }
                   1112: 
1.1.1.6   root     1113: /* do_socket() Must return target values and target errnos. */
                   1114: static abi_long do_socket(int domain, int type, int protocol)
1.1.1.4   root     1115: {
                   1116: #if defined(TARGET_MIPS)
                   1117:     switch(type) {
                   1118:     case TARGET_SOCK_DGRAM:
                   1119:         type = SOCK_DGRAM;
                   1120:         break;
                   1121:     case TARGET_SOCK_STREAM:
                   1122:         type = SOCK_STREAM;
                   1123:         break;
                   1124:     case TARGET_SOCK_RAW:
                   1125:         type = SOCK_RAW;
                   1126:         break;
                   1127:     case TARGET_SOCK_RDM:
                   1128:         type = SOCK_RDM;
                   1129:         break;
                   1130:     case TARGET_SOCK_SEQPACKET:
                   1131:         type = SOCK_SEQPACKET;
                   1132:         break;
                   1133:     case TARGET_SOCK_PACKET:
                   1134:         type = SOCK_PACKET;
                   1135:         break;
                   1136:     }
                   1137: #endif
1.1.1.6   root     1138:     if (domain == PF_NETLINK)
                   1139:         return -EAFNOSUPPORT; /* do not NETLINK socket connections possible */
1.1.1.4   root     1140:     return get_errno(socket(domain, type, protocol));
                   1141: }
                   1142: 
1.1.1.7 ! root     1143: /* MAX_SOCK_ADDR from linux/net/socket.c */
        !          1144: #define MAX_SOCK_ADDR  128
        !          1145: 
1.1.1.6   root     1146: /* do_bind() Must return target values and target errnos. */
                   1147: static abi_long do_bind(int sockfd, abi_ulong target_addr,
                   1148:                         socklen_t addrlen)
1.1.1.4   root     1149: {
1.1.1.7 ! root     1150:     void *addr;
        !          1151: 
        !          1152:     if (addrlen < 0 || addrlen > MAX_SOCK_ADDR)
        !          1153:         return -TARGET_EINVAL;
        !          1154: 
        !          1155:     addr = alloca(addrlen);
1.1.1.6   root     1156: 
1.1.1.4   root     1157:     target_to_host_sockaddr(addr, target_addr, addrlen);
                   1158:     return get_errno(bind(sockfd, addr, addrlen));
                   1159: }
                   1160: 
1.1.1.6   root     1161: /* do_connect() Must return target values and target errnos. */
                   1162: static abi_long do_connect(int sockfd, abi_ulong target_addr,
                   1163:                            socklen_t addrlen)
1.1.1.4   root     1164: {
1.1.1.7 ! root     1165:     void *addr;
        !          1166: 
        !          1167:     if (addrlen < 0 || addrlen > MAX_SOCK_ADDR)
        !          1168:         return -TARGET_EINVAL;
        !          1169: 
        !          1170:     addr = alloca(addrlen);
1.1.1.6   root     1171: 
1.1.1.4   root     1172:     target_to_host_sockaddr(addr, target_addr, addrlen);
                   1173:     return get_errno(connect(sockfd, addr, addrlen));
                   1174: }
                   1175: 
1.1.1.6   root     1176: /* do_sendrecvmsg() Must return target values and target errnos. */
                   1177: static abi_long do_sendrecvmsg(int fd, abi_ulong target_msg,
                   1178:                                int flags, int send)
1.1.1.4   root     1179: {
1.1.1.7 ! root     1180:     abi_long ret, len;
1.1.1.4   root     1181:     struct target_msghdr *msgp;
                   1182:     struct msghdr msg;
                   1183:     int count;
                   1184:     struct iovec *vec;
1.1.1.6   root     1185:     abi_ulong target_vec;
1.1.1.4   root     1186: 
1.1.1.6   root     1187:     /* FIXME */
                   1188:     if (!lock_user_struct(send ? VERIFY_READ : VERIFY_WRITE,
                   1189:                           msgp,
                   1190:                           target_msg,
                   1191:                           send ? 1 : 0))
                   1192:         return -TARGET_EFAULT;
1.1.1.4   root     1193:     if (msgp->msg_name) {
                   1194:         msg.msg_namelen = tswap32(msgp->msg_namelen);
                   1195:         msg.msg_name = alloca(msg.msg_namelen);
                   1196:         target_to_host_sockaddr(msg.msg_name, tswapl(msgp->msg_name),
                   1197:                                 msg.msg_namelen);
                   1198:     } else {
                   1199:         msg.msg_name = NULL;
                   1200:         msg.msg_namelen = 0;
                   1201:     }
                   1202:     msg.msg_controllen = 2 * tswapl(msgp->msg_controllen);
                   1203:     msg.msg_control = alloca(msg.msg_controllen);
                   1204:     msg.msg_flags = tswap32(msgp->msg_flags);
1.1.1.6   root     1205: 
1.1.1.4   root     1206:     count = tswapl(msgp->msg_iovlen);
                   1207:     vec = alloca(count * sizeof(struct iovec));
                   1208:     target_vec = tswapl(msgp->msg_iov);
1.1.1.6   root     1209:     lock_iovec(send ? VERIFY_READ : VERIFY_WRITE, vec, target_vec, count, send);
1.1.1.4   root     1210:     msg.msg_iovlen = count;
                   1211:     msg.msg_iov = vec;
1.1.1.6   root     1212: 
1.1.1.4   root     1213:     if (send) {
1.1.1.6   root     1214:         ret = target_to_host_cmsg(&msg, msgp);
                   1215:         if (ret == 0)
                   1216:             ret = get_errno(sendmsg(fd, &msg, flags));
1.1.1.4   root     1217:     } else {
                   1218:         ret = get_errno(recvmsg(fd, &msg, flags));
1.1.1.7 ! root     1219:         if (!is_error(ret)) {
        !          1220:             len = ret;
1.1.1.6   root     1221:             ret = host_to_target_cmsg(msgp, &msg);
1.1.1.7 ! root     1222:             if (!is_error(ret))
        !          1223:                 ret = len;
        !          1224:         }
1.1.1.4   root     1225:     }
                   1226:     unlock_iovec(vec, target_vec, count, !send);
1.1.1.6   root     1227:     unlock_user_struct(msgp, target_msg, send ? 0 : 1);
1.1.1.4   root     1228:     return ret;
                   1229: }
                   1230: 
1.1.1.6   root     1231: /* do_accept() Must return target values and target errnos. */
                   1232: static abi_long do_accept(int fd, abi_ulong target_addr,
                   1233:                           abi_ulong target_addrlen_addr)
1.1.1.5   root     1234: {
1.1.1.6   root     1235:     socklen_t addrlen;
                   1236:     void *addr;
                   1237:     abi_long ret;
                   1238: 
                   1239:     if (get_user_u32(addrlen, target_addrlen_addr))
                   1240:         return -TARGET_EFAULT;
                   1241: 
1.1.1.7 ! root     1242:     if (addrlen < 0 || addrlen > MAX_SOCK_ADDR)
        !          1243:         return -TARGET_EINVAL;
        !          1244: 
1.1.1.6   root     1245:     addr = alloca(addrlen);
1.1.1.5   root     1246: 
                   1247:     ret = get_errno(accept(fd, addr, &addrlen));
                   1248:     if (!is_error(ret)) {
                   1249:         host_to_target_sockaddr(target_addr, addr, addrlen);
1.1.1.6   root     1250:         if (put_user_u32(addrlen, target_addrlen_addr))
                   1251:             ret = -TARGET_EFAULT;
1.1.1.5   root     1252:     }
                   1253:     return ret;
                   1254: }
                   1255: 
1.1.1.6   root     1256: /* do_getpeername() Must return target values and target errnos. */
                   1257: static abi_long do_getpeername(int fd, abi_ulong target_addr,
                   1258:                                abi_ulong target_addrlen_addr)
1.1.1.5   root     1259: {
1.1.1.6   root     1260:     socklen_t addrlen;
                   1261:     void *addr;
                   1262:     abi_long ret;
                   1263: 
                   1264:     if (get_user_u32(addrlen, target_addrlen_addr))
                   1265:         return -TARGET_EFAULT;
                   1266: 
1.1.1.7 ! root     1267:     if (addrlen < 0 || addrlen > MAX_SOCK_ADDR)
        !          1268:         return -TARGET_EINVAL;
        !          1269: 
1.1.1.6   root     1270:     addr = alloca(addrlen);
1.1.1.5   root     1271: 
                   1272:     ret = get_errno(getpeername(fd, addr, &addrlen));
                   1273:     if (!is_error(ret)) {
                   1274:         host_to_target_sockaddr(target_addr, addr, addrlen);
1.1.1.6   root     1275:         if (put_user_u32(addrlen, target_addrlen_addr))
                   1276:             ret = -TARGET_EFAULT;
1.1.1.5   root     1277:     }
                   1278:     return ret;
                   1279: }
                   1280: 
1.1.1.6   root     1281: /* do_getsockname() Must return target values and target errnos. */
                   1282: static abi_long do_getsockname(int fd, abi_ulong target_addr,
                   1283:                                abi_ulong target_addrlen_addr)
1.1.1.5   root     1284: {
1.1.1.6   root     1285:     socklen_t addrlen;
                   1286:     void *addr;
                   1287:     abi_long ret;
                   1288: 
1.1.1.7 ! root     1289:     if (target_addr == 0)
        !          1290:        return get_errno(accept(fd, NULL, NULL));
        !          1291: 
1.1.1.6   root     1292:     if (get_user_u32(addrlen, target_addrlen_addr))
                   1293:         return -TARGET_EFAULT;
                   1294: 
1.1.1.7 ! root     1295:     if (addrlen < 0 || addrlen > MAX_SOCK_ADDR)
        !          1296:         return -TARGET_EINVAL;
        !          1297: 
1.1.1.6   root     1298:     addr = alloca(addrlen);
1.1.1.5   root     1299: 
                   1300:     ret = get_errno(getsockname(fd, addr, &addrlen));
                   1301:     if (!is_error(ret)) {
                   1302:         host_to_target_sockaddr(target_addr, addr, addrlen);
1.1.1.6   root     1303:         if (put_user_u32(addrlen, target_addrlen_addr))
                   1304:             ret = -TARGET_EFAULT;
1.1.1.5   root     1305:     }
                   1306:     return ret;
                   1307: }
                   1308: 
1.1.1.6   root     1309: /* do_socketpair() Must return target values and target errnos. */
                   1310: static abi_long do_socketpair(int domain, int type, int protocol,
                   1311:                               abi_ulong target_tab_addr)
1.1.1.5   root     1312: {
                   1313:     int tab[2];
1.1.1.6   root     1314:     abi_long ret;
1.1.1.5   root     1315: 
                   1316:     ret = get_errno(socketpair(domain, type, protocol, tab));
                   1317:     if (!is_error(ret)) {
1.1.1.6   root     1318:         if (put_user_s32(tab[0], target_tab_addr)
                   1319:             || put_user_s32(tab[1], target_tab_addr + sizeof(tab[0])))
                   1320:             ret = -TARGET_EFAULT;
1.1.1.5   root     1321:     }
                   1322:     return ret;
                   1323: }
                   1324: 
1.1.1.6   root     1325: /* do_sendto() Must return target values and target errnos. */
                   1326: static abi_long do_sendto(int fd, abi_ulong msg, size_t len, int flags,
                   1327:                           abi_ulong target_addr, socklen_t addrlen)
1.1.1.5   root     1328: {
                   1329:     void *addr;
                   1330:     void *host_msg;
1.1.1.6   root     1331:     abi_long ret;
1.1.1.5   root     1332: 
1.1.1.7 ! root     1333:     if (addrlen < 0 || addrlen > MAX_SOCK_ADDR)
        !          1334:         return -TARGET_EINVAL;
        !          1335: 
1.1.1.6   root     1336:     host_msg = lock_user(VERIFY_READ, msg, len, 1);
                   1337:     if (!host_msg)
                   1338:         return -TARGET_EFAULT;
1.1.1.5   root     1339:     if (target_addr) {
                   1340:         addr = alloca(addrlen);
                   1341:         target_to_host_sockaddr(addr, target_addr, addrlen);
                   1342:         ret = get_errno(sendto(fd, host_msg, len, flags, addr, addrlen));
                   1343:     } else {
                   1344:         ret = get_errno(send(fd, host_msg, len, flags));
                   1345:     }
                   1346:     unlock_user(host_msg, msg, 0);
                   1347:     return ret;
                   1348: }
                   1349: 
1.1.1.6   root     1350: /* do_recvfrom() Must return target values and target errnos. */
                   1351: static abi_long do_recvfrom(int fd, abi_ulong msg, size_t len, int flags,
                   1352:                             abi_ulong target_addr,
                   1353:                             abi_ulong target_addrlen)
1.1.1.5   root     1354: {
                   1355:     socklen_t addrlen;
                   1356:     void *addr;
                   1357:     void *host_msg;
1.1.1.6   root     1358:     abi_long ret;
1.1.1.5   root     1359: 
1.1.1.6   root     1360:     host_msg = lock_user(VERIFY_WRITE, msg, len, 0);
                   1361:     if (!host_msg)
                   1362:         return -TARGET_EFAULT;
1.1.1.5   root     1363:     if (target_addr) {
1.1.1.6   root     1364:         if (get_user_u32(addrlen, target_addrlen)) {
                   1365:             ret = -TARGET_EFAULT;
                   1366:             goto fail;
                   1367:         }
1.1.1.7 ! root     1368:         if (addrlen < 0 || addrlen > MAX_SOCK_ADDR) {
        !          1369:             ret = -TARGET_EINVAL;
        !          1370:             goto fail;
        !          1371:         }
1.1.1.5   root     1372:         addr = alloca(addrlen);
                   1373:         ret = get_errno(recvfrom(fd, host_msg, len, flags, addr, &addrlen));
                   1374:     } else {
                   1375:         addr = NULL; /* To keep compiler quiet.  */
                   1376:         ret = get_errno(recv(fd, host_msg, len, flags));
                   1377:     }
                   1378:     if (!is_error(ret)) {
                   1379:         if (target_addr) {
                   1380:             host_to_target_sockaddr(target_addr, addr, addrlen);
1.1.1.6   root     1381:             if (put_user_u32(addrlen, target_addrlen)) {
                   1382:                 ret = -TARGET_EFAULT;
                   1383:                 goto fail;
                   1384:             }
1.1.1.5   root     1385:         }
                   1386:         unlock_user(host_msg, msg, len);
                   1387:     } else {
1.1.1.6   root     1388: fail:
1.1.1.5   root     1389:         unlock_user(host_msg, msg, 0);
                   1390:     }
                   1391:     return ret;
                   1392: }
                   1393: 
1.1.1.6   root     1394: #ifdef TARGET_NR_socketcall
                   1395: /* do_socketcall() Must return target values and target errnos. */
                   1396: static abi_long do_socketcall(int num, abi_ulong vptr)
1.1       root     1397: {
1.1.1.6   root     1398:     abi_long ret;
                   1399:     const int n = sizeof(abi_ulong);
1.1       root     1400: 
                   1401:     switch(num) {
                   1402:     case SOCKOP_socket:
                   1403:        {
1.1.1.6   root     1404:             int domain, type, protocol;
                   1405: 
                   1406:             if (get_user_s32(domain, vptr)
                   1407:                 || get_user_s32(type, vptr + n)
                   1408:                 || get_user_s32(protocol, vptr + 2 * n))
                   1409:                 return -TARGET_EFAULT;
                   1410: 
1.1.1.4   root     1411:             ret = do_socket(domain, type, protocol);
1.1       root     1412:        }
                   1413:         break;
                   1414:     case SOCKOP_bind:
                   1415:        {
1.1.1.6   root     1416:             int sockfd;
                   1417:             abi_ulong target_addr;
                   1418:             socklen_t addrlen;
                   1419: 
                   1420:             if (get_user_s32(sockfd, vptr)
                   1421:                 || get_user_ual(target_addr, vptr + n)
                   1422:                 || get_user_u32(addrlen, vptr + 2 * n))
                   1423:                 return -TARGET_EFAULT;
                   1424: 
1.1.1.4   root     1425:             ret = do_bind(sockfd, target_addr, addrlen);
1.1       root     1426:         }
                   1427:         break;
                   1428:     case SOCKOP_connect:
                   1429:         {
1.1.1.6   root     1430:             int sockfd;
                   1431:             abi_ulong target_addr;
                   1432:             socklen_t addrlen;
                   1433: 
                   1434:             if (get_user_s32(sockfd, vptr)
                   1435:                 || get_user_ual(target_addr, vptr + n)
                   1436:                 || get_user_u32(addrlen, vptr + 2 * n))
                   1437:                 return -TARGET_EFAULT;
                   1438: 
1.1.1.4   root     1439:             ret = do_connect(sockfd, target_addr, addrlen);
1.1       root     1440:         }
                   1441:         break;
                   1442:     case SOCKOP_listen:
                   1443:         {
1.1.1.6   root     1444:             int sockfd, backlog;
                   1445: 
                   1446:             if (get_user_s32(sockfd, vptr)
                   1447:                 || get_user_s32(backlog, vptr + n))
                   1448:                 return -TARGET_EFAULT;
                   1449: 
1.1       root     1450:             ret = get_errno(listen(sockfd, backlog));
                   1451:         }
                   1452:         break;
                   1453:     case SOCKOP_accept:
                   1454:         {
1.1.1.6   root     1455:             int sockfd;
                   1456:             abi_ulong target_addr, target_addrlen;
                   1457: 
                   1458:             if (get_user_s32(sockfd, vptr)
                   1459:                 || get_user_ual(target_addr, vptr + n)
                   1460:                 || get_user_u32(target_addrlen, vptr + 2 * n))
                   1461:                 return -TARGET_EFAULT;
                   1462: 
1.1.1.5   root     1463:             ret = do_accept(sockfd, target_addr, target_addrlen);
1.1       root     1464:         }
                   1465:         break;
                   1466:     case SOCKOP_getsockname:
                   1467:         {
1.1.1.6   root     1468:             int sockfd;
                   1469:             abi_ulong target_addr, target_addrlen;
                   1470: 
                   1471:             if (get_user_s32(sockfd, vptr)
                   1472:                 || get_user_ual(target_addr, vptr + n)
                   1473:                 || get_user_u32(target_addrlen, vptr + 2 * n))
                   1474:                 return -TARGET_EFAULT;
                   1475: 
1.1.1.5   root     1476:             ret = do_getsockname(sockfd, target_addr, target_addrlen);
1.1       root     1477:         }
                   1478:         break;
                   1479:     case SOCKOP_getpeername:
                   1480:         {
1.1.1.6   root     1481:             int sockfd;
                   1482:             abi_ulong target_addr, target_addrlen;
                   1483: 
                   1484:             if (get_user_s32(sockfd, vptr)
                   1485:                 || get_user_ual(target_addr, vptr + n)
                   1486:                 || get_user_u32(target_addrlen, vptr + 2 * n))
                   1487:                 return -TARGET_EFAULT;
                   1488: 
1.1.1.5   root     1489:             ret = do_getpeername(sockfd, target_addr, target_addrlen);
1.1       root     1490:         }
                   1491:         break;
                   1492:     case SOCKOP_socketpair:
                   1493:         {
1.1.1.6   root     1494:             int domain, type, protocol;
                   1495:             abi_ulong tab;
                   1496: 
                   1497:             if (get_user_s32(domain, vptr)
                   1498:                 || get_user_s32(type, vptr + n)
                   1499:                 || get_user_s32(protocol, vptr + 2 * n)
                   1500:                 || get_user_ual(tab, vptr + 3 * n))
                   1501:                 return -TARGET_EFAULT;
                   1502: 
1.1.1.5   root     1503:             ret = do_socketpair(domain, type, protocol, tab);
1.1       root     1504:         }
                   1505:         break;
                   1506:     case SOCKOP_send:
                   1507:         {
1.1.1.6   root     1508:             int sockfd;
                   1509:             abi_ulong msg;
                   1510:             size_t len;
                   1511:             int flags;
                   1512: 
                   1513:             if (get_user_s32(sockfd, vptr)
                   1514:                 || get_user_ual(msg, vptr + n)
                   1515:                 || get_user_ual(len, vptr + 2 * n)
                   1516:                 || get_user_s32(flags, vptr + 3 * n))
                   1517:                 return -TARGET_EFAULT;
                   1518: 
1.1.1.5   root     1519:             ret = do_sendto(sockfd, msg, len, flags, 0, 0);
1.1       root     1520:         }
                   1521:         break;
                   1522:     case SOCKOP_recv:
                   1523:         {
1.1.1.6   root     1524:             int sockfd;
                   1525:             abi_ulong msg;
                   1526:             size_t len;
                   1527:             int flags;
                   1528: 
                   1529:             if (get_user_s32(sockfd, vptr)
                   1530:                 || get_user_ual(msg, vptr + n)
                   1531:                 || get_user_ual(len, vptr + 2 * n)
                   1532:                 || get_user_s32(flags, vptr + 3 * n))
                   1533:                 return -TARGET_EFAULT;
                   1534: 
1.1.1.5   root     1535:             ret = do_recvfrom(sockfd, msg, len, flags, 0, 0);
1.1       root     1536:         }
                   1537:         break;
                   1538:     case SOCKOP_sendto:
                   1539:         {
1.1.1.6   root     1540:             int sockfd;
                   1541:             abi_ulong msg;
                   1542:             size_t len;
                   1543:             int flags;
                   1544:             abi_ulong addr;
                   1545:             socklen_t addrlen;
                   1546: 
                   1547:             if (get_user_s32(sockfd, vptr)
                   1548:                 || get_user_ual(msg, vptr + n)
                   1549:                 || get_user_ual(len, vptr + 2 * n)
                   1550:                 || get_user_s32(flags, vptr + 3 * n)
                   1551:                 || get_user_ual(addr, vptr + 4 * n)
                   1552:                 || get_user_u32(addrlen, vptr + 5 * n))
                   1553:                 return -TARGET_EFAULT;
                   1554: 
1.1.1.5   root     1555:             ret = do_sendto(sockfd, msg, len, flags, addr, addrlen);
1.1       root     1556:         }
                   1557:         break;
                   1558:     case SOCKOP_recvfrom:
                   1559:         {
1.1.1.6   root     1560:             int sockfd;
                   1561:             abi_ulong msg;
                   1562:             size_t len;
                   1563:             int flags;
                   1564:             abi_ulong addr;
                   1565:             socklen_t addrlen;
                   1566: 
                   1567:             if (get_user_s32(sockfd, vptr)
                   1568:                 || get_user_ual(msg, vptr + n)
                   1569:                 || get_user_ual(len, vptr + 2 * n)
                   1570:                 || get_user_s32(flags, vptr + 3 * n)
                   1571:                 || get_user_ual(addr, vptr + 4 * n)
                   1572:                 || get_user_u32(addrlen, vptr + 5 * n))
                   1573:                 return -TARGET_EFAULT;
                   1574: 
1.1.1.5   root     1575:             ret = do_recvfrom(sockfd, msg, len, flags, addr, addrlen);
1.1       root     1576:         }
                   1577:         break;
                   1578:     case SOCKOP_shutdown:
                   1579:         {
1.1.1.6   root     1580:             int sockfd, how;
                   1581: 
                   1582:             if (get_user_s32(sockfd, vptr)
                   1583:                 || get_user_s32(how, vptr + n))
                   1584:                 return -TARGET_EFAULT;
1.1       root     1585: 
                   1586:             ret = get_errno(shutdown(sockfd, how));
                   1587:         }
                   1588:         break;
                   1589:     case SOCKOP_sendmsg:
                   1590:     case SOCKOP_recvmsg:
                   1591:         {
                   1592:             int fd;
1.1.1.6   root     1593:             abi_ulong target_msg;
1.1.1.4   root     1594:             int flags;
1.1       root     1595: 
1.1.1.6   root     1596:             if (get_user_s32(fd, vptr)
                   1597:                 || get_user_ual(target_msg, vptr + n)
                   1598:                 || get_user_s32(flags, vptr + 2 * n))
                   1599:                 return -TARGET_EFAULT;
1.1.1.4   root     1600: 
1.1.1.6   root     1601:             ret = do_sendrecvmsg(fd, target_msg, flags,
1.1.1.4   root     1602:                                  (num == SOCKOP_sendmsg));
1.1       root     1603:         }
                   1604:         break;
                   1605:     case SOCKOP_setsockopt:
                   1606:         {
1.1.1.6   root     1607:             int sockfd;
                   1608:             int level;
                   1609:             int optname;
                   1610:             abi_ulong optval;
                   1611:             socklen_t optlen;
                   1612: 
                   1613:             if (get_user_s32(sockfd, vptr)
                   1614:                 || get_user_s32(level, vptr + n)
                   1615:                 || get_user_s32(optname, vptr + 2 * n)
                   1616:                 || get_user_ual(optval, vptr + 3 * n)
                   1617:                 || get_user_u32(optlen, vptr + 4 * n))
                   1618:                 return -TARGET_EFAULT;
1.1       root     1619: 
                   1620:             ret = do_setsockopt(sockfd, level, optname, optval, optlen);
                   1621:         }
                   1622:         break;
                   1623:     case SOCKOP_getsockopt:
                   1624:         {
1.1.1.6   root     1625:             int sockfd;
                   1626:             int level;
                   1627:             int optname;
                   1628:             abi_ulong optval;
                   1629:             socklen_t optlen;
                   1630: 
                   1631:             if (get_user_s32(sockfd, vptr)
                   1632:                 || get_user_s32(level, vptr + n)
                   1633:                 || get_user_s32(optname, vptr + 2 * n)
                   1634:                 || get_user_ual(optval, vptr + 3 * n)
                   1635:                 || get_user_u32(optlen, vptr + 4 * n))
                   1636:                 return -TARGET_EFAULT;
1.1       root     1637: 
1.1.1.6   root     1638:             ret = do_getsockopt(sockfd, level, optname, optval, optlen);
1.1       root     1639:         }
                   1640:         break;
                   1641:     default:
                   1642:         gemu_log("Unsupported socketcall: %d\n", num);
1.1.1.6   root     1643:         ret = -TARGET_ENOSYS;
1.1       root     1644:         break;
                   1645:     }
                   1646:     return ret;
                   1647: }
1.1.1.6   root     1648: #endif
1.1       root     1649: 
1.1.1.6   root     1650: #ifdef TARGET_NR_ipc
1.1       root     1651: #define N_SHM_REGIONS  32
                   1652: 
                   1653: static struct shm_region {
1.1.1.6   root     1654:     abi_ulong  start;
                   1655:     abi_ulong  size;
1.1       root     1656: } shm_regions[N_SHM_REGIONS];
1.1.1.7 ! root     1657: #endif
1.1       root     1658: 
1.1.1.6   root     1659: struct target_ipc_perm
                   1660: {
                   1661:     abi_long __key;
                   1662:     abi_ulong uid;
                   1663:     abi_ulong gid;
                   1664:     abi_ulong cuid;
                   1665:     abi_ulong cgid;
                   1666:     unsigned short int mode;
                   1667:     unsigned short int __pad1;
                   1668:     unsigned short int __seq;
                   1669:     unsigned short int __pad2;
                   1670:     abi_ulong __unused1;
                   1671:     abi_ulong __unused2;
                   1672: };
                   1673: 
                   1674: struct target_semid_ds
                   1675: {
                   1676:   struct target_ipc_perm sem_perm;
                   1677:   abi_ulong sem_otime;
                   1678:   abi_ulong __unused1;
                   1679:   abi_ulong sem_ctime;
                   1680:   abi_ulong __unused2;
                   1681:   abi_ulong sem_nsems;
                   1682:   abi_ulong __unused3;
                   1683:   abi_ulong __unused4;
                   1684: };
                   1685: 
                   1686: static inline abi_long target_to_host_ipc_perm(struct ipc_perm *host_ip,
                   1687:                                                abi_ulong target_addr)
                   1688: {
                   1689:     struct target_ipc_perm *target_ip;
                   1690:     struct target_semid_ds *target_sd;
                   1691: 
                   1692:     if (!lock_user_struct(VERIFY_READ, target_sd, target_addr, 1))
                   1693:         return -TARGET_EFAULT;
                   1694:     target_ip=&(target_sd->sem_perm);
                   1695:     host_ip->__key = tswapl(target_ip->__key);
                   1696:     host_ip->uid = tswapl(target_ip->uid);
                   1697:     host_ip->gid = tswapl(target_ip->gid);
                   1698:     host_ip->cuid = tswapl(target_ip->cuid);
                   1699:     host_ip->cgid = tswapl(target_ip->cgid);
                   1700:     host_ip->mode = tswapl(target_ip->mode);
                   1701:     unlock_user_struct(target_sd, target_addr, 0);
                   1702:     return 0;
                   1703: }
                   1704: 
                   1705: static inline abi_long host_to_target_ipc_perm(abi_ulong target_addr,
                   1706:                                                struct ipc_perm *host_ip)
                   1707: {
                   1708:     struct target_ipc_perm *target_ip;
                   1709:     struct target_semid_ds *target_sd;
                   1710: 
                   1711:     if (!lock_user_struct(VERIFY_WRITE, target_sd, target_addr, 0))
                   1712:         return -TARGET_EFAULT;
                   1713:     target_ip = &(target_sd->sem_perm);
                   1714:     target_ip->__key = tswapl(host_ip->__key);
                   1715:     target_ip->uid = tswapl(host_ip->uid);
                   1716:     target_ip->gid = tswapl(host_ip->gid);
                   1717:     target_ip->cuid = tswapl(host_ip->cuid);
                   1718:     target_ip->cgid = tswapl(host_ip->cgid);
                   1719:     target_ip->mode = tswapl(host_ip->mode);
                   1720:     unlock_user_struct(target_sd, target_addr, 1);
                   1721:     return 0;
                   1722: }
                   1723: 
                   1724: static inline abi_long target_to_host_semid_ds(struct semid_ds *host_sd,
                   1725:                                                abi_ulong target_addr)
                   1726: {
                   1727:     struct target_semid_ds *target_sd;
                   1728: 
                   1729:     if (!lock_user_struct(VERIFY_READ, target_sd, target_addr, 1))
                   1730:         return -TARGET_EFAULT;
                   1731:     target_to_host_ipc_perm(&(host_sd->sem_perm),target_addr);
                   1732:     host_sd->sem_nsems = tswapl(target_sd->sem_nsems);
                   1733:     host_sd->sem_otime = tswapl(target_sd->sem_otime);
                   1734:     host_sd->sem_ctime = tswapl(target_sd->sem_ctime);
                   1735:     unlock_user_struct(target_sd, target_addr, 0);
                   1736:     return 0;
                   1737: }
                   1738: 
                   1739: static inline abi_long host_to_target_semid_ds(abi_ulong target_addr,
                   1740:                                                struct semid_ds *host_sd)
                   1741: {
                   1742:     struct target_semid_ds *target_sd;
                   1743: 
                   1744:     if (!lock_user_struct(VERIFY_WRITE, target_sd, target_addr, 0))
                   1745:         return -TARGET_EFAULT;
                   1746:     host_to_target_ipc_perm(target_addr,&(host_sd->sem_perm));
                   1747:     target_sd->sem_nsems = tswapl(host_sd->sem_nsems);
                   1748:     target_sd->sem_otime = tswapl(host_sd->sem_otime);
                   1749:     target_sd->sem_ctime = tswapl(host_sd->sem_ctime);
                   1750:     unlock_user_struct(target_sd, target_addr, 1);
                   1751:     return 0;
                   1752: }
                   1753: 
1.1.1.5   root     1754: union semun {
                   1755:        int val;
1.1.1.6   root     1756:        struct semid_ds *buf;
1.1.1.5   root     1757:        unsigned short *array;
                   1758: };
                   1759: 
1.1.1.6   root     1760: union target_semun {
                   1761:        int val;
                   1762:        abi_long buf;
                   1763:        unsigned short int *array;
                   1764: };
                   1765: 
                   1766: static inline abi_long target_to_host_semun(int cmd,
                   1767:                                             union semun *host_su,
                   1768:                                             abi_ulong target_addr,
                   1769:                                             struct semid_ds *ds)
                   1770: {
                   1771:     union target_semun *target_su;
                   1772: 
                   1773:     switch( cmd ) {
                   1774:        case IPC_STAT:
                   1775:        case IPC_SET:
                   1776:            if (!lock_user_struct(VERIFY_READ, target_su, target_addr, 1))
                   1777:                return -TARGET_EFAULT;
                   1778:           target_to_host_semid_ds(ds,target_su->buf);
                   1779:           host_su->buf = ds;
                   1780:            unlock_user_struct(target_su, target_addr, 0);
                   1781:           break;
                   1782:        case GETVAL:
                   1783:        case SETVAL:
                   1784:            if (!lock_user_struct(VERIFY_READ, target_su, target_addr, 1))
                   1785:                return -TARGET_EFAULT;
                   1786:           host_su->val = tswapl(target_su->val);
                   1787:            unlock_user_struct(target_su, target_addr, 0);
                   1788:           break;
                   1789:        case GETALL:
                   1790:        case SETALL:
                   1791:            if (!lock_user_struct(VERIFY_READ, target_su, target_addr, 1))
                   1792:                return -TARGET_EFAULT;
                   1793:           *host_su->array = tswap16(*target_su->array);
                   1794:            unlock_user_struct(target_su, target_addr, 0);
                   1795:           break;
                   1796:        default:
                   1797:            gemu_log("semun operation not fully supported: %d\n", (int)cmd);
                   1798:     }
                   1799:     return 0;
                   1800: }
                   1801: 
                   1802: static inline abi_long host_to_target_semun(int cmd,
                   1803:                                             abi_ulong target_addr,
                   1804:                                             union semun *host_su,
                   1805:                                             struct semid_ds *ds)
                   1806: {
                   1807:     union target_semun *target_su;
                   1808: 
                   1809:     switch( cmd ) {
                   1810:        case IPC_STAT:
                   1811:        case IPC_SET:
                   1812:            if (lock_user_struct(VERIFY_WRITE, target_su, target_addr, 0))
                   1813:                return -TARGET_EFAULT;
                   1814:           host_to_target_semid_ds(target_su->buf,ds);
                   1815:            unlock_user_struct(target_su, target_addr, 1);
                   1816:           break;
                   1817:        case GETVAL:
                   1818:        case SETVAL:
                   1819:            if (lock_user_struct(VERIFY_WRITE, target_su, target_addr, 0))
                   1820:                return -TARGET_EFAULT;
                   1821:           target_su->val = tswapl(host_su->val);
                   1822:            unlock_user_struct(target_su, target_addr, 1);
                   1823:           break;
                   1824:        case GETALL:
                   1825:        case SETALL:
                   1826:            if (lock_user_struct(VERIFY_WRITE, target_su, target_addr, 0))
                   1827:                return -TARGET_EFAULT;
                   1828:           *target_su->array = tswap16(*host_su->array);
                   1829:            unlock_user_struct(target_su, target_addr, 1);
                   1830:           break;
                   1831:         default:
                   1832:            gemu_log("semun operation not fully supported: %d\n", (int)cmd);
                   1833:     }
                   1834:     return 0;
                   1835: }
                   1836: 
                   1837: static inline abi_long do_semctl(int first, int second, int third,
                   1838:                                  abi_long ptr)
                   1839: {
                   1840:     union semun arg;
                   1841:     struct semid_ds dsarg;
                   1842:     int cmd = third&0xff;
                   1843:     abi_long ret = 0;
                   1844: 
                   1845:     switch( cmd ) {
                   1846:        case GETVAL:
                   1847:             target_to_host_semun(cmd,&arg,ptr,&dsarg);
                   1848:             ret = get_errno(semctl(first, second, cmd, arg));
                   1849:             host_to_target_semun(cmd,ptr,&arg,&dsarg);
                   1850:             break;
                   1851:        case SETVAL:
                   1852:             target_to_host_semun(cmd,&arg,ptr,&dsarg);
                   1853:             ret = get_errno(semctl(first, second, cmd, arg));
                   1854:             host_to_target_semun(cmd,ptr,&arg,&dsarg);
                   1855:             break;
                   1856:        case GETALL:
                   1857:             target_to_host_semun(cmd,&arg,ptr,&dsarg);
                   1858:             ret = get_errno(semctl(first, second, cmd, arg));
                   1859:             host_to_target_semun(cmd,ptr,&arg,&dsarg);
                   1860:             break;
                   1861:        case SETALL:
                   1862:             target_to_host_semun(cmd,&arg,ptr,&dsarg);
                   1863:             ret = get_errno(semctl(first, second, cmd, arg));
                   1864:             host_to_target_semun(cmd,ptr,&arg,&dsarg);
                   1865:             break;
                   1866:        case IPC_STAT:
                   1867:             target_to_host_semun(cmd,&arg,ptr,&dsarg);
                   1868:             ret = get_errno(semctl(first, second, cmd, arg));
                   1869:             host_to_target_semun(cmd,ptr,&arg,&dsarg);
                   1870:             break;
                   1871:        case IPC_SET:
                   1872:             target_to_host_semun(cmd,&arg,ptr,&dsarg);
                   1873:             ret = get_errno(semctl(first, second, cmd, arg));
                   1874:             host_to_target_semun(cmd,ptr,&arg,&dsarg);
                   1875:             break;
                   1876:     default:
                   1877:             ret = get_errno(semctl(first, second, cmd, arg));
                   1878:     }
                   1879: 
                   1880:     return ret;
                   1881: }
                   1882: 
                   1883: struct target_msqid_ds
                   1884: {
1.1.1.7 ! root     1885:     struct target_ipc_perm msg_perm;
        !          1886:     abi_ulong msg_stime;
        !          1887: #if TARGET_ABI_BITS == 32
        !          1888:     abi_ulong __unused1;
        !          1889: #endif
        !          1890:     abi_ulong msg_rtime;
        !          1891: #if TARGET_ABI_BITS == 32
        !          1892:     abi_ulong __unused2;
        !          1893: #endif
        !          1894:     abi_ulong msg_ctime;
        !          1895: #if TARGET_ABI_BITS == 32
        !          1896:     abi_ulong __unused3;
        !          1897: #endif
        !          1898:     abi_ulong __msg_cbytes;
        !          1899:     abi_ulong msg_qnum;
        !          1900:     abi_ulong msg_qbytes;
        !          1901:     abi_ulong msg_lspid;
        !          1902:     abi_ulong msg_lrpid;
        !          1903:     abi_ulong __unused4;
        !          1904:     abi_ulong __unused5;
1.1.1.6   root     1905: };
                   1906: 
                   1907: static inline abi_long target_to_host_msqid_ds(struct msqid_ds *host_md,
                   1908:                                                abi_ulong target_addr)
                   1909: {
                   1910:     struct target_msqid_ds *target_md;
                   1911: 
                   1912:     if (!lock_user_struct(VERIFY_READ, target_md, target_addr, 1))
                   1913:         return -TARGET_EFAULT;
1.1.1.7 ! root     1914:     if (target_to_host_ipc_perm(&(host_md->msg_perm),target_addr))
        !          1915:         return -TARGET_EFAULT;
1.1.1.6   root     1916:     host_md->msg_stime = tswapl(target_md->msg_stime);
                   1917:     host_md->msg_rtime = tswapl(target_md->msg_rtime);
                   1918:     host_md->msg_ctime = tswapl(target_md->msg_ctime);
                   1919:     host_md->__msg_cbytes = tswapl(target_md->__msg_cbytes);
                   1920:     host_md->msg_qnum = tswapl(target_md->msg_qnum);
                   1921:     host_md->msg_qbytes = tswapl(target_md->msg_qbytes);
                   1922:     host_md->msg_lspid = tswapl(target_md->msg_lspid);
                   1923:     host_md->msg_lrpid = tswapl(target_md->msg_lrpid);
                   1924:     unlock_user_struct(target_md, target_addr, 0);
                   1925:     return 0;
                   1926: }
                   1927: 
                   1928: static inline abi_long host_to_target_msqid_ds(abi_ulong target_addr,
                   1929:                                                struct msqid_ds *host_md)
                   1930: {
                   1931:     struct target_msqid_ds *target_md;
                   1932: 
                   1933:     if (!lock_user_struct(VERIFY_WRITE, target_md, target_addr, 0))
                   1934:         return -TARGET_EFAULT;
1.1.1.7 ! root     1935:     if (host_to_target_ipc_perm(target_addr,&(host_md->msg_perm)))
        !          1936:         return -TARGET_EFAULT;
1.1.1.6   root     1937:     target_md->msg_stime = tswapl(host_md->msg_stime);
                   1938:     target_md->msg_rtime = tswapl(host_md->msg_rtime);
                   1939:     target_md->msg_ctime = tswapl(host_md->msg_ctime);
                   1940:     target_md->__msg_cbytes = tswapl(host_md->__msg_cbytes);
                   1941:     target_md->msg_qnum = tswapl(host_md->msg_qnum);
                   1942:     target_md->msg_qbytes = tswapl(host_md->msg_qbytes);
                   1943:     target_md->msg_lspid = tswapl(host_md->msg_lspid);
                   1944:     target_md->msg_lrpid = tswapl(host_md->msg_lrpid);
                   1945:     unlock_user_struct(target_md, target_addr, 1);
                   1946:     return 0;
                   1947: }
                   1948: 
1.1.1.7 ! root     1949: struct target_msginfo {
        !          1950:     int msgpool;
        !          1951:     int msgmap;
        !          1952:     int msgmax;
        !          1953:     int msgmnb;
        !          1954:     int msgmni;
        !          1955:     int msgssz;
        !          1956:     int msgtql;
        !          1957:     unsigned short int msgseg;
        !          1958: };
        !          1959: 
        !          1960: static inline abi_long host_to_target_msginfo(abi_ulong target_addr,
        !          1961:                                               struct msginfo *host_msginfo)
        !          1962: {
        !          1963:     struct target_msginfo *target_msginfo;
        !          1964:     if (!lock_user_struct(VERIFY_WRITE, target_msginfo, target_addr, 0))
        !          1965:         return -TARGET_EFAULT;
        !          1966:     __put_user(host_msginfo->msgpool, &target_msginfo->msgpool);
        !          1967:     __put_user(host_msginfo->msgmap, &target_msginfo->msgmap);
        !          1968:     __put_user(host_msginfo->msgmax, &target_msginfo->msgmax);
        !          1969:     __put_user(host_msginfo->msgmnb, &target_msginfo->msgmnb);
        !          1970:     __put_user(host_msginfo->msgmni, &target_msginfo->msgmni);
        !          1971:     __put_user(host_msginfo->msgssz, &target_msginfo->msgssz);
        !          1972:     __put_user(host_msginfo->msgtql, &target_msginfo->msgtql);
        !          1973:     __put_user(host_msginfo->msgseg, &target_msginfo->msgseg);
        !          1974:     unlock_user_struct(target_msginfo, target_addr, 1);
        !          1975:     return 0;
        !          1976: }
        !          1977: 
        !          1978: static inline abi_long do_msgctl(int msgid, int cmd, abi_long ptr)
1.1.1.6   root     1979: {
                   1980:     struct msqid_ds dsarg;
1.1.1.7 ! root     1981:     struct msginfo msginfo;
        !          1982:     abi_long ret = -TARGET_EINVAL;
        !          1983: 
        !          1984:     cmd &= 0xff;
        !          1985: 
        !          1986:     switch (cmd) {
1.1.1.6   root     1987:     case IPC_STAT:
                   1988:     case IPC_SET:
1.1.1.7 ! root     1989:     case MSG_STAT:
        !          1990:         if (target_to_host_msqid_ds(&dsarg,ptr))
        !          1991:             return -TARGET_EFAULT;
        !          1992:         ret = get_errno(msgctl(msgid, cmd, &dsarg));
        !          1993:         if (host_to_target_msqid_ds(ptr,&dsarg))
        !          1994:             return -TARGET_EFAULT;
        !          1995:         break;
        !          1996:     case IPC_RMID:
        !          1997:         ret = get_errno(msgctl(msgid, cmd, NULL));
        !          1998:         break;
        !          1999:     case IPC_INFO:
        !          2000:     case MSG_INFO:
        !          2001:         ret = get_errno(msgctl(msgid, cmd, (struct msqid_ds *)&msginfo));
        !          2002:         if (host_to_target_msginfo(ptr, &msginfo))
        !          2003:             return -TARGET_EFAULT;
        !          2004:         break;
1.1.1.6   root     2005:     }
1.1.1.7 ! root     2006: 
1.1.1.6   root     2007:     return ret;
                   2008: }
                   2009: 
                   2010: struct target_msgbuf {
1.1.1.7 ! root     2011:     abi_long mtype;
        !          2012:     char       mtext[1];
1.1.1.6   root     2013: };
                   2014: 
                   2015: static inline abi_long do_msgsnd(int msqid, abi_long msgp,
                   2016:                                  unsigned int msgsz, int msgflg)
                   2017: {
                   2018:     struct target_msgbuf *target_mb;
                   2019:     struct msgbuf *host_mb;
                   2020:     abi_long ret = 0;
                   2021: 
                   2022:     if (!lock_user_struct(VERIFY_READ, target_mb, msgp, 0))
                   2023:         return -TARGET_EFAULT;
                   2024:     host_mb = malloc(msgsz+sizeof(long));
1.1.1.7 ! root     2025:     host_mb->mtype = (abi_long) tswapl(target_mb->mtype);
        !          2026:     memcpy(host_mb->mtext, target_mb->mtext, msgsz);
1.1.1.6   root     2027:     ret = get_errno(msgsnd(msqid, host_mb, msgsz, msgflg));
                   2028:     free(host_mb);
                   2029:     unlock_user_struct(target_mb, msgp, 0);
                   2030: 
                   2031:     return ret;
                   2032: }
                   2033: 
                   2034: static inline abi_long do_msgrcv(int msqid, abi_long msgp,
1.1.1.7 ! root     2035:                                  unsigned int msgsz, abi_long msgtyp,
1.1.1.6   root     2036:                                  int msgflg)
                   2037: {
                   2038:     struct target_msgbuf *target_mb;
                   2039:     char *target_mtext;
                   2040:     struct msgbuf *host_mb;
                   2041:     abi_long ret = 0;
                   2042: 
                   2043:     if (!lock_user_struct(VERIFY_WRITE, target_mb, msgp, 0))
                   2044:         return -TARGET_EFAULT;
1.1.1.7 ! root     2045: 
1.1.1.6   root     2046:     host_mb = malloc(msgsz+sizeof(long));
1.1.1.7 ! root     2047:     ret = get_errno(msgrcv(msqid, host_mb, msgsz, tswapl(msgtyp), msgflg));
        !          2048: 
1.1.1.6   root     2049:     if (ret > 0) {
                   2050:         abi_ulong target_mtext_addr = msgp + sizeof(abi_ulong);
                   2051:         target_mtext = lock_user(VERIFY_WRITE, target_mtext_addr, ret, 0);
                   2052:         if (!target_mtext) {
                   2053:             ret = -TARGET_EFAULT;
                   2054:             goto end;
                   2055:         }
1.1.1.7 ! root     2056:         memcpy(target_mb->mtext, host_mb->mtext, ret);
1.1.1.6   root     2057:         unlock_user(target_mtext, target_mtext_addr, ret);
                   2058:     }
1.1.1.7 ! root     2059: 
1.1.1.6   root     2060:     target_mb->mtype = tswapl(host_mb->mtype);
                   2061:     free(host_mb);
                   2062: 
                   2063: end:
                   2064:     if (target_mb)
                   2065:         unlock_user_struct(target_mb, msgp, 1);
                   2066:     return ret;
                   2067: }
                   2068: 
1.1.1.7 ! root     2069: #ifdef TARGET_NR_ipc
1.1.1.3   root     2070: /* ??? This only works with linear mappings.  */
1.1.1.6   root     2071: /* do_ipc() must return target values and target errnos. */
                   2072: static abi_long do_ipc(unsigned int call, int first,
                   2073:                        int second, int third,
                   2074:                        abi_long ptr, abi_long fifth)
1.1       root     2075: {
                   2076:     int version;
1.1.1.6   root     2077:     abi_long ret = 0;
1.1       root     2078:     struct shmid_ds shm_info;
                   2079:     int i;
                   2080: 
                   2081:     version = call >> 16;
                   2082:     call &= 0xffff;
                   2083: 
                   2084:     switch (call) {
1.1.1.5   root     2085:     case IPCOP_semop:
1.1.1.6   root     2086:         ret = get_errno(semop(first,(struct sembuf *)g2h(ptr), second));
1.1.1.5   root     2087:         break;
                   2088: 
                   2089:     case IPCOP_semget:
                   2090:         ret = get_errno(semget(first, second, third));
                   2091:         break;
                   2092: 
                   2093:     case IPCOP_semctl:
1.1.1.6   root     2094:         ret = do_semctl(first, second, third, ptr);
1.1.1.5   root     2095:         break;
                   2096: 
                   2097:     case IPCOP_semtimedop:
1.1.1.6   root     2098:         gemu_log("Unsupported ipc call: %d (version %d)\n", call, version);
                   2099:         ret = -TARGET_ENOSYS;
1.1.1.5   root     2100:         break;
                   2101: 
1.1.1.7 ! root     2102:     case IPCOP_msgget:
        !          2103:         ret = get_errno(msgget(first, second));
        !          2104:         break;
1.1.1.5   root     2105: 
1.1.1.7 ! root     2106:     case IPCOP_msgsnd:
        !          2107:         ret = do_msgsnd(first, ptr, second, third);
        !          2108:         break;
1.1.1.5   root     2109: 
1.1.1.7 ! root     2110:     case IPCOP_msgctl:
        !          2111:         ret = do_msgctl(first, second, ptr);
        !          2112:         break;
1.1.1.5   root     2113: 
1.1.1.7 ! root     2114:     case IPCOP_msgrcv:
        !          2115:         switch (version) {
        !          2116:         case 0:
        !          2117:             {
        !          2118:                 struct target_ipc_kludge {
        !          2119:                     abi_long msgp;
        !          2120:                     abi_long msgtyp;
        !          2121:                 } *tmp;
1.1.1.5   root     2122: 
1.1.1.7 ! root     2123:                 if (!lock_user_struct(VERIFY_READ, tmp, ptr, 1)) {
        !          2124:                     ret = -TARGET_EFAULT;
        !          2125:                     break;
        !          2126:                 }
1.1.1.5   root     2127: 
1.1.1.7 ! root     2128:                 ret = do_msgrcv(first, tmp->msgp, second, tmp->msgtyp, third);
1.1.1.5   root     2129: 
1.1.1.7 ! root     2130:                 unlock_user_struct(tmp, ptr, 0);
        !          2131:                 break;
        !          2132:             }
        !          2133:         default:
        !          2134:             ret = do_msgrcv(first, ptr, second, fifth, third);
        !          2135:         }
        !          2136:         break;
1.1.1.5   root     2137: 
1.1       root     2138:     case IPCOP_shmat:
1.1.1.6   root     2139:         {
                   2140:             abi_ulong raddr;
                   2141:             void *host_addr;
                   2142:             /* SHM_* flags are the same on all linux platforms */
                   2143:             host_addr = shmat(first, (void *)g2h(ptr), second);
                   2144:             if (host_addr == (void *)-1) {
                   2145:                 ret = get_errno((long)host_addr);
1.1       root     2146:                 break;
1.1.1.6   root     2147:             }
                   2148:             raddr = h2g((unsigned long)host_addr);
                   2149:             /* find out the length of the shared memory segment */
                   2150:             
                   2151:             ret = get_errno(shmctl(first, IPC_STAT, &shm_info));
                   2152:             if (is_error(ret)) {
                   2153:                 /* can't get length, bail out */
                   2154:                 shmdt(host_addr);
                   2155:                 break;
                   2156:             }
                   2157:             page_set_flags(raddr, raddr + shm_info.shm_segsz,
                   2158:                            PAGE_VALID | PAGE_READ |
                   2159:                            ((second & SHM_RDONLY)? 0: PAGE_WRITE));
                   2160:             for (i = 0; i < N_SHM_REGIONS; ++i) {
                   2161:                 if (shm_regions[i].start == 0) {
                   2162:                     shm_regions[i].start = raddr;
                   2163:                     shm_regions[i].size = shm_info.shm_segsz;
                   2164:                     break;
                   2165:                 }
                   2166:             }
                   2167:             if (put_user_ual(raddr, third))
                   2168:                 return -TARGET_EFAULT;
                   2169:             ret = 0;
                   2170:         }
1.1       root     2171:        break;
                   2172:     case IPCOP_shmdt:
                   2173:        for (i = 0; i < N_SHM_REGIONS; ++i) {
                   2174:            if (shm_regions[i].start == ptr) {
                   2175:                shm_regions[i].start = 0;
                   2176:                page_set_flags(ptr, shm_regions[i].size, 0);
                   2177:                break;
                   2178:            }
                   2179:        }
1.1.1.6   root     2180:        ret = get_errno(shmdt((void *)g2h(ptr)));
1.1       root     2181:        break;
                   2182: 
                   2183:     case IPCOP_shmget:
                   2184:        /* IPC_* flag values are the same on all linux platforms */
                   2185:        ret = get_errno(shmget(first, second, third));
                   2186:        break;
                   2187: 
                   2188:        /* IPC_* and SHM_* command values are the same on all linux platforms */
                   2189:     case IPCOP_shmctl:
                   2190:         switch(second) {
                   2191:         case IPC_RMID:
                   2192:         case SHM_LOCK:
                   2193:         case SHM_UNLOCK:
                   2194:             ret = get_errno(shmctl(first, second, NULL));
                   2195:             break;
                   2196:         default:
                   2197:             goto unimplemented;
                   2198:         }
                   2199:         break;
                   2200:     default:
                   2201:     unimplemented:
1.1.1.6   root     2202:        gemu_log("Unsupported ipc call: %d (version %d)\n", call, version);
                   2203:        ret = -TARGET_ENOSYS;
1.1       root     2204:        break;
                   2205:     }
                   2206:     return ret;
                   2207: }
1.1.1.6   root     2208: #endif
1.1       root     2209: 
                   2210: /* kernel structure types definitions */
                   2211: #define IFNAMSIZ        16
                   2212: 
                   2213: #define STRUCT(name, list...) STRUCT_ ## name,
                   2214: #define STRUCT_SPECIAL(name) STRUCT_ ## name,
                   2215: enum {
                   2216: #include "syscall_types.h"
                   2217: };
                   2218: #undef STRUCT
                   2219: #undef STRUCT_SPECIAL
                   2220: 
1.1.1.7 ! root     2221: #define STRUCT(name, list...) static const argtype struct_ ## name ## _def[] = { list, TYPE_NULL };
1.1       root     2222: #define STRUCT_SPECIAL(name)
                   2223: #include "syscall_types.h"
                   2224: #undef STRUCT
                   2225: #undef STRUCT_SPECIAL
                   2226: 
                   2227: typedef struct IOCTLEntry {
                   2228:     unsigned int target_cmd;
                   2229:     unsigned int host_cmd;
                   2230:     const char *name;
                   2231:     int access;
                   2232:     const argtype arg_type[5];
                   2233: } IOCTLEntry;
                   2234: 
                   2235: #define IOC_R 0x0001
                   2236: #define IOC_W 0x0002
                   2237: #define IOC_RW (IOC_R | IOC_W)
                   2238: 
                   2239: #define MAX_STRUCT_SIZE 4096
                   2240: 
1.1.1.7 ! root     2241: static IOCTLEntry ioctl_entries[] = {
1.1       root     2242: #define IOCTL(cmd, access, types...) \
                   2243:     { TARGET_ ## cmd, cmd, #cmd, access, { types } },
                   2244: #include "ioctls.h"
                   2245:     { 0, 0, },
                   2246: };
                   2247: 
1.1.1.3   root     2248: /* ??? Implement proper locking for ioctls.  */
1.1.1.6   root     2249: /* do_ioctl() Must return target values and target errnos. */
                   2250: static abi_long do_ioctl(int fd, abi_long cmd, abi_long arg)
1.1       root     2251: {
                   2252:     const IOCTLEntry *ie;
                   2253:     const argtype *arg_type;
1.1.1.6   root     2254:     abi_long ret;
1.1       root     2255:     uint8_t buf_temp[MAX_STRUCT_SIZE];
1.1.1.3   root     2256:     int target_size;
                   2257:     void *argptr;
1.1       root     2258: 
                   2259:     ie = ioctl_entries;
                   2260:     for(;;) {
                   2261:         if (ie->target_cmd == 0) {
1.1.1.6   root     2262:             gemu_log("Unsupported ioctl: cmd=0x%04lx\n", (long)cmd);
                   2263:             return -TARGET_ENOSYS;
1.1       root     2264:         }
                   2265:         if (ie->target_cmd == cmd)
                   2266:             break;
                   2267:         ie++;
                   2268:     }
                   2269:     arg_type = ie->arg_type;
                   2270: #if defined(DEBUG)
1.1.1.6   root     2271:     gemu_log("ioctl: cmd=0x%04lx (%s)\n", (long)cmd, ie->name);
1.1       root     2272: #endif
                   2273:     switch(arg_type[0]) {
                   2274:     case TYPE_NULL:
                   2275:         /* no argument */
                   2276:         ret = get_errno(ioctl(fd, ie->host_cmd));
                   2277:         break;
                   2278:     case TYPE_PTRVOID:
                   2279:     case TYPE_INT:
                   2280:         /* int argment */
                   2281:         ret = get_errno(ioctl(fd, ie->host_cmd, arg));
                   2282:         break;
                   2283:     case TYPE_PTR:
                   2284:         arg_type++;
1.1.1.3   root     2285:         target_size = thunk_type_size(arg_type, 0);
1.1       root     2286:         switch(ie->access) {
                   2287:         case IOC_R:
                   2288:             ret = get_errno(ioctl(fd, ie->host_cmd, buf_temp));
                   2289:             if (!is_error(ret)) {
1.1.1.6   root     2290:                 argptr = lock_user(VERIFY_WRITE, arg, target_size, 0);
                   2291:                 if (!argptr)
                   2292:                     return -TARGET_EFAULT;
1.1.1.3   root     2293:                 thunk_convert(argptr, buf_temp, arg_type, THUNK_TARGET);
                   2294:                 unlock_user(argptr, arg, target_size);
1.1       root     2295:             }
                   2296:             break;
                   2297:         case IOC_W:
1.1.1.6   root     2298:             argptr = lock_user(VERIFY_READ, arg, target_size, 1);
                   2299:             if (!argptr)
                   2300:                 return -TARGET_EFAULT;
1.1.1.3   root     2301:             thunk_convert(buf_temp, argptr, arg_type, THUNK_HOST);
                   2302:             unlock_user(argptr, arg, 0);
1.1       root     2303:             ret = get_errno(ioctl(fd, ie->host_cmd, buf_temp));
                   2304:             break;
                   2305:         default:
                   2306:         case IOC_RW:
1.1.1.6   root     2307:             argptr = lock_user(VERIFY_READ, arg, target_size, 1);
                   2308:             if (!argptr)
                   2309:                 return -TARGET_EFAULT;
1.1.1.3   root     2310:             thunk_convert(buf_temp, argptr, arg_type, THUNK_HOST);
                   2311:             unlock_user(argptr, arg, 0);
1.1       root     2312:             ret = get_errno(ioctl(fd, ie->host_cmd, buf_temp));
                   2313:             if (!is_error(ret)) {
1.1.1.6   root     2314:                 argptr = lock_user(VERIFY_WRITE, arg, target_size, 0);
                   2315:                 if (!argptr)
                   2316:                     return -TARGET_EFAULT;
1.1.1.3   root     2317:                 thunk_convert(argptr, buf_temp, arg_type, THUNK_TARGET);
                   2318:                 unlock_user(argptr, arg, target_size);
1.1       root     2319:             }
                   2320:             break;
                   2321:         }
                   2322:         break;
                   2323:     default:
1.1.1.6   root     2324:         gemu_log("Unsupported ioctl type: cmd=0x%04lx type=%d\n",
                   2325:                  (long)cmd, arg_type[0]);
                   2326:         ret = -TARGET_ENOSYS;
1.1       root     2327:         break;
                   2328:     }
                   2329:     return ret;
                   2330: }
                   2331: 
1.1.1.7 ! root     2332: static const bitmask_transtbl iflag_tbl[] = {
1.1       root     2333:         { TARGET_IGNBRK, TARGET_IGNBRK, IGNBRK, IGNBRK },
                   2334:         { TARGET_BRKINT, TARGET_BRKINT, BRKINT, BRKINT },
                   2335:         { TARGET_IGNPAR, TARGET_IGNPAR, IGNPAR, IGNPAR },
                   2336:         { TARGET_PARMRK, TARGET_PARMRK, PARMRK, PARMRK },
                   2337:         { TARGET_INPCK, TARGET_INPCK, INPCK, INPCK },
                   2338:         { TARGET_ISTRIP, TARGET_ISTRIP, ISTRIP, ISTRIP },
                   2339:         { TARGET_INLCR, TARGET_INLCR, INLCR, INLCR },
                   2340:         { TARGET_IGNCR, TARGET_IGNCR, IGNCR, IGNCR },
                   2341:         { TARGET_ICRNL, TARGET_ICRNL, ICRNL, ICRNL },
                   2342:         { TARGET_IUCLC, TARGET_IUCLC, IUCLC, IUCLC },
                   2343:         { TARGET_IXON, TARGET_IXON, IXON, IXON },
                   2344:         { TARGET_IXANY, TARGET_IXANY, IXANY, IXANY },
                   2345:         { TARGET_IXOFF, TARGET_IXOFF, IXOFF, IXOFF },
                   2346:         { TARGET_IMAXBEL, TARGET_IMAXBEL, IMAXBEL, IMAXBEL },
                   2347:         { 0, 0, 0, 0 }
                   2348: };
                   2349: 
1.1.1.7 ! root     2350: static const bitmask_transtbl oflag_tbl[] = {
1.1       root     2351:        { TARGET_OPOST, TARGET_OPOST, OPOST, OPOST },
                   2352:        { TARGET_OLCUC, TARGET_OLCUC, OLCUC, OLCUC },
                   2353:        { TARGET_ONLCR, TARGET_ONLCR, ONLCR, ONLCR },
                   2354:        { TARGET_OCRNL, TARGET_OCRNL, OCRNL, OCRNL },
                   2355:        { TARGET_ONOCR, TARGET_ONOCR, ONOCR, ONOCR },
                   2356:        { TARGET_ONLRET, TARGET_ONLRET, ONLRET, ONLRET },
                   2357:        { TARGET_OFILL, TARGET_OFILL, OFILL, OFILL },
                   2358:        { TARGET_OFDEL, TARGET_OFDEL, OFDEL, OFDEL },
                   2359:        { TARGET_NLDLY, TARGET_NL0, NLDLY, NL0 },
                   2360:        { TARGET_NLDLY, TARGET_NL1, NLDLY, NL1 },
                   2361:        { TARGET_CRDLY, TARGET_CR0, CRDLY, CR0 },
                   2362:        { TARGET_CRDLY, TARGET_CR1, CRDLY, CR1 },
                   2363:        { TARGET_CRDLY, TARGET_CR2, CRDLY, CR2 },
                   2364:        { TARGET_CRDLY, TARGET_CR3, CRDLY, CR3 },
                   2365:        { TARGET_TABDLY, TARGET_TAB0, TABDLY, TAB0 },
                   2366:        { TARGET_TABDLY, TARGET_TAB1, TABDLY, TAB1 },
                   2367:        { TARGET_TABDLY, TARGET_TAB2, TABDLY, TAB2 },
                   2368:        { TARGET_TABDLY, TARGET_TAB3, TABDLY, TAB3 },
                   2369:        { TARGET_BSDLY, TARGET_BS0, BSDLY, BS0 },
                   2370:        { TARGET_BSDLY, TARGET_BS1, BSDLY, BS1 },
                   2371:        { TARGET_VTDLY, TARGET_VT0, VTDLY, VT0 },
                   2372:        { TARGET_VTDLY, TARGET_VT1, VTDLY, VT1 },
                   2373:        { TARGET_FFDLY, TARGET_FF0, FFDLY, FF0 },
                   2374:        { TARGET_FFDLY, TARGET_FF1, FFDLY, FF1 },
                   2375:        { 0, 0, 0, 0 }
                   2376: };
                   2377: 
1.1.1.7 ! root     2378: static const bitmask_transtbl cflag_tbl[] = {
1.1       root     2379:        { TARGET_CBAUD, TARGET_B0, CBAUD, B0 },
                   2380:        { TARGET_CBAUD, TARGET_B50, CBAUD, B50 },
                   2381:        { TARGET_CBAUD, TARGET_B75, CBAUD, B75 },
                   2382:        { TARGET_CBAUD, TARGET_B110, CBAUD, B110 },
                   2383:        { TARGET_CBAUD, TARGET_B134, CBAUD, B134 },
                   2384:        { TARGET_CBAUD, TARGET_B150, CBAUD, B150 },
                   2385:        { TARGET_CBAUD, TARGET_B200, CBAUD, B200 },
                   2386:        { TARGET_CBAUD, TARGET_B300, CBAUD, B300 },
                   2387:        { TARGET_CBAUD, TARGET_B600, CBAUD, B600 },
                   2388:        { TARGET_CBAUD, TARGET_B1200, CBAUD, B1200 },
                   2389:        { TARGET_CBAUD, TARGET_B1800, CBAUD, B1800 },
                   2390:        { TARGET_CBAUD, TARGET_B2400, CBAUD, B2400 },
                   2391:        { TARGET_CBAUD, TARGET_B4800, CBAUD, B4800 },
                   2392:        { TARGET_CBAUD, TARGET_B9600, CBAUD, B9600 },
                   2393:        { TARGET_CBAUD, TARGET_B19200, CBAUD, B19200 },
                   2394:        { TARGET_CBAUD, TARGET_B38400, CBAUD, B38400 },
                   2395:        { TARGET_CBAUD, TARGET_B57600, CBAUD, B57600 },
                   2396:        { TARGET_CBAUD, TARGET_B115200, CBAUD, B115200 },
                   2397:        { TARGET_CBAUD, TARGET_B230400, CBAUD, B230400 },
                   2398:        { TARGET_CBAUD, TARGET_B460800, CBAUD, B460800 },
                   2399:        { TARGET_CSIZE, TARGET_CS5, CSIZE, CS5 },
                   2400:        { TARGET_CSIZE, TARGET_CS6, CSIZE, CS6 },
                   2401:        { TARGET_CSIZE, TARGET_CS7, CSIZE, CS7 },
                   2402:        { TARGET_CSIZE, TARGET_CS8, CSIZE, CS8 },
                   2403:        { TARGET_CSTOPB, TARGET_CSTOPB, CSTOPB, CSTOPB },
                   2404:        { TARGET_CREAD, TARGET_CREAD, CREAD, CREAD },
                   2405:        { TARGET_PARENB, TARGET_PARENB, PARENB, PARENB },
                   2406:        { TARGET_PARODD, TARGET_PARODD, PARODD, PARODD },
                   2407:        { TARGET_HUPCL, TARGET_HUPCL, HUPCL, HUPCL },
                   2408:        { TARGET_CLOCAL, TARGET_CLOCAL, CLOCAL, CLOCAL },
                   2409:        { TARGET_CRTSCTS, TARGET_CRTSCTS, CRTSCTS, CRTSCTS },
                   2410:        { 0, 0, 0, 0 }
                   2411: };
                   2412: 
1.1.1.7 ! root     2413: static const bitmask_transtbl lflag_tbl[] = {
1.1       root     2414:        { TARGET_ISIG, TARGET_ISIG, ISIG, ISIG },
                   2415:        { TARGET_ICANON, TARGET_ICANON, ICANON, ICANON },
                   2416:        { TARGET_XCASE, TARGET_XCASE, XCASE, XCASE },
                   2417:        { TARGET_ECHO, TARGET_ECHO, ECHO, ECHO },
                   2418:        { TARGET_ECHOE, TARGET_ECHOE, ECHOE, ECHOE },
                   2419:        { TARGET_ECHOK, TARGET_ECHOK, ECHOK, ECHOK },
                   2420:        { TARGET_ECHONL, TARGET_ECHONL, ECHONL, ECHONL },
                   2421:        { TARGET_NOFLSH, TARGET_NOFLSH, NOFLSH, NOFLSH },
                   2422:        { TARGET_TOSTOP, TARGET_TOSTOP, TOSTOP, TOSTOP },
                   2423:        { TARGET_ECHOCTL, TARGET_ECHOCTL, ECHOCTL, ECHOCTL },
                   2424:        { TARGET_ECHOPRT, TARGET_ECHOPRT, ECHOPRT, ECHOPRT },
                   2425:        { TARGET_ECHOKE, TARGET_ECHOKE, ECHOKE, ECHOKE },
                   2426:        { TARGET_FLUSHO, TARGET_FLUSHO, FLUSHO, FLUSHO },
                   2427:        { TARGET_PENDIN, TARGET_PENDIN, PENDIN, PENDIN },
                   2428:        { TARGET_IEXTEN, TARGET_IEXTEN, IEXTEN, IEXTEN },
                   2429:        { 0, 0, 0, 0 }
                   2430: };
                   2431: 
                   2432: static void target_to_host_termios (void *dst, const void *src)
                   2433: {
                   2434:     struct host_termios *host = dst;
                   2435:     const struct target_termios *target = src;
1.1.1.6   root     2436: 
                   2437:     host->c_iflag =
1.1       root     2438:         target_to_host_bitmask(tswap32(target->c_iflag), iflag_tbl);
1.1.1.6   root     2439:     host->c_oflag =
1.1       root     2440:         target_to_host_bitmask(tswap32(target->c_oflag), oflag_tbl);
1.1.1.6   root     2441:     host->c_cflag =
1.1       root     2442:         target_to_host_bitmask(tswap32(target->c_cflag), cflag_tbl);
1.1.1.6   root     2443:     host->c_lflag =
1.1       root     2444:         target_to_host_bitmask(tswap32(target->c_lflag), lflag_tbl);
                   2445:     host->c_line = target->c_line;
1.1.1.6   root     2446: 
                   2447:     host->c_cc[VINTR] = target->c_cc[TARGET_VINTR];
                   2448:     host->c_cc[VQUIT] = target->c_cc[TARGET_VQUIT];
                   2449:     host->c_cc[VERASE] = target->c_cc[TARGET_VERASE];
                   2450:     host->c_cc[VKILL] = target->c_cc[TARGET_VKILL];
                   2451:     host->c_cc[VEOF] = target->c_cc[TARGET_VEOF];
                   2452:     host->c_cc[VTIME] = target->c_cc[TARGET_VTIME];
                   2453:     host->c_cc[VMIN] = target->c_cc[TARGET_VMIN];
                   2454:     host->c_cc[VSWTC] = target->c_cc[TARGET_VSWTC];
                   2455:     host->c_cc[VSTART] = target->c_cc[TARGET_VSTART];
                   2456:     host->c_cc[VSTOP] = target->c_cc[TARGET_VSTOP];
                   2457:     host->c_cc[VSUSP] = target->c_cc[TARGET_VSUSP];
                   2458:     host->c_cc[VEOL] = target->c_cc[TARGET_VEOL];
                   2459:     host->c_cc[VREPRINT] = target->c_cc[TARGET_VREPRINT];
                   2460:     host->c_cc[VDISCARD] = target->c_cc[TARGET_VDISCARD];
                   2461:     host->c_cc[VWERASE] = target->c_cc[TARGET_VWERASE];
                   2462:     host->c_cc[VLNEXT] = target->c_cc[TARGET_VLNEXT];
                   2463:     host->c_cc[VEOL2] = target->c_cc[TARGET_VEOL2];
1.1       root     2464: }
1.1.1.6   root     2465: 
1.1       root     2466: static void host_to_target_termios (void *dst, const void *src)
                   2467: {
                   2468:     struct target_termios *target = dst;
                   2469:     const struct host_termios *host = src;
                   2470: 
1.1.1.6   root     2471:     target->c_iflag =
1.1       root     2472:         tswap32(host_to_target_bitmask(host->c_iflag, iflag_tbl));
1.1.1.6   root     2473:     target->c_oflag =
1.1       root     2474:         tswap32(host_to_target_bitmask(host->c_oflag, oflag_tbl));
1.1.1.6   root     2475:     target->c_cflag =
1.1       root     2476:         tswap32(host_to_target_bitmask(host->c_cflag, cflag_tbl));
1.1.1.6   root     2477:     target->c_lflag =
1.1       root     2478:         tswap32(host_to_target_bitmask(host->c_lflag, lflag_tbl));
                   2479:     target->c_line = host->c_line;
1.1.1.6   root     2480: 
1.1       root     2481:     target->c_cc[TARGET_VINTR] = host->c_cc[VINTR];
                   2482:     target->c_cc[TARGET_VQUIT] = host->c_cc[VQUIT];
                   2483:     target->c_cc[TARGET_VERASE] = host->c_cc[VERASE];
                   2484:     target->c_cc[TARGET_VKILL] = host->c_cc[VKILL];
                   2485:     target->c_cc[TARGET_VEOF] = host->c_cc[VEOF];
                   2486:     target->c_cc[TARGET_VTIME] = host->c_cc[VTIME];
                   2487:     target->c_cc[TARGET_VMIN] = host->c_cc[VMIN];
                   2488:     target->c_cc[TARGET_VSWTC] = host->c_cc[VSWTC];
                   2489:     target->c_cc[TARGET_VSTART] = host->c_cc[VSTART];
                   2490:     target->c_cc[TARGET_VSTOP] = host->c_cc[VSTOP];
                   2491:     target->c_cc[TARGET_VSUSP] = host->c_cc[VSUSP];
                   2492:     target->c_cc[TARGET_VEOL] = host->c_cc[VEOL];
                   2493:     target->c_cc[TARGET_VREPRINT] = host->c_cc[VREPRINT];
                   2494:     target->c_cc[TARGET_VDISCARD] = host->c_cc[VDISCARD];
                   2495:     target->c_cc[TARGET_VWERASE] = host->c_cc[VWERASE];
                   2496:     target->c_cc[TARGET_VLNEXT] = host->c_cc[VLNEXT];
                   2497:     target->c_cc[TARGET_VEOL2] = host->c_cc[VEOL2];
                   2498: }
                   2499: 
1.1.1.7 ! root     2500: static const StructEntry struct_termios_def = {
1.1       root     2501:     .convert = { host_to_target_termios, target_to_host_termios },
                   2502:     .size = { sizeof(struct target_termios), sizeof(struct host_termios) },
                   2503:     .align = { __alignof__(struct target_termios), __alignof__(struct host_termios) },
                   2504: };
                   2505: 
                   2506: static bitmask_transtbl mmap_flags_tbl[] = {
                   2507:        { TARGET_MAP_SHARED, TARGET_MAP_SHARED, MAP_SHARED, MAP_SHARED },
                   2508:        { TARGET_MAP_PRIVATE, TARGET_MAP_PRIVATE, MAP_PRIVATE, MAP_PRIVATE },
                   2509:        { TARGET_MAP_FIXED, TARGET_MAP_FIXED, MAP_FIXED, MAP_FIXED },
                   2510:        { TARGET_MAP_ANONYMOUS, TARGET_MAP_ANONYMOUS, MAP_ANONYMOUS, MAP_ANONYMOUS },
                   2511:        { TARGET_MAP_GROWSDOWN, TARGET_MAP_GROWSDOWN, MAP_GROWSDOWN, MAP_GROWSDOWN },
                   2512:        { TARGET_MAP_DENYWRITE, TARGET_MAP_DENYWRITE, MAP_DENYWRITE, MAP_DENYWRITE },
                   2513:        { TARGET_MAP_EXECUTABLE, TARGET_MAP_EXECUTABLE, MAP_EXECUTABLE, MAP_EXECUTABLE },
                   2514:        { TARGET_MAP_LOCKED, TARGET_MAP_LOCKED, MAP_LOCKED, MAP_LOCKED },
                   2515:        { 0, 0, 0, 0 }
                   2516: };
                   2517: 
                   2518: static bitmask_transtbl fcntl_flags_tbl[] = {
                   2519:        { TARGET_O_ACCMODE,   TARGET_O_WRONLY,    O_ACCMODE,   O_WRONLY,    },
                   2520:        { TARGET_O_ACCMODE,   TARGET_O_RDWR,      O_ACCMODE,   O_RDWR,      },
                   2521:        { TARGET_O_CREAT,     TARGET_O_CREAT,     O_CREAT,     O_CREAT,     },
                   2522:        { TARGET_O_EXCL,      TARGET_O_EXCL,      O_EXCL,      O_EXCL,      },
                   2523:        { TARGET_O_NOCTTY,    TARGET_O_NOCTTY,    O_NOCTTY,    O_NOCTTY,    },
                   2524:        { TARGET_O_TRUNC,     TARGET_O_TRUNC,     O_TRUNC,     O_TRUNC,     },
                   2525:        { TARGET_O_APPEND,    TARGET_O_APPEND,    O_APPEND,    O_APPEND,    },
                   2526:        { TARGET_O_NONBLOCK,  TARGET_O_NONBLOCK,  O_NONBLOCK,  O_NONBLOCK,  },
                   2527:        { TARGET_O_SYNC,      TARGET_O_SYNC,      O_SYNC,      O_SYNC,      },
                   2528:        { TARGET_FASYNC,      TARGET_FASYNC,      FASYNC,      FASYNC,      },
                   2529:        { TARGET_O_DIRECTORY, TARGET_O_DIRECTORY, O_DIRECTORY, O_DIRECTORY, },
                   2530:        { TARGET_O_NOFOLLOW,  TARGET_O_NOFOLLOW,  O_NOFOLLOW,  O_NOFOLLOW,  },
                   2531:        { TARGET_O_LARGEFILE, TARGET_O_LARGEFILE, O_LARGEFILE, O_LARGEFILE, },
                   2532: #if defined(O_DIRECT)
                   2533:        { TARGET_O_DIRECT,    TARGET_O_DIRECT,    O_DIRECT,    O_DIRECT,    },
                   2534: #endif
                   2535:        { 0, 0, 0, 0 }
                   2536: };
                   2537: 
                   2538: #if defined(TARGET_I386)
                   2539: 
                   2540: /* NOTE: there is really one LDT for all the threads */
1.1.1.7 ! root     2541: static uint8_t *ldt_table;
1.1       root     2542: 
1.1.1.6   root     2543: static abi_long read_ldt(abi_ulong ptr, unsigned long bytecount)
1.1       root     2544: {
                   2545:     int size;
1.1.1.3   root     2546:     void *p;
1.1       root     2547: 
                   2548:     if (!ldt_table)
                   2549:         return 0;
                   2550:     size = TARGET_LDT_ENTRIES * TARGET_LDT_ENTRY_SIZE;
                   2551:     if (size > bytecount)
                   2552:         size = bytecount;
1.1.1.6   root     2553:     p = lock_user(VERIFY_WRITE, ptr, size, 0);
                   2554:     if (!p)
                   2555:         return -TARGET_EFAULT;
                   2556:     /* ??? Should this by byteswapped?  */
1.1.1.3   root     2557:     memcpy(p, ldt_table, size);
                   2558:     unlock_user(p, ptr, size);
1.1       root     2559:     return size;
                   2560: }
                   2561: 
                   2562: /* XXX: add locking support */
1.1.1.6   root     2563: static abi_long write_ldt(CPUX86State *env,
                   2564:                           abi_ulong ptr, unsigned long bytecount, int oldmode)
1.1       root     2565: {
                   2566:     struct target_modify_ldt_ldt_s ldt_info;
1.1.1.3   root     2567:     struct target_modify_ldt_ldt_s *target_ldt_info;
1.1       root     2568:     int seg_32bit, contents, read_exec_only, limit_in_pages;
1.1.1.6   root     2569:     int seg_not_present, useable, lm;
1.1       root     2570:     uint32_t *lp, entry_1, entry_2;
                   2571: 
                   2572:     if (bytecount != sizeof(ldt_info))
1.1.1.6   root     2573:         return -TARGET_EINVAL;
                   2574:     if (!lock_user_struct(VERIFY_READ, target_ldt_info, ptr, 1))
                   2575:         return -TARGET_EFAULT;
1.1.1.3   root     2576:     ldt_info.entry_number = tswap32(target_ldt_info->entry_number);
                   2577:     ldt_info.base_addr = tswapl(target_ldt_info->base_addr);
                   2578:     ldt_info.limit = tswap32(target_ldt_info->limit);
                   2579:     ldt_info.flags = tswap32(target_ldt_info->flags);
                   2580:     unlock_user_struct(target_ldt_info, ptr, 0);
1.1.1.6   root     2581: 
1.1       root     2582:     if (ldt_info.entry_number >= TARGET_LDT_ENTRIES)
1.1.1.6   root     2583:         return -TARGET_EINVAL;
1.1       root     2584:     seg_32bit = ldt_info.flags & 1;
                   2585:     contents = (ldt_info.flags >> 1) & 3;
                   2586:     read_exec_only = (ldt_info.flags >> 3) & 1;
                   2587:     limit_in_pages = (ldt_info.flags >> 4) & 1;
                   2588:     seg_not_present = (ldt_info.flags >> 5) & 1;
                   2589:     useable = (ldt_info.flags >> 6) & 1;
1.1.1.6   root     2590: #ifdef TARGET_ABI32
                   2591:     lm = 0;
                   2592: #else
                   2593:     lm = (ldt_info.flags >> 7) & 1;
                   2594: #endif
1.1       root     2595:     if (contents == 3) {
                   2596:         if (oldmode)
1.1.1.6   root     2597:             return -TARGET_EINVAL;
1.1       root     2598:         if (seg_not_present == 0)
1.1.1.6   root     2599:             return -TARGET_EINVAL;
1.1       root     2600:     }
                   2601:     /* allocate the LDT */
                   2602:     if (!ldt_table) {
1.1.1.7 ! root     2603:         env->ldt.base = target_mmap(0,
        !          2604:                                     TARGET_LDT_ENTRIES * TARGET_LDT_ENTRY_SIZE,
        !          2605:                                     PROT_READ|PROT_WRITE,
        !          2606:                                     MAP_ANONYMOUS|MAP_PRIVATE, -1, 0);
        !          2607:         if (env->ldt.base == -1)
1.1.1.6   root     2608:             return -TARGET_ENOMEM;
1.1.1.7 ! root     2609:         memset(g2h(env->ldt.base), 0,
        !          2610:                TARGET_LDT_ENTRIES * TARGET_LDT_ENTRY_SIZE);
1.1       root     2611:         env->ldt.limit = 0xffff;
1.1.1.7 ! root     2612:         ldt_table = g2h(env->ldt.base);
1.1       root     2613:     }
                   2614: 
                   2615:     /* NOTE: same code as Linux kernel */
                   2616:     /* Allow LDTs to be cleared by the user. */
                   2617:     if (ldt_info.base_addr == 0 && ldt_info.limit == 0) {
                   2618:         if (oldmode ||
                   2619:             (contents == 0             &&
                   2620:              read_exec_only == 1       &&
                   2621:              seg_32bit == 0            &&
                   2622:              limit_in_pages == 0       &&
                   2623:              seg_not_present == 1      &&
                   2624:              useable == 0 )) {
                   2625:             entry_1 = 0;
                   2626:             entry_2 = 0;
                   2627:             goto install;
                   2628:         }
                   2629:     }
1.1.1.6   root     2630: 
1.1       root     2631:     entry_1 = ((ldt_info.base_addr & 0x0000ffff) << 16) |
                   2632:         (ldt_info.limit & 0x0ffff);
                   2633:     entry_2 = (ldt_info.base_addr & 0xff000000) |
                   2634:         ((ldt_info.base_addr & 0x00ff0000) >> 16) |
                   2635:         (ldt_info.limit & 0xf0000) |
                   2636:         ((read_exec_only ^ 1) << 9) |
                   2637:         (contents << 10) |
                   2638:         ((seg_not_present ^ 1) << 15) |
                   2639:         (seg_32bit << 22) |
                   2640:         (limit_in_pages << 23) |
1.1.1.6   root     2641:         (lm << 21) |
1.1       root     2642:         0x7000;
                   2643:     if (!oldmode)
                   2644:         entry_2 |= (useable << 20);
                   2645: 
                   2646:     /* Install the new entry ...  */
                   2647: install:
                   2648:     lp = (uint32_t *)(ldt_table + (ldt_info.entry_number << 3));
                   2649:     lp[0] = tswap32(entry_1);
                   2650:     lp[1] = tswap32(entry_2);
                   2651:     return 0;
                   2652: }
                   2653: 
                   2654: /* specific and weird i386 syscalls */
1.1.1.7 ! root     2655: static abi_long do_modify_ldt(CPUX86State *env, int func, abi_ulong ptr,
        !          2656:                               unsigned long bytecount)
1.1       root     2657: {
1.1.1.6   root     2658:     abi_long ret;
                   2659: 
1.1       root     2660:     switch (func) {
                   2661:     case 0:
                   2662:         ret = read_ldt(ptr, bytecount);
                   2663:         break;
                   2664:     case 1:
                   2665:         ret = write_ldt(env, ptr, bytecount, 1);
                   2666:         break;
                   2667:     case 0x11:
                   2668:         ret = write_ldt(env, ptr, bytecount, 0);
                   2669:         break;
1.1.1.6   root     2670:     default:
                   2671:         ret = -TARGET_ENOSYS;
                   2672:         break;
1.1       root     2673:     }
                   2674:     return ret;
                   2675: }
                   2676: 
1.1.1.7 ! root     2677: #if defined(TARGET_I386) && defined(TARGET_ABI32)
        !          2678: static abi_long do_set_thread_area(CPUX86State *env, abi_ulong ptr)
1.1.1.6   root     2679: {
                   2680:     uint64_t *gdt_table = g2h(env->gdt.base);
                   2681:     struct target_modify_ldt_ldt_s ldt_info;
                   2682:     struct target_modify_ldt_ldt_s *target_ldt_info;
                   2683:     int seg_32bit, contents, read_exec_only, limit_in_pages;
                   2684:     int seg_not_present, useable, lm;
                   2685:     uint32_t *lp, entry_1, entry_2;
                   2686:     int i;
                   2687: 
                   2688:     lock_user_struct(VERIFY_WRITE, target_ldt_info, ptr, 1);
                   2689:     if (!target_ldt_info)
                   2690:         return -TARGET_EFAULT;
                   2691:     ldt_info.entry_number = tswap32(target_ldt_info->entry_number);
                   2692:     ldt_info.base_addr = tswapl(target_ldt_info->base_addr);
                   2693:     ldt_info.limit = tswap32(target_ldt_info->limit);
                   2694:     ldt_info.flags = tswap32(target_ldt_info->flags);
                   2695:     if (ldt_info.entry_number == -1) {
                   2696:         for (i=TARGET_GDT_ENTRY_TLS_MIN; i<=TARGET_GDT_ENTRY_TLS_MAX; i++) {
                   2697:             if (gdt_table[i] == 0) {
                   2698:                 ldt_info.entry_number = i;
                   2699:                 target_ldt_info->entry_number = tswap32(i);
                   2700:                 break;
                   2701:             }
                   2702:         }
                   2703:     }
                   2704:     unlock_user_struct(target_ldt_info, ptr, 1);
                   2705: 
                   2706:     if (ldt_info.entry_number < TARGET_GDT_ENTRY_TLS_MIN || 
                   2707:         ldt_info.entry_number > TARGET_GDT_ENTRY_TLS_MAX)
                   2708:            return -TARGET_EINVAL;
                   2709:     seg_32bit = ldt_info.flags & 1;
                   2710:     contents = (ldt_info.flags >> 1) & 3;
                   2711:     read_exec_only = (ldt_info.flags >> 3) & 1;
                   2712:     limit_in_pages = (ldt_info.flags >> 4) & 1;
                   2713:     seg_not_present = (ldt_info.flags >> 5) & 1;
                   2714:     useable = (ldt_info.flags >> 6) & 1;
                   2715: #ifdef TARGET_ABI32
                   2716:     lm = 0;
                   2717: #else
                   2718:     lm = (ldt_info.flags >> 7) & 1;
                   2719: #endif
                   2720: 
                   2721:     if (contents == 3) {
                   2722:         if (seg_not_present == 0)
                   2723:             return -TARGET_EINVAL;
                   2724:     }
                   2725: 
                   2726:     /* NOTE: same code as Linux kernel */
                   2727:     /* Allow LDTs to be cleared by the user. */
                   2728:     if (ldt_info.base_addr == 0 && ldt_info.limit == 0) {
                   2729:         if ((contents == 0             &&
                   2730:              read_exec_only == 1       &&
                   2731:              seg_32bit == 0            &&
                   2732:              limit_in_pages == 0       &&
                   2733:              seg_not_present == 1      &&
                   2734:              useable == 0 )) {
                   2735:             entry_1 = 0;
                   2736:             entry_2 = 0;
                   2737:             goto install;
                   2738:         }
                   2739:     }
                   2740: 
                   2741:     entry_1 = ((ldt_info.base_addr & 0x0000ffff) << 16) |
                   2742:         (ldt_info.limit & 0x0ffff);
                   2743:     entry_2 = (ldt_info.base_addr & 0xff000000) |
                   2744:         ((ldt_info.base_addr & 0x00ff0000) >> 16) |
                   2745:         (ldt_info.limit & 0xf0000) |
                   2746:         ((read_exec_only ^ 1) << 9) |
                   2747:         (contents << 10) |
                   2748:         ((seg_not_present ^ 1) << 15) |
                   2749:         (seg_32bit << 22) |
                   2750:         (limit_in_pages << 23) |
                   2751:         (useable << 20) |
                   2752:         (lm << 21) |
                   2753:         0x7000;
                   2754: 
                   2755:     /* Install the new entry ...  */
                   2756: install:
                   2757:     lp = (uint32_t *)(gdt_table + ldt_info.entry_number);
                   2758:     lp[0] = tswap32(entry_1);
                   2759:     lp[1] = tswap32(entry_2);
                   2760:     return 0;
                   2761: }
                   2762: 
1.1.1.7 ! root     2763: static abi_long do_get_thread_area(CPUX86State *env, abi_ulong ptr)
1.1.1.6   root     2764: {
                   2765:     struct target_modify_ldt_ldt_s *target_ldt_info;
                   2766:     uint64_t *gdt_table = g2h(env->gdt.base);
                   2767:     uint32_t base_addr, limit, flags;
                   2768:     int seg_32bit, contents, read_exec_only, limit_in_pages, idx;
                   2769:     int seg_not_present, useable, lm;
                   2770:     uint32_t *lp, entry_1, entry_2;
                   2771: 
                   2772:     lock_user_struct(VERIFY_WRITE, target_ldt_info, ptr, 1);
                   2773:     if (!target_ldt_info)
                   2774:         return -TARGET_EFAULT;
                   2775:     idx = tswap32(target_ldt_info->entry_number);
                   2776:     if (idx < TARGET_GDT_ENTRY_TLS_MIN ||
                   2777:         idx > TARGET_GDT_ENTRY_TLS_MAX) {
                   2778:         unlock_user_struct(target_ldt_info, ptr, 1);
                   2779:         return -TARGET_EINVAL;
                   2780:     }
                   2781:     lp = (uint32_t *)(gdt_table + idx);
                   2782:     entry_1 = tswap32(lp[0]);
                   2783:     entry_2 = tswap32(lp[1]);
                   2784:     
                   2785:     read_exec_only = ((entry_2 >> 9) & 1) ^ 1;
                   2786:     contents = (entry_2 >> 10) & 3;
                   2787:     seg_not_present = ((entry_2 >> 15) & 1) ^ 1;
                   2788:     seg_32bit = (entry_2 >> 22) & 1;
                   2789:     limit_in_pages = (entry_2 >> 23) & 1;
                   2790:     useable = (entry_2 >> 20) & 1;
                   2791: #ifdef TARGET_ABI32
                   2792:     lm = 0;
                   2793: #else
                   2794:     lm = (entry_2 >> 21) & 1;
                   2795: #endif
                   2796:     flags = (seg_32bit << 0) | (contents << 1) |
                   2797:         (read_exec_only << 3) | (limit_in_pages << 4) |
                   2798:         (seg_not_present << 5) | (useable << 6) | (lm << 7);
                   2799:     limit = (entry_1 & 0xffff) | (entry_2  & 0xf0000);
                   2800:     base_addr = (entry_1 >> 16) | 
                   2801:         (entry_2 & 0xff000000) | 
                   2802:         ((entry_2 & 0xff) << 16);
                   2803:     target_ldt_info->base_addr = tswapl(base_addr);
                   2804:     target_ldt_info->limit = tswap32(limit);
                   2805:     target_ldt_info->flags = tswap32(flags);
                   2806:     unlock_user_struct(target_ldt_info, ptr, 1);
                   2807:     return 0;
                   2808: }
1.1.1.7 ! root     2809: #endif /* TARGET_I386 && TARGET_ABI32 */
1.1.1.6   root     2810: 
                   2811: #ifndef TARGET_ABI32
1.1.1.7 ! root     2812: static abi_long do_arch_prctl(CPUX86State *env, int code, abi_ulong addr)
1.1.1.6   root     2813: {
                   2814:     abi_long ret;
                   2815:     abi_ulong val;
                   2816:     int idx;
                   2817:     
                   2818:     switch(code) {
                   2819:     case TARGET_ARCH_SET_GS:
                   2820:     case TARGET_ARCH_SET_FS:
                   2821:         if (code == TARGET_ARCH_SET_GS)
                   2822:             idx = R_GS;
                   2823:         else
                   2824:             idx = R_FS;
                   2825:         cpu_x86_load_seg(env, idx, 0);
                   2826:         env->segs[idx].base = addr;
                   2827:         break;
                   2828:     case TARGET_ARCH_GET_GS:
                   2829:     case TARGET_ARCH_GET_FS:
                   2830:         if (code == TARGET_ARCH_GET_GS)
                   2831:             idx = R_GS;
                   2832:         else
                   2833:             idx = R_FS;
                   2834:         val = env->segs[idx].base;
                   2835:         if (put_user(val, addr, abi_ulong))
                   2836:             return -TARGET_EFAULT;
                   2837:         break;
                   2838:     default:
                   2839:         ret = -TARGET_EINVAL;
                   2840:         break;
                   2841:     }
                   2842:     return 0;
                   2843: }
                   2844: #endif
                   2845: 
1.1       root     2846: #endif /* defined(TARGET_I386) */
                   2847: 
1.1.1.7 ! root     2848: #if defined(USE_NPTL)
        !          2849: 
        !          2850: #define NEW_STACK_SIZE PTHREAD_STACK_MIN
        !          2851: 
        !          2852: static pthread_mutex_t clone_lock = PTHREAD_MUTEX_INITIALIZER;
        !          2853: typedef struct {
        !          2854:     CPUState *env;
        !          2855:     pthread_mutex_t mutex;
        !          2856:     pthread_cond_t cond;
        !          2857:     pthread_t thread;
        !          2858:     uint32_t tid;
        !          2859:     abi_ulong child_tidptr;
        !          2860:     abi_ulong parent_tidptr;
        !          2861:     sigset_t sigmask;
        !          2862: } new_thread_info;
        !          2863: 
        !          2864: static void *clone_func(void *arg)
        !          2865: {
        !          2866:     new_thread_info *info = arg;
        !          2867:     CPUState *env;
        !          2868: 
        !          2869:     env = info->env;
        !          2870:     thread_env = env;
        !          2871:     info->tid = gettid();
        !          2872:     if (info->child_tidptr)
        !          2873:         put_user_u32(info->tid, info->child_tidptr);
        !          2874:     if (info->parent_tidptr)
        !          2875:         put_user_u32(info->tid, info->parent_tidptr);
        !          2876:     /* Enable signals.  */
        !          2877:     sigprocmask(SIG_SETMASK, &info->sigmask, NULL);
        !          2878:     /* Signal to the parent that we're ready.  */
        !          2879:     pthread_mutex_lock(&info->mutex);
        !          2880:     pthread_cond_broadcast(&info->cond);
        !          2881:     pthread_mutex_unlock(&info->mutex);
        !          2882:     /* Wait until the parent has finshed initializing the tls state.  */
        !          2883:     pthread_mutex_lock(&clone_lock);
        !          2884:     pthread_mutex_unlock(&clone_lock);
        !          2885:     cpu_loop(env);
        !          2886:     /* never exits */
        !          2887:     return NULL;
        !          2888: }
        !          2889: #else
1.1       root     2890: /* this stack is the equivalent of the kernel stack associated with a
                   2891:    thread/process */
                   2892: #define NEW_STACK_SIZE 8192
                   2893: 
                   2894: static int clone_func(void *arg)
                   2895: {
                   2896:     CPUState *env = arg;
                   2897:     cpu_loop(env);
                   2898:     /* never exits */
                   2899:     return 0;
                   2900: }
1.1.1.7 ! root     2901: #endif
1.1       root     2902: 
1.1.1.6   root     2903: /* do_fork() Must return host values and target errnos (unlike most
                   2904:    do_*() functions). */
1.1.1.7 ! root     2905: static int do_fork(CPUState *env, unsigned int flags, abi_ulong newsp,
        !          2906:                    abi_ulong parent_tidptr, target_ulong newtls,
        !          2907:                    abi_ulong child_tidptr)
1.1       root     2908: {
                   2909:     int ret;
                   2910:     TaskState *ts;
                   2911:     uint8_t *new_stack;
                   2912:     CPUState *new_env;
1.1.1.7 ! root     2913: #if defined(USE_NPTL)
        !          2914:     unsigned int nptl_flags;
        !          2915:     sigset_t sigmask;
        !          2916: #endif
        !          2917: 
        !          2918:     /* Emulate vfork() with fork() */
        !          2919:     if (flags & CLONE_VFORK)
        !          2920:         flags &= ~(CLONE_VFORK | CLONE_VM);
1.1.1.6   root     2921: 
1.1       root     2922:     if (flags & CLONE_VM) {
1.1.1.7 ! root     2923: #if defined(USE_NPTL)
        !          2924:         new_thread_info info;
        !          2925:         pthread_attr_t attr;
        !          2926: #endif
        !          2927:         ts = qemu_mallocz(sizeof(TaskState) + NEW_STACK_SIZE);
        !          2928:         init_task_state(ts);
1.1       root     2929:         new_stack = ts->stack;
                   2930:         /* we create a new CPU instance. */
1.1.1.6   root     2931:         new_env = cpu_copy(env);
1.1.1.7 ! root     2932:         /* Init regs that differ from the parent.  */
        !          2933:         cpu_clone_regs(new_env, newsp);
        !          2934:         new_env->opaque = ts;
        !          2935: #if defined(USE_NPTL)
        !          2936:         nptl_flags = flags;
        !          2937:         flags &= ~CLONE_NPTL_FLAGS2;
        !          2938: 
        !          2939:         /* TODO: Implement CLONE_CHILD_CLEARTID.  */
        !          2940:         if (nptl_flags & CLONE_SETTLS)
        !          2941:             cpu_set_tls (new_env, newtls);
        !          2942: 
        !          2943:         /* Grab a mutex so that thread setup appears atomic.  */
        !          2944:         pthread_mutex_lock(&clone_lock);
        !          2945: 
        !          2946:         memset(&info, 0, sizeof(info));
        !          2947:         pthread_mutex_init(&info.mutex, NULL);
        !          2948:         pthread_mutex_lock(&info.mutex);
        !          2949:         pthread_cond_init(&info.cond, NULL);
        !          2950:         info.env = new_env;
        !          2951:         if (nptl_flags & CLONE_CHILD_SETTID)
        !          2952:             info.child_tidptr = child_tidptr;
        !          2953:         if (nptl_flags & CLONE_PARENT_SETTID)
        !          2954:             info.parent_tidptr = parent_tidptr;
        !          2955: 
        !          2956:         ret = pthread_attr_init(&attr);
        !          2957:         ret = pthread_attr_setstack(&attr, new_stack, NEW_STACK_SIZE);
        !          2958:         /* It is not safe to deliver signals until the child has finished
        !          2959:            initializing, so temporarily block all signals.  */
        !          2960:         sigfillset(&sigmask);
        !          2961:         sigprocmask(SIG_BLOCK, &sigmask, &info.sigmask);
        !          2962: 
        !          2963:         ret = pthread_create(&info.thread, &attr, clone_func, &info);
        !          2964: 
        !          2965:         sigprocmask(SIG_SETMASK, &info.sigmask, NULL);
        !          2966:         pthread_attr_destroy(&attr);
        !          2967:         if (ret == 0) {
        !          2968:             /* Wait for the child to initialize.  */
        !          2969:             pthread_cond_wait(&info.cond, &info.mutex);
        !          2970:             ret = info.tid;
        !          2971:             if (flags & CLONE_PARENT_SETTID)
        !          2972:                 put_user_u32(ret, parent_tidptr);
        !          2973:         } else {
        !          2974:             ret = -1;
1.1.1.6   root     2975:         }
1.1.1.7 ! root     2976:         pthread_mutex_unlock(&info.mutex);
        !          2977:         pthread_cond_destroy(&info.cond);
        !          2978:         pthread_mutex_destroy(&info.mutex);
        !          2979:         pthread_mutex_unlock(&clone_lock);
1.1       root     2980: #else
1.1.1.7 ! root     2981:         if (flags & CLONE_NPTL_FLAGS2)
        !          2982:             return -EINVAL;
        !          2983:         /* This is probably going to die very quickly, but do it anyway.  */
1.1       root     2984: #ifdef __ia64__
1.1.1.3   root     2985:         ret = __clone2(clone_func, new_stack + NEW_STACK_SIZE, flags, new_env);
1.1       root     2986: #else
                   2987:        ret = clone(clone_func, new_stack + NEW_STACK_SIZE, flags, new_env);
                   2988: #endif
1.1.1.7 ! root     2989: #endif
1.1       root     2990:     } else {
                   2991:         /* if no CLONE_VM, we consider it is a fork */
1.1.1.7 ! root     2992:         if ((flags & ~(CSIGNAL | CLONE_NPTL_FLAGS2)) != 0)
1.1       root     2993:             return -EINVAL;
1.1.1.7 ! root     2994:         fork_start();
1.1       root     2995:         ret = fork();
1.1.1.7 ! root     2996:         if (ret == 0) {
        !          2997:             /* Child Process.  */
        !          2998:             cpu_clone_regs(env, newsp);
        !          2999:             fork_end(1);
        !          3000: #if defined(USE_NPTL)
        !          3001:             /* There is a race condition here.  The parent process could
        !          3002:                theoretically read the TID in the child process before the child
        !          3003:                tid is set.  This would require using either ptrace
        !          3004:                (not implemented) or having *_tidptr to point at a shared memory
        !          3005:                mapping.  We can't repeat the spinlock hack used above because
        !          3006:                the child process gets its own copy of the lock.  */
        !          3007:             if (flags & CLONE_CHILD_SETTID)
        !          3008:                 put_user_u32(gettid(), child_tidptr);
        !          3009:             if (flags & CLONE_PARENT_SETTID)
        !          3010:                 put_user_u32(gettid(), parent_tidptr);
        !          3011:             ts = (TaskState *)env->opaque;
        !          3012:             if (flags & CLONE_SETTLS)
        !          3013:                 cpu_set_tls (env, newtls);
        !          3014:             /* TODO: Implement CLONE_CHILD_CLEARTID.  */
        !          3015: #endif
        !          3016:         } else {
        !          3017:             fork_end(0);
        !          3018:         }
1.1       root     3019:     }
                   3020:     return ret;
                   3021: }
                   3022: 
1.1.1.6   root     3023: static abi_long do_fcntl(int fd, int cmd, abi_ulong arg)
1.1       root     3024: {
                   3025:     struct flock fl;
1.1.1.3   root     3026:     struct target_flock *target_fl;
1.1.1.5   root     3027:     struct flock64 fl64;
                   3028:     struct target_flock64 *target_fl64;
1.1.1.6   root     3029:     abi_long ret;
1.1.1.3   root     3030: 
1.1       root     3031:     switch(cmd) {
                   3032:     case TARGET_F_GETLK:
1.1.1.6   root     3033:         if (!lock_user_struct(VERIFY_READ, target_fl, arg, 1))
                   3034:             return -TARGET_EFAULT;
                   3035:         fl.l_type = tswap16(target_fl->l_type);
                   3036:         fl.l_whence = tswap16(target_fl->l_whence);
                   3037:         fl.l_start = tswapl(target_fl->l_start);
                   3038:         fl.l_len = tswapl(target_fl->l_len);
                   3039:         fl.l_pid = tswapl(target_fl->l_pid);
                   3040:         unlock_user_struct(target_fl, arg, 0);
                   3041:         ret = get_errno(fcntl(fd, cmd, &fl));
1.1       root     3042:         if (ret == 0) {
1.1.1.6   root     3043:             if (!lock_user_struct(VERIFY_WRITE, target_fl, arg, 0))
                   3044:                 return -TARGET_EFAULT;
1.1       root     3045:             target_fl->l_type = tswap16(fl.l_type);
                   3046:             target_fl->l_whence = tswap16(fl.l_whence);
                   3047:             target_fl->l_start = tswapl(fl.l_start);
                   3048:             target_fl->l_len = tswapl(fl.l_len);
                   3049:             target_fl->l_pid = tswapl(fl.l_pid);
1.1.1.3   root     3050:             unlock_user_struct(target_fl, arg, 1);
1.1       root     3051:         }
                   3052:         break;
1.1.1.6   root     3053: 
1.1       root     3054:     case TARGET_F_SETLK:
                   3055:     case TARGET_F_SETLKW:
1.1.1.6   root     3056:         if (!lock_user_struct(VERIFY_READ, target_fl, arg, 1))
                   3057:             return -TARGET_EFAULT;
1.1       root     3058:         fl.l_type = tswap16(target_fl->l_type);
                   3059:         fl.l_whence = tswap16(target_fl->l_whence);
                   3060:         fl.l_start = tswapl(target_fl->l_start);
                   3061:         fl.l_len = tswapl(target_fl->l_len);
                   3062:         fl.l_pid = tswapl(target_fl->l_pid);
1.1.1.3   root     3063:         unlock_user_struct(target_fl, arg, 0);
1.1.1.6   root     3064:         ret = get_errno(fcntl(fd, cmd, &fl));
1.1       root     3065:         break;
1.1.1.6   root     3066: 
1.1       root     3067:     case TARGET_F_GETLK64:
1.1.1.6   root     3068:         if (!lock_user_struct(VERIFY_READ, target_fl64, arg, 1))
                   3069:             return -TARGET_EFAULT;
                   3070:         fl64.l_type = tswap16(target_fl64->l_type) >> 1;
                   3071:         fl64.l_whence = tswap16(target_fl64->l_whence);
                   3072:         fl64.l_start = tswapl(target_fl64->l_start);
                   3073:         fl64.l_len = tswapl(target_fl64->l_len);
                   3074:         fl64.l_pid = tswap16(target_fl64->l_pid);
                   3075:         unlock_user_struct(target_fl64, arg, 0);
                   3076:         ret = get_errno(fcntl(fd, cmd >> 1, &fl64));
1.1.1.5   root     3077:         if (ret == 0) {
1.1.1.6   root     3078:             if (!lock_user_struct(VERIFY_WRITE, target_fl64, arg, 0))
                   3079:                 return -TARGET_EFAULT;
1.1.1.5   root     3080:             target_fl64->l_type = tswap16(fl64.l_type) >> 1;
                   3081:             target_fl64->l_whence = tswap16(fl64.l_whence);
                   3082:             target_fl64->l_start = tswapl(fl64.l_start);
                   3083:             target_fl64->l_len = tswapl(fl64.l_len);
                   3084:             target_fl64->l_pid = tswapl(fl64.l_pid);
                   3085:             unlock_user_struct(target_fl64, arg, 1);
                   3086:         }
1.1.1.6   root     3087:         break;
1.1       root     3088:     case TARGET_F_SETLK64:
                   3089:     case TARGET_F_SETLKW64:
1.1.1.6   root     3090:         if (!lock_user_struct(VERIFY_READ, target_fl64, arg, 1))
                   3091:             return -TARGET_EFAULT;
1.1.1.5   root     3092:         fl64.l_type = tswap16(target_fl64->l_type) >> 1;
                   3093:         fl64.l_whence = tswap16(target_fl64->l_whence);
                   3094:         fl64.l_start = tswapl(target_fl64->l_start);
                   3095:         fl64.l_len = tswapl(target_fl64->l_len);
                   3096:         fl64.l_pid = tswap16(target_fl64->l_pid);
                   3097:         unlock_user_struct(target_fl64, arg, 0);
1.1.1.6   root     3098:         ret = get_errno(fcntl(fd, cmd >> 1, &fl64));
1.1       root     3099:         break;
                   3100: 
                   3101:     case F_GETFL:
1.1.1.6   root     3102:         ret = get_errno(fcntl(fd, cmd, arg));
                   3103:         if (ret >= 0) {
                   3104:             ret = host_to_target_bitmask(ret, fcntl_flags_tbl);
                   3105:         }
1.1       root     3106:         break;
                   3107: 
                   3108:     case F_SETFL:
1.1.1.6   root     3109:         ret = get_errno(fcntl(fd, cmd, target_to_host_bitmask(arg, fcntl_flags_tbl)));
1.1       root     3110:         break;
                   3111: 
                   3112:     default:
1.1.1.6   root     3113:         ret = get_errno(fcntl(fd, cmd, arg));
1.1       root     3114:         break;
                   3115:     }
                   3116:     return ret;
                   3117: }
                   3118: 
                   3119: #ifdef USE_UID16
                   3120: 
                   3121: static inline int high2lowuid(int uid)
                   3122: {
                   3123:     if (uid > 65535)
                   3124:         return 65534;
                   3125:     else
                   3126:         return uid;
                   3127: }
                   3128: 
                   3129: static inline int high2lowgid(int gid)
                   3130: {
                   3131:     if (gid > 65535)
                   3132:         return 65534;
                   3133:     else
                   3134:         return gid;
                   3135: }
                   3136: 
                   3137: static inline int low2highuid(int uid)
                   3138: {
                   3139:     if ((int16_t)uid == -1)
                   3140:         return -1;
                   3141:     else
                   3142:         return uid;
                   3143: }
                   3144: 
                   3145: static inline int low2highgid(int gid)
                   3146: {
                   3147:     if ((int16_t)gid == -1)
                   3148:         return -1;
                   3149:     else
                   3150:         return gid;
                   3151: }
                   3152: 
                   3153: #endif /* USE_UID16 */
                   3154: 
                   3155: void syscall_init(void)
                   3156: {
                   3157:     IOCTLEntry *ie;
                   3158:     const argtype *arg_type;
                   3159:     int size;
1.1.1.6   root     3160:     int i;
1.1       root     3161: 
1.1.1.6   root     3162: #define STRUCT(name, list...) thunk_register_struct(STRUCT_ ## name, #name, struct_ ## name ## _def);
                   3163: #define STRUCT_SPECIAL(name) thunk_register_struct_direct(STRUCT_ ## name, #name, &struct_ ## name ## _def);
1.1       root     3164: #include "syscall_types.h"
                   3165: #undef STRUCT
                   3166: #undef STRUCT_SPECIAL
                   3167: 
                   3168:     /* we patch the ioctl size if necessary. We rely on the fact that
                   3169:        no ioctl has all the bits at '1' in the size field */
                   3170:     ie = ioctl_entries;
                   3171:     while (ie->target_cmd != 0) {
                   3172:         if (((ie->target_cmd >> TARGET_IOC_SIZESHIFT) & TARGET_IOC_SIZEMASK) ==
                   3173:             TARGET_IOC_SIZEMASK) {
                   3174:             arg_type = ie->arg_type;
                   3175:             if (arg_type[0] != TYPE_PTR) {
1.1.1.6   root     3176:                 fprintf(stderr, "cannot patch size for ioctl 0x%x\n",
1.1       root     3177:                         ie->target_cmd);
                   3178:                 exit(1);
                   3179:             }
                   3180:             arg_type++;
                   3181:             size = thunk_type_size(arg_type, 0);
1.1.1.6   root     3182:             ie->target_cmd = (ie->target_cmd &
1.1       root     3183:                               ~(TARGET_IOC_SIZEMASK << TARGET_IOC_SIZESHIFT)) |
                   3184:                 (size << TARGET_IOC_SIZESHIFT);
                   3185:         }
1.1.1.6   root     3186: 
                   3187:         /* Build target_to_host_errno_table[] table from
                   3188:          * host_to_target_errno_table[]. */
                   3189:         for (i=0; i < ERRNO_TABLE_SIZE; i++)
                   3190:                 target_to_host_errno_table[host_to_target_errno_table[i]] = i;
                   3191: 
1.1       root     3192:         /* automatic consistency check if same arch */
1.1.1.7 ! root     3193: #if (defined(__i386__) && defined(TARGET_I386) && defined(TARGET_ABI32)) || \
        !          3194:     (defined(__x86_64__) && defined(TARGET_X86_64))
        !          3195:         if (unlikely(ie->target_cmd != ie->host_cmd)) {
        !          3196:             fprintf(stderr, "ERROR: ioctl(%s): target=0x%x host=0x%x\n",
        !          3197:                     ie->name, ie->target_cmd, ie->host_cmd);
1.1       root     3198:         }
                   3199: #endif
                   3200:         ie++;
                   3201:     }
                   3202: }
                   3203: 
1.1.1.6   root     3204: #if TARGET_ABI_BITS == 32
1.1.1.3   root     3205: static inline uint64_t target_offset64(uint32_t word0, uint32_t word1)
                   3206: {
1.1.1.7 ! root     3207: #ifdef TARGET_WORDS_BIGENDIAN
1.1.1.3   root     3208:     return ((uint64_t)word0 << 32) | word1;
                   3209: #else
                   3210:     return ((uint64_t)word1 << 32) | word0;
                   3211: #endif
                   3212: }
1.1.1.6   root     3213: #else /* TARGET_ABI_BITS == 32 */
                   3214: static inline uint64_t target_offset64(uint64_t word0, uint64_t word1)
                   3215: {
                   3216:     return word0;
                   3217: }
                   3218: #endif /* TARGET_ABI_BITS != 32 */
1.1.1.3   root     3219: 
                   3220: #ifdef TARGET_NR_truncate64
1.1.1.6   root     3221: static inline abi_long target_truncate64(void *cpu_env, const char *arg1,
                   3222:                                          abi_long arg2,
                   3223:                                          abi_long arg3,
                   3224:                                          abi_long arg4)
1.1.1.3   root     3225: {
                   3226: #ifdef TARGET_ARM
                   3227:     if (((CPUARMState *)cpu_env)->eabi)
                   3228:       {
                   3229:         arg2 = arg3;
                   3230:         arg3 = arg4;
                   3231:       }
                   3232: #endif
                   3233:     return get_errno(truncate64(arg1, target_offset64(arg2, arg3)));
                   3234: }
                   3235: #endif
                   3236: 
                   3237: #ifdef TARGET_NR_ftruncate64
1.1.1.6   root     3238: static inline abi_long target_ftruncate64(void *cpu_env, abi_long arg1,
                   3239:                                           abi_long arg2,
                   3240:                                           abi_long arg3,
                   3241:                                           abi_long arg4)
1.1.1.3   root     3242: {
                   3243: #ifdef TARGET_ARM
                   3244:     if (((CPUARMState *)cpu_env)->eabi)
                   3245:       {
                   3246:         arg2 = arg3;
                   3247:         arg3 = arg4;
                   3248:       }
                   3249: #endif
                   3250:     return get_errno(ftruncate64(arg1, target_offset64(arg2, arg3)));
                   3251: }
                   3252: #endif
                   3253: 
1.1.1.6   root     3254: static inline abi_long target_to_host_timespec(struct timespec *host_ts,
                   3255:                                                abi_ulong target_addr)
1.1.1.3   root     3256: {
                   3257:     struct target_timespec *target_ts;
                   3258: 
1.1.1.6   root     3259:     if (!lock_user_struct(VERIFY_READ, target_ts, target_addr, 1))
                   3260:         return -TARGET_EFAULT;
1.1.1.3   root     3261:     host_ts->tv_sec = tswapl(target_ts->tv_sec);
                   3262:     host_ts->tv_nsec = tswapl(target_ts->tv_nsec);
                   3263:     unlock_user_struct(target_ts, target_addr, 0);
1.1.1.7 ! root     3264:     return 0;
1.1.1.3   root     3265: }
                   3266: 
1.1.1.6   root     3267: static inline abi_long host_to_target_timespec(abi_ulong target_addr,
                   3268:                                                struct timespec *host_ts)
1.1.1.3   root     3269: {
                   3270:     struct target_timespec *target_ts;
                   3271: 
1.1.1.6   root     3272:     if (!lock_user_struct(VERIFY_WRITE, target_ts, target_addr, 0))
                   3273:         return -TARGET_EFAULT;
1.1.1.3   root     3274:     target_ts->tv_sec = tswapl(host_ts->tv_sec);
                   3275:     target_ts->tv_nsec = tswapl(host_ts->tv_nsec);
                   3276:     unlock_user_struct(target_ts, target_addr, 1);
1.1.1.7 ! root     3277:     return 0;
        !          3278: }
        !          3279: 
        !          3280: #ifdef TARGET_NR_stat64
        !          3281: static inline abi_long host_to_target_stat64(void *cpu_env,
        !          3282:                                              abi_ulong target_addr,
        !          3283:                                              struct stat *host_st)
        !          3284: {
        !          3285: #ifdef TARGET_ARM
        !          3286:     if (((CPUARMState *)cpu_env)->eabi) {
        !          3287:         struct target_eabi_stat64 *target_st;
        !          3288: 
        !          3289:         if (!lock_user_struct(VERIFY_WRITE, target_st, target_addr, 0))
        !          3290:             return -TARGET_EFAULT;
        !          3291:         memset(target_st, 0, sizeof(struct target_eabi_stat64));
        !          3292:         __put_user(host_st->st_dev, &target_st->st_dev);
        !          3293:         __put_user(host_st->st_ino, &target_st->st_ino);
        !          3294: #ifdef TARGET_STAT64_HAS_BROKEN_ST_INO
        !          3295:         __put_user(host_st->st_ino, &target_st->__st_ino);
        !          3296: #endif
        !          3297:         __put_user(host_st->st_mode, &target_st->st_mode);
        !          3298:         __put_user(host_st->st_nlink, &target_st->st_nlink);
        !          3299:         __put_user(host_st->st_uid, &target_st->st_uid);
        !          3300:         __put_user(host_st->st_gid, &target_st->st_gid);
        !          3301:         __put_user(host_st->st_rdev, &target_st->st_rdev);
        !          3302:         __put_user(host_st->st_size, &target_st->st_size);
        !          3303:         __put_user(host_st->st_blksize, &target_st->st_blksize);
        !          3304:         __put_user(host_st->st_blocks, &target_st->st_blocks);
        !          3305:         __put_user(host_st->st_atime, &target_st->target_st_atime);
        !          3306:         __put_user(host_st->st_mtime, &target_st->target_st_mtime);
        !          3307:         __put_user(host_st->st_ctime, &target_st->target_st_ctime);
        !          3308:         unlock_user_struct(target_st, target_addr, 1);
        !          3309:     } else
        !          3310: #endif
        !          3311:     {
        !          3312:         struct target_stat64 *target_st;
        !          3313: 
        !          3314:         if (!lock_user_struct(VERIFY_WRITE, target_st, target_addr, 0))
        !          3315:             return -TARGET_EFAULT;
        !          3316:         memset(target_st, 0, sizeof(struct target_stat64));
        !          3317:         __put_user(host_st->st_dev, &target_st->st_dev);
        !          3318:         __put_user(host_st->st_ino, &target_st->st_ino);
        !          3319: #ifdef TARGET_STAT64_HAS_BROKEN_ST_INO
        !          3320:         __put_user(host_st->st_ino, &target_st->__st_ino);
        !          3321: #endif
        !          3322:         __put_user(host_st->st_mode, &target_st->st_mode);
        !          3323:         __put_user(host_st->st_nlink, &target_st->st_nlink);
        !          3324:         __put_user(host_st->st_uid, &target_st->st_uid);
        !          3325:         __put_user(host_st->st_gid, &target_st->st_gid);
        !          3326:         __put_user(host_st->st_rdev, &target_st->st_rdev);
        !          3327:         /* XXX: better use of kernel struct */
        !          3328:         __put_user(host_st->st_size, &target_st->st_size);
        !          3329:         __put_user(host_st->st_blksize, &target_st->st_blksize);
        !          3330:         __put_user(host_st->st_blocks, &target_st->st_blocks);
        !          3331:         __put_user(host_st->st_atime, &target_st->target_st_atime);
        !          3332:         __put_user(host_st->st_mtime, &target_st->target_st_mtime);
        !          3333:         __put_user(host_st->st_ctime, &target_st->target_st_ctime);
        !          3334:         unlock_user_struct(target_st, target_addr, 1);
        !          3335:     }
        !          3336: 
        !          3337:     return 0;
        !          3338: }
        !          3339: #endif
        !          3340: 
        !          3341: #if defined(USE_NPTL)
        !          3342: /* ??? Using host futex calls even when target atomic operations
        !          3343:    are not really atomic probably breaks things.  However implementing
        !          3344:    futexes locally would make futexes shared between multiple processes
        !          3345:    tricky.  However they're probably useless because guest atomic
        !          3346:    operations won't work either.  */
        !          3347: static int do_futex(target_ulong uaddr, int op, int val, target_ulong timeout,
        !          3348:                     target_ulong uaddr2, int val3)
        !          3349: {
        !          3350:     struct timespec ts, *pts;
        !          3351: 
        !          3352:     /* ??? We assume FUTEX_* constants are the same on both host
        !          3353:        and target.  */
        !          3354:     switch (op) {
        !          3355:     case FUTEX_WAIT:
        !          3356:         if (timeout) {
        !          3357:             pts = &ts;
        !          3358:             target_to_host_timespec(pts, timeout);
        !          3359:         } else {
        !          3360:             pts = NULL;
        !          3361:         }
        !          3362:         return get_errno(sys_futex(g2h(uaddr), FUTEX_WAIT, tswap32(val),
        !          3363:                          pts, NULL, 0));
        !          3364:     case FUTEX_WAKE:
        !          3365:         return get_errno(sys_futex(g2h(uaddr), FUTEX_WAKE, val, NULL, NULL, 0));
        !          3366:     case FUTEX_FD:
        !          3367:         return get_errno(sys_futex(g2h(uaddr), FUTEX_FD, val, NULL, NULL, 0));
        !          3368:     case FUTEX_REQUEUE:
        !          3369:         return get_errno(sys_futex(g2h(uaddr), FUTEX_REQUEUE, val,
        !          3370:                          NULL, g2h(uaddr2), 0));
        !          3371:     case FUTEX_CMP_REQUEUE:
        !          3372:         return get_errno(sys_futex(g2h(uaddr), FUTEX_CMP_REQUEUE, val,
        !          3373:                          NULL, g2h(uaddr2), tswap32(val3)));
        !          3374:     default:
        !          3375:         return -TARGET_ENOSYS;
        !          3376:     }
        !          3377: }
        !          3378: #endif
        !          3379: 
        !          3380: int get_osversion(void)
        !          3381: {
        !          3382:     static int osversion;
        !          3383:     struct new_utsname buf;
        !          3384:     const char *s;
        !          3385:     int i, n, tmp;
        !          3386:     if (osversion)
        !          3387:         return osversion;
        !          3388:     if (qemu_uname_release && *qemu_uname_release) {
        !          3389:         s = qemu_uname_release;
        !          3390:     } else {
        !          3391:         if (sys_uname(&buf))
        !          3392:             return 0;
        !          3393:         s = buf.release;
        !          3394:     }
        !          3395:     tmp = 0;
        !          3396:     for (i = 0; i < 3; i++) {
        !          3397:         n = 0;
        !          3398:         while (*s >= '0' && *s <= '9') {
        !          3399:             n *= 10;
        !          3400:             n += *s - '0';
        !          3401:             s++;
        !          3402:         }
        !          3403:         tmp = (tmp << 8) + n;
        !          3404:         if (*s == '.')
        !          3405:             s++;
        !          3406:     }
        !          3407:     osversion = tmp;
        !          3408:     return osversion;
1.1.1.3   root     3409: }
                   3410: 
1.1.1.6   root     3411: /* do_syscall() should always have a single exit point at the end so
                   3412:    that actions, such as logging of syscall results, can be performed.
                   3413:    All errnos that do_syscall() returns must be -TARGET_<errcode>. */
                   3414: abi_long do_syscall(void *cpu_env, int num, abi_long arg1,
                   3415:                     abi_long arg2, abi_long arg3, abi_long arg4,
                   3416:                     abi_long arg5, abi_long arg6)
1.1       root     3417: {
1.1.1.6   root     3418:     abi_long ret;
1.1       root     3419:     struct stat st;
1.1.1.2   root     3420:     struct statfs stfs;
1.1.1.3   root     3421:     void *p;
1.1.1.6   root     3422: 
1.1       root     3423: #ifdef DEBUG
                   3424:     gemu_log("syscall %d", num);
                   3425: #endif
1.1.1.6   root     3426:     if(do_strace)
                   3427:         print_syscall(num, arg1, arg2, arg3, arg4, arg5, arg6);
                   3428: 
1.1       root     3429:     switch(num) {
                   3430:     case TARGET_NR_exit:
                   3431: #ifdef HAVE_GPROF
                   3432:         _mcleanup();
                   3433: #endif
                   3434:         gdb_exit(cpu_env, arg1);
                   3435:         /* XXX: should free thread stack and CPU env */
1.1.1.7 ! root     3436:         sys_exit(arg1);
1.1       root     3437:         ret = 0; /* avoid warning */
                   3438:         break;
                   3439:     case TARGET_NR_read:
1.1.1.7 ! root     3440:         if (arg3 == 0)
        !          3441:             ret = 0;
        !          3442:         else {
        !          3443:             if (!(p = lock_user(VERIFY_WRITE, arg2, arg3, 0)))
        !          3444:                 goto efault;
        !          3445:             ret = get_errno(read(arg1, p, arg3));
        !          3446:             unlock_user(p, arg2, ret);
        !          3447:         }
1.1       root     3448:         break;
                   3449:     case TARGET_NR_write:
1.1.1.6   root     3450:         if (!(p = lock_user(VERIFY_READ, arg2, arg3, 1)))
                   3451:             goto efault;
1.1.1.3   root     3452:         ret = get_errno(write(arg1, p, arg3));
                   3453:         unlock_user(p, arg2, 0);
1.1       root     3454:         break;
                   3455:     case TARGET_NR_open:
1.1.1.6   root     3456:         if (!(p = lock_user_string(arg1)))
                   3457:             goto efault;
1.1.1.3   root     3458:         ret = get_errno(open(path(p),
1.1       root     3459:                              target_to_host_bitmask(arg2, fcntl_flags_tbl),
                   3460:                              arg3));
1.1.1.3   root     3461:         unlock_user(p, arg1, 0);
1.1       root     3462:         break;
1.1.1.6   root     3463: #if defined(TARGET_NR_openat) && defined(__NR_openat)
                   3464:     case TARGET_NR_openat:
                   3465:         if (!(p = lock_user_string(arg2)))
                   3466:             goto efault;
                   3467:         ret = get_errno(sys_openat(arg1,
                   3468:                                    path(p),
                   3469:                                    target_to_host_bitmask(arg3, fcntl_flags_tbl),
                   3470:                                    arg4));
                   3471:         unlock_user(p, arg2, 0);
                   3472:         break;
                   3473: #endif
1.1       root     3474:     case TARGET_NR_close:
                   3475:         ret = get_errno(close(arg1));
                   3476:         break;
                   3477:     case TARGET_NR_brk:
1.1.1.3   root     3478:         ret = do_brk(arg1);
1.1       root     3479:         break;
                   3480:     case TARGET_NR_fork:
1.1.1.7 ! root     3481:         ret = get_errno(do_fork(cpu_env, SIGCHLD, 0, 0, 0, 0));
1.1       root     3482:         break;
1.1.1.6   root     3483: #ifdef TARGET_NR_waitpid
1.1       root     3484:     case TARGET_NR_waitpid:
                   3485:         {
1.1.1.3   root     3486:             int status;
                   3487:             ret = get_errno(waitpid(arg1, &status, arg3));
1.1.1.6   root     3488:             if (!is_error(ret) && arg2
                   3489:                 && put_user_s32(status, arg2))
                   3490:                 goto efault;
1.1       root     3491:         }
                   3492:         break;
1.1.1.6   root     3493: #endif
1.1.1.7 ! root     3494: #ifdef TARGET_NR_waitid
        !          3495:     case TARGET_NR_waitid:
        !          3496:         {
        !          3497:             siginfo_t info;
        !          3498:             info.si_pid = 0;
        !          3499:             ret = get_errno(waitid(arg1, arg2, &info, arg4));
        !          3500:             if (!is_error(ret) && arg3 && info.si_pid != 0) {
        !          3501:                 if (!(p = lock_user(VERIFY_WRITE, arg3, sizeof(target_siginfo_t), 0)))
        !          3502:                     goto efault;
        !          3503:                 host_to_target_siginfo(p, &info);
        !          3504:                 unlock_user(p, arg3, sizeof(target_siginfo_t));
        !          3505:             }
        !          3506:         }
        !          3507:         break;
        !          3508: #endif
1.1.1.6   root     3509: #ifdef TARGET_NR_creat /* not on alpha */
1.1       root     3510:     case TARGET_NR_creat:
1.1.1.6   root     3511:         if (!(p = lock_user_string(arg1)))
                   3512:             goto efault;
1.1.1.3   root     3513:         ret = get_errno(creat(p, arg2));
                   3514:         unlock_user(p, arg1, 0);
1.1       root     3515:         break;
1.1.1.6   root     3516: #endif
1.1       root     3517:     case TARGET_NR_link:
1.1.1.3   root     3518:         {
                   3519:             void * p2;
                   3520:             p = lock_user_string(arg1);
                   3521:             p2 = lock_user_string(arg2);
1.1.1.6   root     3522:             if (!p || !p2)
                   3523:                 ret = -TARGET_EFAULT;
                   3524:             else
                   3525:                 ret = get_errno(link(p, p2));
1.1.1.3   root     3526:             unlock_user(p2, arg2, 0);
                   3527:             unlock_user(p, arg1, 0);
                   3528:         }
1.1       root     3529:         break;
1.1.1.6   root     3530: #if defined(TARGET_NR_linkat) && defined(__NR_linkat)
                   3531:     case TARGET_NR_linkat:
                   3532:         {
                   3533:             void * p2 = NULL;
                   3534:             if (!arg2 || !arg4)
                   3535:                 goto efault;
                   3536:             p  = lock_user_string(arg2);
                   3537:             p2 = lock_user_string(arg4);
                   3538:             if (!p || !p2)
                   3539:                 ret = -TARGET_EFAULT;
                   3540:             else
                   3541:                 ret = get_errno(sys_linkat(arg1, p, arg3, p2, arg5));
                   3542:             unlock_user(p, arg2, 0);
                   3543:             unlock_user(p2, arg4, 0);
                   3544:         }
                   3545:         break;
                   3546: #endif
1.1       root     3547:     case TARGET_NR_unlink:
1.1.1.6   root     3548:         if (!(p = lock_user_string(arg1)))
                   3549:             goto efault;
1.1.1.3   root     3550:         ret = get_errno(unlink(p));
                   3551:         unlock_user(p, arg1, 0);
1.1       root     3552:         break;
1.1.1.6   root     3553: #if defined(TARGET_NR_unlinkat) && defined(__NR_unlinkat)
                   3554:     case TARGET_NR_unlinkat:
                   3555:         if (!(p = lock_user_string(arg2)))
                   3556:             goto efault;
                   3557:         ret = get_errno(sys_unlinkat(arg1, p, arg3));
                   3558:         unlock_user(p, arg2, 0);
                   3559:         break;
                   3560: #endif
1.1       root     3561:     case TARGET_NR_execve:
                   3562:         {
                   3563:             char **argp, **envp;
                   3564:             int argc, envc;
1.1.1.6   root     3565:             abi_ulong gp;
                   3566:             abi_ulong guest_argp;
                   3567:             abi_ulong guest_envp;
                   3568:             abi_ulong addr;
1.1       root     3569:             char **q;
                   3570: 
                   3571:             argc = 0;
1.1.1.3   root     3572:             guest_argp = arg2;
1.1.1.7 ! root     3573:             for (gp = guest_argp; gp; gp += sizeof(abi_ulong)) {
1.1.1.6   root     3574:                 if (get_user_ual(addr, gp))
                   3575:                     goto efault;
                   3576:                 if (!addr)
                   3577:                     break;
1.1       root     3578:                 argc++;
1.1.1.6   root     3579:             }
1.1       root     3580:             envc = 0;
1.1.1.3   root     3581:             guest_envp = arg3;
1.1.1.7 ! root     3582:             for (gp = guest_envp; gp; gp += sizeof(abi_ulong)) {
1.1.1.6   root     3583:                 if (get_user_ual(addr, gp))
                   3584:                     goto efault;
                   3585:                 if (!addr)
                   3586:                     break;
1.1       root     3587:                 envc++;
1.1.1.6   root     3588:             }
1.1       root     3589: 
                   3590:             argp = alloca((argc + 1) * sizeof(void *));
                   3591:             envp = alloca((envc + 1) * sizeof(void *));
                   3592: 
1.1.1.7 ! root     3593:             for (gp = guest_argp, q = argp; gp;
1.1.1.6   root     3594:                   gp += sizeof(abi_ulong), q++) {
                   3595:                 if (get_user_ual(addr, gp))
                   3596:                     goto execve_efault;
1.1.1.3   root     3597:                 if (!addr)
                   3598:                     break;
1.1.1.6   root     3599:                 if (!(*q = lock_user_string(addr)))
                   3600:                     goto execve_efault;
1.1.1.3   root     3601:             }
1.1       root     3602:             *q = NULL;
                   3603: 
1.1.1.7 ! root     3604:             for (gp = guest_envp, q = envp; gp;
1.1.1.6   root     3605:                   gp += sizeof(abi_ulong), q++) {
                   3606:                 if (get_user_ual(addr, gp))
                   3607:                     goto execve_efault;
1.1.1.3   root     3608:                 if (!addr)
                   3609:                     break;
1.1.1.6   root     3610:                 if (!(*q = lock_user_string(addr)))
                   3611:                     goto execve_efault;
1.1.1.3   root     3612:             }
1.1       root     3613:             *q = NULL;
                   3614: 
1.1.1.6   root     3615:             if (!(p = lock_user_string(arg1)))
                   3616:                 goto execve_efault;
1.1.1.3   root     3617:             ret = get_errno(execve(p, argp, envp));
                   3618:             unlock_user(p, arg1, 0);
                   3619: 
1.1.1.6   root     3620:             goto execve_end;
                   3621: 
                   3622:         execve_efault:
                   3623:             ret = -TARGET_EFAULT;
                   3624: 
                   3625:         execve_end:
1.1.1.3   root     3626:             for (gp = guest_argp, q = argp; *q;
1.1.1.6   root     3627:                   gp += sizeof(abi_ulong), q++) {
                   3628:                 if (get_user_ual(addr, gp)
                   3629:                     || !addr)
                   3630:                     break;
1.1.1.3   root     3631:                 unlock_user(*q, addr, 0);
                   3632:             }
                   3633:             for (gp = guest_envp, q = envp; *q;
1.1.1.6   root     3634:                   gp += sizeof(abi_ulong), q++) {
                   3635:                 if (get_user_ual(addr, gp)
                   3636:                     || !addr)
                   3637:                     break;
1.1.1.3   root     3638:                 unlock_user(*q, addr, 0);
                   3639:             }
1.1       root     3640:         }
                   3641:         break;
                   3642:     case TARGET_NR_chdir:
1.1.1.6   root     3643:         if (!(p = lock_user_string(arg1)))
                   3644:             goto efault;
1.1.1.3   root     3645:         ret = get_errno(chdir(p));
                   3646:         unlock_user(p, arg1, 0);
1.1       root     3647:         break;
                   3648: #ifdef TARGET_NR_time
                   3649:     case TARGET_NR_time:
                   3650:         {
1.1.1.3   root     3651:             time_t host_time;
                   3652:             ret = get_errno(time(&host_time));
1.1.1.6   root     3653:             if (!is_error(ret)
                   3654:                 && arg1
                   3655:                 && put_user_sal(host_time, arg1))
                   3656:                 goto efault;
1.1       root     3657:         }
                   3658:         break;
                   3659: #endif
                   3660:     case TARGET_NR_mknod:
1.1.1.6   root     3661:         if (!(p = lock_user_string(arg1)))
                   3662:             goto efault;
1.1.1.3   root     3663:         ret = get_errno(mknod(p, arg2, arg3));
                   3664:         unlock_user(p, arg1, 0);
1.1       root     3665:         break;
1.1.1.6   root     3666: #if defined(TARGET_NR_mknodat) && defined(__NR_mknodat)
                   3667:     case TARGET_NR_mknodat:
                   3668:         if (!(p = lock_user_string(arg2)))
                   3669:             goto efault;
                   3670:         ret = get_errno(sys_mknodat(arg1, p, arg3, arg4));
                   3671:         unlock_user(p, arg2, 0);
                   3672:         break;
                   3673: #endif
1.1       root     3674:     case TARGET_NR_chmod:
1.1.1.6   root     3675:         if (!(p = lock_user_string(arg1)))
                   3676:             goto efault;
1.1.1.3   root     3677:         ret = get_errno(chmod(p, arg2));
                   3678:         unlock_user(p, arg1, 0);
1.1       root     3679:         break;
                   3680: #ifdef TARGET_NR_break
                   3681:     case TARGET_NR_break:
                   3682:         goto unimplemented;
                   3683: #endif
                   3684: #ifdef TARGET_NR_oldstat
                   3685:     case TARGET_NR_oldstat:
                   3686:         goto unimplemented;
                   3687: #endif
                   3688:     case TARGET_NR_lseek:
                   3689:         ret = get_errno(lseek(arg1, arg2, arg3));
                   3690:         break;
1.1.1.6   root     3691: #ifdef TARGET_NR_getxpid
                   3692:     case TARGET_NR_getxpid:
                   3693: #else
1.1       root     3694:     case TARGET_NR_getpid:
1.1.1.6   root     3695: #endif
1.1       root     3696:         ret = get_errno(getpid());
                   3697:         break;
                   3698:     case TARGET_NR_mount:
1.1.1.6   root     3699:                {
                   3700:                        /* need to look at the data field */
                   3701:                        void *p2, *p3;
                   3702:                        p = lock_user_string(arg1);
                   3703:                        p2 = lock_user_string(arg2);
                   3704:                        p3 = lock_user_string(arg3);
                   3705:                         if (!p || !p2 || !p3)
                   3706:                             ret = -TARGET_EFAULT;
                   3707:                         else
                   3708:                             /* FIXME - arg5 should be locked, but it isn't clear how to
                   3709:                              * do that since it's not guaranteed to be a NULL-terminated
                   3710:                              * string.
                   3711:                              */
                   3712:                             ret = get_errno(mount(p, p2, p3, (unsigned long)arg4, g2h(arg5)));
                   3713:                         unlock_user(p, arg1, 0);
                   3714:                         unlock_user(p2, arg2, 0);
                   3715:                         unlock_user(p3, arg3, 0);
                   3716:                        break;
                   3717:                }
                   3718: #ifdef TARGET_NR_umount
1.1       root     3719:     case TARGET_NR_umount:
1.1.1.6   root     3720:         if (!(p = lock_user_string(arg1)))
                   3721:             goto efault;
1.1.1.3   root     3722:         ret = get_errno(umount(p));
                   3723:         unlock_user(p, arg1, 0);
1.1       root     3724:         break;
1.1.1.6   root     3725: #endif
                   3726: #ifdef TARGET_NR_stime /* not on alpha */
1.1       root     3727:     case TARGET_NR_stime:
                   3728:         {
1.1.1.3   root     3729:             time_t host_time;
1.1.1.6   root     3730:             if (get_user_sal(host_time, arg1))
                   3731:                 goto efault;
1.1.1.3   root     3732:             ret = get_errno(stime(&host_time));
1.1       root     3733:         }
                   3734:         break;
1.1.1.6   root     3735: #endif
1.1       root     3736:     case TARGET_NR_ptrace:
                   3737:         goto unimplemented;
1.1.1.6   root     3738: #ifdef TARGET_NR_alarm /* not on alpha */
1.1       root     3739:     case TARGET_NR_alarm:
                   3740:         ret = alarm(arg1);
                   3741:         break;
1.1.1.6   root     3742: #endif
1.1       root     3743: #ifdef TARGET_NR_oldfstat
                   3744:     case TARGET_NR_oldfstat:
                   3745:         goto unimplemented;
                   3746: #endif
1.1.1.6   root     3747: #ifdef TARGET_NR_pause /* not on alpha */
1.1       root     3748:     case TARGET_NR_pause:
                   3749:         ret = get_errno(pause());
                   3750:         break;
1.1.1.6   root     3751: #endif
                   3752: #ifdef TARGET_NR_utime
1.1       root     3753:     case TARGET_NR_utime:
                   3754:         {
1.1.1.3   root     3755:             struct utimbuf tbuf, *host_tbuf;
                   3756:             struct target_utimbuf *target_tbuf;
                   3757:             if (arg2) {
1.1.1.6   root     3758:                 if (!lock_user_struct(VERIFY_READ, target_tbuf, arg2, 1))
                   3759:                     goto efault;
1.1.1.3   root     3760:                 tbuf.actime = tswapl(target_tbuf->actime);
                   3761:                 tbuf.modtime = tswapl(target_tbuf->modtime);
                   3762:                 unlock_user_struct(target_tbuf, arg2, 0);
                   3763:                 host_tbuf = &tbuf;
1.1       root     3764:             } else {
1.1.1.3   root     3765:                 host_tbuf = NULL;
1.1       root     3766:             }
1.1.1.6   root     3767:             if (!(p = lock_user_string(arg1)))
                   3768:                 goto efault;
1.1.1.3   root     3769:             ret = get_errno(utime(p, host_tbuf));
                   3770:             unlock_user(p, arg1, 0);
1.1       root     3771:         }
                   3772:         break;
1.1.1.6   root     3773: #endif
1.1       root     3774:     case TARGET_NR_utimes:
                   3775:         {
                   3776:             struct timeval *tvp, tv[2];
1.1.1.3   root     3777:             if (arg2) {
1.1.1.6   root     3778:                 if (copy_from_user_timeval(&tv[0], arg2)
                   3779:                     || copy_from_user_timeval(&tv[1],
                   3780:                                               arg2 + sizeof(struct target_timeval)))
                   3781:                     goto efault;
1.1       root     3782:                 tvp = tv;
                   3783:             } else {
                   3784:                 tvp = NULL;
                   3785:             }
1.1.1.6   root     3786:             if (!(p = lock_user_string(arg1)))
                   3787:                 goto efault;
1.1.1.3   root     3788:             ret = get_errno(utimes(p, tvp));
                   3789:             unlock_user(p, arg1, 0);
1.1       root     3790:         }
                   3791:         break;
1.1.1.7 ! root     3792: #if defined(TARGET_NR_futimesat) && defined(__NR_futimesat)
        !          3793:     case TARGET_NR_futimesat:
        !          3794:         {
        !          3795:             struct timeval *tvp, tv[2];
        !          3796:             if (arg3) {
        !          3797:                 if (copy_from_user_timeval(&tv[0], arg3)
        !          3798:                     || copy_from_user_timeval(&tv[1],
        !          3799:                                               arg3 + sizeof(struct target_timeval)))
        !          3800:                     goto efault;
        !          3801:                 tvp = tv;
        !          3802:             } else {
        !          3803:                 tvp = NULL;
        !          3804:             }
        !          3805:             if (!(p = lock_user_string(arg2)))
        !          3806:                 goto efault;
        !          3807:             ret = get_errno(sys_futimesat(arg1, path(p), tvp));
        !          3808:             unlock_user(p, arg2, 0);
        !          3809:         }
        !          3810:         break;
        !          3811: #endif
1.1       root     3812: #ifdef TARGET_NR_stty
                   3813:     case TARGET_NR_stty:
                   3814:         goto unimplemented;
                   3815: #endif
                   3816: #ifdef TARGET_NR_gtty
                   3817:     case TARGET_NR_gtty:
                   3818:         goto unimplemented;
                   3819: #endif
                   3820:     case TARGET_NR_access:
1.1.1.6   root     3821:         if (!(p = lock_user_string(arg1)))
                   3822:             goto efault;
1.1.1.3   root     3823:         ret = get_errno(access(p, arg2));
                   3824:         unlock_user(p, arg1, 0);
1.1       root     3825:         break;
1.1.1.6   root     3826: #if defined(TARGET_NR_faccessat) && defined(__NR_faccessat)
                   3827:     case TARGET_NR_faccessat:
                   3828:         if (!(p = lock_user_string(arg2)))
                   3829:             goto efault;
                   3830:         ret = get_errno(sys_faccessat(arg1, p, arg3, arg4));
                   3831:         unlock_user(p, arg2, 0);
                   3832:         break;
                   3833: #endif
                   3834: #ifdef TARGET_NR_nice /* not on alpha */
1.1       root     3835:     case TARGET_NR_nice:
                   3836:         ret = get_errno(nice(arg1));
                   3837:         break;
1.1.1.6   root     3838: #endif
1.1       root     3839: #ifdef TARGET_NR_ftime
                   3840:     case TARGET_NR_ftime:
                   3841:         goto unimplemented;
                   3842: #endif
                   3843:     case TARGET_NR_sync:
                   3844:         sync();
                   3845:         ret = 0;
                   3846:         break;
                   3847:     case TARGET_NR_kill:
1.1.1.7 ! root     3848:         ret = get_errno(kill(arg1, target_to_host_signal(arg2)));
1.1       root     3849:         break;
                   3850:     case TARGET_NR_rename:
1.1.1.3   root     3851:         {
                   3852:             void *p2;
                   3853:             p = lock_user_string(arg1);
                   3854:             p2 = lock_user_string(arg2);
1.1.1.6   root     3855:             if (!p || !p2)
                   3856:                 ret = -TARGET_EFAULT;
                   3857:             else
                   3858:                 ret = get_errno(rename(p, p2));
1.1.1.3   root     3859:             unlock_user(p2, arg2, 0);
                   3860:             unlock_user(p, arg1, 0);
                   3861:         }
1.1       root     3862:         break;
1.1.1.6   root     3863: #if defined(TARGET_NR_renameat) && defined(__NR_renameat)
                   3864:     case TARGET_NR_renameat:
                   3865:         {
                   3866:             void *p2;
                   3867:             p  = lock_user_string(arg2);
                   3868:             p2 = lock_user_string(arg4);
                   3869:             if (!p || !p2)
                   3870:                 ret = -TARGET_EFAULT;
                   3871:             else
                   3872:                 ret = get_errno(sys_renameat(arg1, p, arg3, p2));
                   3873:             unlock_user(p2, arg4, 0);
                   3874:             unlock_user(p, arg2, 0);
                   3875:         }
                   3876:         break;
                   3877: #endif
1.1       root     3878:     case TARGET_NR_mkdir:
1.1.1.6   root     3879:         if (!(p = lock_user_string(arg1)))
                   3880:             goto efault;
1.1.1.3   root     3881:         ret = get_errno(mkdir(p, arg2));
                   3882:         unlock_user(p, arg1, 0);
1.1       root     3883:         break;
1.1.1.6   root     3884: #if defined(TARGET_NR_mkdirat) && defined(__NR_mkdirat)
                   3885:     case TARGET_NR_mkdirat:
                   3886:         if (!(p = lock_user_string(arg2)))
                   3887:             goto efault;
                   3888:         ret = get_errno(sys_mkdirat(arg1, p, arg3));
                   3889:         unlock_user(p, arg2, 0);
                   3890:         break;
                   3891: #endif
1.1       root     3892:     case TARGET_NR_rmdir:
1.1.1.6   root     3893:         if (!(p = lock_user_string(arg1)))
                   3894:             goto efault;
1.1.1.3   root     3895:         ret = get_errno(rmdir(p));
                   3896:         unlock_user(p, arg1, 0);
1.1       root     3897:         break;
                   3898:     case TARGET_NR_dup:
                   3899:         ret = get_errno(dup(arg1));
                   3900:         break;
                   3901:     case TARGET_NR_pipe:
                   3902:         {
1.1.1.3   root     3903:             int host_pipe[2];
                   3904:             ret = get_errno(pipe(host_pipe));
1.1       root     3905:             if (!is_error(ret)) {
1.1.1.6   root     3906: #if defined(TARGET_MIPS)
                   3907:                 CPUMIPSState *env = (CPUMIPSState*)cpu_env;
1.1.1.7 ! root     3908:                env->active_tc.gpr[3] = host_pipe[1];
        !          3909:                ret = host_pipe[0];
        !          3910: #elif defined(TARGET_SH4)
        !          3911:                ((CPUSH4State*)cpu_env)->gregs[1] = host_pipe[1];
1.1.1.6   root     3912:                ret = host_pipe[0];
                   3913: #else
                   3914:                 if (put_user_s32(host_pipe[0], arg1)
                   3915:                     || put_user_s32(host_pipe[1], arg1 + sizeof(host_pipe[0])))
                   3916:                     goto efault;
                   3917: #endif
1.1       root     3918:             }
                   3919:         }
                   3920:         break;
                   3921:     case TARGET_NR_times:
                   3922:         {
1.1.1.3   root     3923:             struct target_tms *tmsp;
1.1       root     3924:             struct tms tms;
                   3925:             ret = get_errno(times(&tms));
1.1.1.3   root     3926:             if (arg1) {
1.1.1.6   root     3927:                 tmsp = lock_user(VERIFY_WRITE, arg1, sizeof(struct target_tms), 0);
                   3928:                 if (!tmsp)
                   3929:                     goto efault;
1.1       root     3930:                 tmsp->tms_utime = tswapl(host_to_target_clock_t(tms.tms_utime));
                   3931:                 tmsp->tms_stime = tswapl(host_to_target_clock_t(tms.tms_stime));
                   3932:                 tmsp->tms_cutime = tswapl(host_to_target_clock_t(tms.tms_cutime));
                   3933:                 tmsp->tms_cstime = tswapl(host_to_target_clock_t(tms.tms_cstime));
                   3934:             }
                   3935:             if (!is_error(ret))
                   3936:                 ret = host_to_target_clock_t(ret);
                   3937:         }
                   3938:         break;
                   3939: #ifdef TARGET_NR_prof
                   3940:     case TARGET_NR_prof:
                   3941:         goto unimplemented;
                   3942: #endif
1.1.1.6   root     3943: #ifdef TARGET_NR_signal
1.1       root     3944:     case TARGET_NR_signal:
                   3945:         goto unimplemented;
1.1.1.6   root     3946: #endif
1.1       root     3947:     case TARGET_NR_acct:
1.1.1.7 ! root     3948:         if (arg1 == 0) {
        !          3949:             ret = get_errno(acct(NULL));
        !          3950:         } else {
        !          3951:             if (!(p = lock_user_string(arg1)))
        !          3952:                 goto efault;
        !          3953:             ret = get_errno(acct(path(p)));
        !          3954:             unlock_user(p, arg1, 0);
        !          3955:         }
1.1.1.3   root     3956:         break;
1.1.1.6   root     3957: #ifdef TARGET_NR_umount2 /* not on alpha */
1.1       root     3958:     case TARGET_NR_umount2:
1.1.1.6   root     3959:         if (!(p = lock_user_string(arg1)))
                   3960:             goto efault;
1.1.1.3   root     3961:         ret = get_errno(umount2(p, arg2));
                   3962:         unlock_user(p, arg1, 0);
1.1       root     3963:         break;
1.1.1.6   root     3964: #endif
1.1       root     3965: #ifdef TARGET_NR_lock
                   3966:     case TARGET_NR_lock:
                   3967:         goto unimplemented;
                   3968: #endif
                   3969:     case TARGET_NR_ioctl:
                   3970:         ret = do_ioctl(arg1, arg2, arg3);
                   3971:         break;
                   3972:     case TARGET_NR_fcntl:
1.1.1.6   root     3973:         ret = do_fcntl(arg1, arg2, arg3);
1.1       root     3974:         break;
                   3975: #ifdef TARGET_NR_mpx
                   3976:     case TARGET_NR_mpx:
                   3977:         goto unimplemented;
                   3978: #endif
                   3979:     case TARGET_NR_setpgid:
                   3980:         ret = get_errno(setpgid(arg1, arg2));
                   3981:         break;
                   3982: #ifdef TARGET_NR_ulimit
                   3983:     case TARGET_NR_ulimit:
                   3984:         goto unimplemented;
                   3985: #endif
                   3986: #ifdef TARGET_NR_oldolduname
                   3987:     case TARGET_NR_oldolduname:
                   3988:         goto unimplemented;
                   3989: #endif
                   3990:     case TARGET_NR_umask:
                   3991:         ret = get_errno(umask(arg1));
                   3992:         break;
                   3993:     case TARGET_NR_chroot:
1.1.1.6   root     3994:         if (!(p = lock_user_string(arg1)))
                   3995:             goto efault;
1.1.1.3   root     3996:         ret = get_errno(chroot(p));
                   3997:         unlock_user(p, arg1, 0);
1.1       root     3998:         break;
                   3999:     case TARGET_NR_ustat:
                   4000:         goto unimplemented;
                   4001:     case TARGET_NR_dup2:
                   4002:         ret = get_errno(dup2(arg1, arg2));
                   4003:         break;
1.1.1.6   root     4004: #ifdef TARGET_NR_getppid /* not on alpha */
1.1       root     4005:     case TARGET_NR_getppid:
                   4006:         ret = get_errno(getppid());
                   4007:         break;
1.1.1.6   root     4008: #endif
1.1       root     4009:     case TARGET_NR_getpgrp:
                   4010:         ret = get_errno(getpgrp());
                   4011:         break;
                   4012:     case TARGET_NR_setsid:
                   4013:         ret = get_errno(setsid());
                   4014:         break;
1.1.1.6   root     4015: #ifdef TARGET_NR_sigaction
1.1       root     4016:     case TARGET_NR_sigaction:
                   4017:         {
1.1.1.6   root     4018: #if !defined(TARGET_MIPS)
1.1.1.3   root     4019:             struct target_old_sigaction *old_act;
1.1       root     4020:             struct target_sigaction act, oact, *pact;
1.1.1.3   root     4021:             if (arg2) {
1.1.1.6   root     4022:                 if (!lock_user_struct(VERIFY_READ, old_act, arg2, 1))
                   4023:                     goto efault;
1.1       root     4024:                 act._sa_handler = old_act->_sa_handler;
                   4025:                 target_siginitset(&act.sa_mask, old_act->sa_mask);
                   4026:                 act.sa_flags = old_act->sa_flags;
                   4027:                 act.sa_restorer = old_act->sa_restorer;
1.1.1.3   root     4028:                 unlock_user_struct(old_act, arg2, 0);
1.1       root     4029:                 pact = &act;
                   4030:             } else {
                   4031:                 pact = NULL;
                   4032:             }
                   4033:             ret = get_errno(do_sigaction(arg1, pact, &oact));
1.1.1.3   root     4034:             if (!is_error(ret) && arg3) {
1.1.1.6   root     4035:                 if (!lock_user_struct(VERIFY_WRITE, old_act, arg3, 0))
                   4036:                     goto efault;
1.1.1.3   root     4037:                 old_act->_sa_handler = oact._sa_handler;
                   4038:                 old_act->sa_mask = oact.sa_mask.sig[0];
                   4039:                 old_act->sa_flags = oact.sa_flags;
                   4040:                 old_act->sa_restorer = oact.sa_restorer;
                   4041:                 unlock_user_struct(old_act, arg3, 1);
1.1       root     4042:             }
1.1.1.6   root     4043: #else
1.1.1.4   root     4044:            struct target_sigaction act, oact, *pact, *old_act;
                   4045: 
                   4046:            if (arg2) {
1.1.1.6   root     4047:                 if (!lock_user_struct(VERIFY_READ, old_act, arg2, 1))
                   4048:                     goto efault;
1.1.1.4   root     4049:                act._sa_handler = old_act->_sa_handler;
                   4050:                target_siginitset(&act.sa_mask, old_act->sa_mask.sig[0]);
                   4051:                act.sa_flags = old_act->sa_flags;
                   4052:                unlock_user_struct(old_act, arg2, 0);
                   4053:                pact = &act;
                   4054:            } else {
                   4055:                pact = NULL;
                   4056:            }
                   4057: 
                   4058:            ret = get_errno(do_sigaction(arg1, pact, &oact));
                   4059: 
                   4060:            if (!is_error(ret) && arg3) {
1.1.1.6   root     4061:                 if (!lock_user_struct(VERIFY_WRITE, old_act, arg3, 0))
                   4062:                     goto efault;
1.1.1.4   root     4063:                old_act->_sa_handler = oact._sa_handler;
                   4064:                old_act->sa_flags = oact.sa_flags;
                   4065:                old_act->sa_mask.sig[0] = oact.sa_mask.sig[0];
                   4066:                old_act->sa_mask.sig[1] = 0;
                   4067:                old_act->sa_mask.sig[2] = 0;
                   4068:                old_act->sa_mask.sig[3] = 0;
                   4069:                unlock_user_struct(old_act, arg3, 1);
                   4070:            }
1.1.1.6   root     4071: #endif
1.1       root     4072:         }
                   4073:         break;
1.1.1.6   root     4074: #endif
1.1       root     4075:     case TARGET_NR_rt_sigaction:
1.1.1.3   root     4076:         {
                   4077:             struct target_sigaction *act;
                   4078:             struct target_sigaction *oact;
                   4079: 
1.1.1.6   root     4080:             if (arg2) {
                   4081:                 if (!lock_user_struct(VERIFY_READ, act, arg2, 1))
                   4082:                     goto efault;
                   4083:             } else
1.1.1.3   root     4084:                 act = NULL;
1.1.1.6   root     4085:             if (arg3) {
                   4086:                 if (!lock_user_struct(VERIFY_WRITE, oact, arg3, 0)) {
                   4087:                     ret = -TARGET_EFAULT;
                   4088:                     goto rt_sigaction_fail;
                   4089:                 }
                   4090:             } else
1.1.1.3   root     4091:                 oact = NULL;
                   4092:             ret = get_errno(do_sigaction(arg1, act, oact));
1.1.1.6   root     4093:        rt_sigaction_fail:
                   4094:             if (act)
1.1.1.3   root     4095:                 unlock_user_struct(act, arg2, 0);
1.1.1.6   root     4096:             if (oact)
1.1.1.3   root     4097:                 unlock_user_struct(oact, arg3, 1);
                   4098:         }
1.1       root     4099:         break;
1.1.1.6   root     4100: #ifdef TARGET_NR_sgetmask /* not on alpha */
1.1       root     4101:     case TARGET_NR_sgetmask:
                   4102:         {
                   4103:             sigset_t cur_set;
1.1.1.6   root     4104:             abi_ulong target_set;
1.1       root     4105:             sigprocmask(0, NULL, &cur_set);
                   4106:             host_to_target_old_sigset(&target_set, &cur_set);
                   4107:             ret = target_set;
                   4108:         }
                   4109:         break;
1.1.1.6   root     4110: #endif
                   4111: #ifdef TARGET_NR_ssetmask /* not on alpha */
1.1       root     4112:     case TARGET_NR_ssetmask:
                   4113:         {
                   4114:             sigset_t set, oset, cur_set;
1.1.1.6   root     4115:             abi_ulong target_set = arg1;
1.1       root     4116:             sigprocmask(0, NULL, &cur_set);
                   4117:             target_to_host_old_sigset(&set, &target_set);
                   4118:             sigorset(&set, &set, &cur_set);
                   4119:             sigprocmask(SIG_SETMASK, &set, &oset);
                   4120:             host_to_target_old_sigset(&target_set, &oset);
                   4121:             ret = target_set;
                   4122:         }
                   4123:         break;
1.1.1.6   root     4124: #endif
                   4125: #ifdef TARGET_NR_sigprocmask
1.1       root     4126:     case TARGET_NR_sigprocmask:
                   4127:         {
                   4128:             int how = arg1;
                   4129:             sigset_t set, oldset, *set_ptr;
1.1.1.6   root     4130: 
1.1.1.3   root     4131:             if (arg2) {
1.1       root     4132:                 switch(how) {
                   4133:                 case TARGET_SIG_BLOCK:
                   4134:                     how = SIG_BLOCK;
                   4135:                     break;
                   4136:                 case TARGET_SIG_UNBLOCK:
                   4137:                     how = SIG_UNBLOCK;
                   4138:                     break;
                   4139:                 case TARGET_SIG_SETMASK:
                   4140:                     how = SIG_SETMASK;
                   4141:                     break;
                   4142:                 default:
1.1.1.6   root     4143:                     ret = -TARGET_EINVAL;
1.1       root     4144:                     goto fail;
                   4145:                 }
1.1.1.6   root     4146:                 if (!(p = lock_user(VERIFY_READ, arg2, sizeof(target_sigset_t), 1)))
                   4147:                     goto efault;
1.1.1.3   root     4148:                 target_to_host_old_sigset(&set, p);
                   4149:                 unlock_user(p, arg2, 0);
1.1       root     4150:                 set_ptr = &set;
                   4151:             } else {
                   4152:                 how = 0;
                   4153:                 set_ptr = NULL;
                   4154:             }
                   4155:             ret = get_errno(sigprocmask(arg1, set_ptr, &oldset));
1.1.1.3   root     4156:             if (!is_error(ret) && arg3) {
1.1.1.6   root     4157:                 if (!(p = lock_user(VERIFY_WRITE, arg3, sizeof(target_sigset_t), 0)))
                   4158:                     goto efault;
1.1.1.3   root     4159:                 host_to_target_old_sigset(p, &oldset);
                   4160:                 unlock_user(p, arg3, sizeof(target_sigset_t));
1.1       root     4161:             }
                   4162:         }
                   4163:         break;
1.1.1.6   root     4164: #endif
1.1       root     4165:     case TARGET_NR_rt_sigprocmask:
                   4166:         {
                   4167:             int how = arg1;
                   4168:             sigset_t set, oldset, *set_ptr;
1.1.1.6   root     4169: 
1.1.1.3   root     4170:             if (arg2) {
1.1       root     4171:                 switch(how) {
                   4172:                 case TARGET_SIG_BLOCK:
                   4173:                     how = SIG_BLOCK;
                   4174:                     break;
                   4175:                 case TARGET_SIG_UNBLOCK:
                   4176:                     how = SIG_UNBLOCK;
                   4177:                     break;
                   4178:                 case TARGET_SIG_SETMASK:
                   4179:                     how = SIG_SETMASK;
                   4180:                     break;
                   4181:                 default:
1.1.1.6   root     4182:                     ret = -TARGET_EINVAL;
1.1       root     4183:                     goto fail;
                   4184:                 }
1.1.1.6   root     4185:                 if (!(p = lock_user(VERIFY_READ, arg2, sizeof(target_sigset_t), 1)))
                   4186:                     goto efault;
1.1.1.3   root     4187:                 target_to_host_sigset(&set, p);
                   4188:                 unlock_user(p, arg2, 0);
1.1       root     4189:                 set_ptr = &set;
                   4190:             } else {
                   4191:                 how = 0;
                   4192:                 set_ptr = NULL;
                   4193:             }
                   4194:             ret = get_errno(sigprocmask(how, set_ptr, &oldset));
1.1.1.3   root     4195:             if (!is_error(ret) && arg3) {
1.1.1.6   root     4196:                 if (!(p = lock_user(VERIFY_WRITE, arg3, sizeof(target_sigset_t), 0)))
                   4197:                     goto efault;
1.1.1.3   root     4198:                 host_to_target_sigset(p, &oldset);
                   4199:                 unlock_user(p, arg3, sizeof(target_sigset_t));
1.1       root     4200:             }
                   4201:         }
                   4202:         break;
1.1.1.6   root     4203: #ifdef TARGET_NR_sigpending
1.1       root     4204:     case TARGET_NR_sigpending:
                   4205:         {
                   4206:             sigset_t set;
                   4207:             ret = get_errno(sigpending(&set));
                   4208:             if (!is_error(ret)) {
1.1.1.6   root     4209:                 if (!(p = lock_user(VERIFY_WRITE, arg1, sizeof(target_sigset_t), 0)))
                   4210:                     goto efault;
1.1.1.3   root     4211:                 host_to_target_old_sigset(p, &set);
                   4212:                 unlock_user(p, arg1, sizeof(target_sigset_t));
1.1       root     4213:             }
                   4214:         }
                   4215:         break;
1.1.1.6   root     4216: #endif
1.1       root     4217:     case TARGET_NR_rt_sigpending:
                   4218:         {
                   4219:             sigset_t set;
                   4220:             ret = get_errno(sigpending(&set));
                   4221:             if (!is_error(ret)) {
1.1.1.6   root     4222:                 if (!(p = lock_user(VERIFY_WRITE, arg1, sizeof(target_sigset_t), 0)))
                   4223:                     goto efault;
1.1.1.3   root     4224:                 host_to_target_sigset(p, &set);
                   4225:                 unlock_user(p, arg1, sizeof(target_sigset_t));
1.1       root     4226:             }
                   4227:         }
                   4228:         break;
1.1.1.6   root     4229: #ifdef TARGET_NR_sigsuspend
1.1       root     4230:     case TARGET_NR_sigsuspend:
                   4231:         {
                   4232:             sigset_t set;
1.1.1.6   root     4233:             if (!(p = lock_user(VERIFY_READ, arg1, sizeof(target_sigset_t), 1)))
                   4234:                 goto efault;
1.1.1.3   root     4235:             target_to_host_old_sigset(&set, p);
                   4236:             unlock_user(p, arg1, 0);
1.1       root     4237:             ret = get_errno(sigsuspend(&set));
                   4238:         }
                   4239:         break;
1.1.1.6   root     4240: #endif
1.1       root     4241:     case TARGET_NR_rt_sigsuspend:
                   4242:         {
                   4243:             sigset_t set;
1.1.1.6   root     4244:             if (!(p = lock_user(VERIFY_READ, arg1, sizeof(target_sigset_t), 1)))
                   4245:                 goto efault;
1.1.1.3   root     4246:             target_to_host_sigset(&set, p);
                   4247:             unlock_user(p, arg1, 0);
1.1       root     4248:             ret = get_errno(sigsuspend(&set));
                   4249:         }
                   4250:         break;
                   4251:     case TARGET_NR_rt_sigtimedwait:
                   4252:         {
                   4253:             sigset_t set;
                   4254:             struct timespec uts, *puts;
                   4255:             siginfo_t uinfo;
1.1.1.6   root     4256: 
                   4257:             if (!(p = lock_user(VERIFY_READ, arg1, sizeof(target_sigset_t), 1)))
                   4258:                 goto efault;
1.1.1.3   root     4259:             target_to_host_sigset(&set, p);
                   4260:             unlock_user(p, arg1, 0);
                   4261:             if (arg3) {
1.1       root     4262:                 puts = &uts;
1.1.1.3   root     4263:                 target_to_host_timespec(puts, arg3);
1.1       root     4264:             } else {
                   4265:                 puts = NULL;
                   4266:             }
                   4267:             ret = get_errno(sigtimedwait(&set, &uinfo, puts));
1.1.1.3   root     4268:             if (!is_error(ret) && arg2) {
1.1.1.7 ! root     4269:                 if (!(p = lock_user(VERIFY_WRITE, arg2, sizeof(target_siginfo_t), 0)))
1.1.1.6   root     4270:                     goto efault;
1.1.1.3   root     4271:                 host_to_target_siginfo(p, &uinfo);
1.1.1.7 ! root     4272:                 unlock_user(p, arg2, sizeof(target_siginfo_t));
1.1       root     4273:             }
                   4274:         }
                   4275:         break;
                   4276:     case TARGET_NR_rt_sigqueueinfo:
                   4277:         {
                   4278:             siginfo_t uinfo;
1.1.1.6   root     4279:             if (!(p = lock_user(VERIFY_READ, arg3, sizeof(target_sigset_t), 1)))
                   4280:                 goto efault;
1.1.1.3   root     4281:             target_to_host_siginfo(&uinfo, p);
                   4282:             unlock_user(p, arg1, 0);
1.1       root     4283:             ret = get_errno(sys_rt_sigqueueinfo(arg1, arg2, &uinfo));
                   4284:         }
                   4285:         break;
1.1.1.6   root     4286: #ifdef TARGET_NR_sigreturn
1.1       root     4287:     case TARGET_NR_sigreturn:
                   4288:         /* NOTE: ret is eax, so not transcoding must be done */
                   4289:         ret = do_sigreturn(cpu_env);
                   4290:         break;
1.1.1.6   root     4291: #endif
1.1       root     4292:     case TARGET_NR_rt_sigreturn:
                   4293:         /* NOTE: ret is eax, so not transcoding must be done */
                   4294:         ret = do_rt_sigreturn(cpu_env);
                   4295:         break;
                   4296:     case TARGET_NR_sethostname:
1.1.1.6   root     4297:         if (!(p = lock_user_string(arg1)))
                   4298:             goto efault;
1.1.1.3   root     4299:         ret = get_errno(sethostname(p, arg2));
                   4300:         unlock_user(p, arg1, 0);
1.1       root     4301:         break;
                   4302:     case TARGET_NR_setrlimit:
                   4303:         {
                   4304:             /* XXX: convert resource ? */
                   4305:             int resource = arg1;
1.1.1.3   root     4306:             struct target_rlimit *target_rlim;
1.1       root     4307:             struct rlimit rlim;
1.1.1.6   root     4308:             if (!lock_user_struct(VERIFY_READ, target_rlim, arg2, 1))
                   4309:                 goto efault;
1.1       root     4310:             rlim.rlim_cur = tswapl(target_rlim->rlim_cur);
                   4311:             rlim.rlim_max = tswapl(target_rlim->rlim_max);
1.1.1.3   root     4312:             unlock_user_struct(target_rlim, arg2, 0);
1.1       root     4313:             ret = get_errno(setrlimit(resource, &rlim));
                   4314:         }
                   4315:         break;
                   4316:     case TARGET_NR_getrlimit:
                   4317:         {
                   4318:             /* XXX: convert resource ? */
                   4319:             int resource = arg1;
1.1.1.3   root     4320:             struct target_rlimit *target_rlim;
1.1       root     4321:             struct rlimit rlim;
1.1.1.6   root     4322: 
1.1       root     4323:             ret = get_errno(getrlimit(resource, &rlim));
                   4324:             if (!is_error(ret)) {
1.1.1.6   root     4325:                 if (!lock_user_struct(VERIFY_WRITE, target_rlim, arg2, 0))
                   4326:                     goto efault;
1.1.1.3   root     4327:                 rlim.rlim_cur = tswapl(target_rlim->rlim_cur);
                   4328:                 rlim.rlim_max = tswapl(target_rlim->rlim_max);
                   4329:                 unlock_user_struct(target_rlim, arg2, 1);
1.1       root     4330:             }
                   4331:         }
                   4332:         break;
                   4333:     case TARGET_NR_getrusage:
                   4334:         {
                   4335:             struct rusage rusage;
                   4336:             ret = get_errno(getrusage(arg1, &rusage));
                   4337:             if (!is_error(ret)) {
1.1.1.3   root     4338:                 host_to_target_rusage(arg2, &rusage);
1.1       root     4339:             }
                   4340:         }
                   4341:         break;
                   4342:     case TARGET_NR_gettimeofday:
                   4343:         {
                   4344:             struct timeval tv;
                   4345:             ret = get_errno(gettimeofday(&tv, NULL));
                   4346:             if (!is_error(ret)) {
1.1.1.6   root     4347:                 if (copy_to_user_timeval(arg1, &tv))
                   4348:                     goto efault;
1.1       root     4349:             }
                   4350:         }
                   4351:         break;
                   4352:     case TARGET_NR_settimeofday:
                   4353:         {
                   4354:             struct timeval tv;
1.1.1.6   root     4355:             if (copy_from_user_timeval(&tv, arg1))
                   4356:                 goto efault;
1.1       root     4357:             ret = get_errno(settimeofday(&tv, NULL));
                   4358:         }
                   4359:         break;
1.1.1.2   root     4360: #ifdef TARGET_NR_select
1.1       root     4361:     case TARGET_NR_select:
                   4362:         {
1.1.1.3   root     4363:             struct target_sel_arg_struct *sel;
1.1.1.6   root     4364:             abi_ulong inp, outp, exp, tvp;
1.1.1.3   root     4365:             long nsel;
                   4366: 
1.1.1.6   root     4367:             if (!lock_user_struct(VERIFY_READ, sel, arg1, 1))
                   4368:                 goto efault;
1.1.1.3   root     4369:             nsel = tswapl(sel->n);
                   4370:             inp = tswapl(sel->inp);
                   4371:             outp = tswapl(sel->outp);
                   4372:             exp = tswapl(sel->exp);
                   4373:             tvp = tswapl(sel->tvp);
                   4374:             unlock_user_struct(sel, arg1, 0);
                   4375:             ret = do_select(nsel, inp, outp, exp, tvp);
1.1       root     4376:         }
                   4377:         break;
1.1.1.2   root     4378: #endif
1.1       root     4379:     case TARGET_NR_symlink:
1.1.1.3   root     4380:         {
                   4381:             void *p2;
                   4382:             p = lock_user_string(arg1);
                   4383:             p2 = lock_user_string(arg2);
1.1.1.6   root     4384:             if (!p || !p2)
                   4385:                 ret = -TARGET_EFAULT;
                   4386:             else
                   4387:                 ret = get_errno(symlink(p, p2));
1.1.1.3   root     4388:             unlock_user(p2, arg2, 0);
                   4389:             unlock_user(p, arg1, 0);
                   4390:         }
1.1       root     4391:         break;
1.1.1.6   root     4392: #if defined(TARGET_NR_symlinkat) && defined(__NR_symlinkat)
                   4393:     case TARGET_NR_symlinkat:
                   4394:         {
                   4395:             void *p2;
                   4396:             p  = lock_user_string(arg1);
                   4397:             p2 = lock_user_string(arg3);
                   4398:             if (!p || !p2)
                   4399:                 ret = -TARGET_EFAULT;
                   4400:             else
                   4401:                 ret = get_errno(sys_symlinkat(p, arg2, p2));
                   4402:             unlock_user(p2, arg3, 0);
                   4403:             unlock_user(p, arg1, 0);
                   4404:         }
                   4405:         break;
                   4406: #endif
1.1       root     4407: #ifdef TARGET_NR_oldlstat
                   4408:     case TARGET_NR_oldlstat:
                   4409:         goto unimplemented;
                   4410: #endif
                   4411:     case TARGET_NR_readlink:
1.1.1.3   root     4412:         {
1.1.1.7 ! root     4413:             void *p2, *temp;
1.1.1.3   root     4414:             p = lock_user_string(arg1);
1.1.1.6   root     4415:             p2 = lock_user(VERIFY_WRITE, arg2, arg3, 0);
                   4416:             if (!p || !p2)
                   4417:                 ret = -TARGET_EFAULT;
1.1.1.7 ! root     4418:             else {
        !          4419:                 if (strncmp((const char *)p, "/proc/self/exe", 14) == 0) {
        !          4420:                     char real[PATH_MAX];
        !          4421:                     temp = realpath(exec_path,real);
        !          4422:                     ret = (temp==NULL) ? get_errno(-1) : strlen(real) ;
        !          4423:                     snprintf((char *)p2, arg3, "%s", real);
        !          4424:                     }
        !          4425:                 else
        !          4426:                     ret = get_errno(readlink(path(p), p2, arg3));
        !          4427:             }
1.1.1.3   root     4428:             unlock_user(p2, arg2, ret);
                   4429:             unlock_user(p, arg1, 0);
                   4430:         }
1.1       root     4431:         break;
1.1.1.6   root     4432: #if defined(TARGET_NR_readlinkat) && defined(__NR_readlinkat)
                   4433:     case TARGET_NR_readlinkat:
                   4434:         {
                   4435:             void *p2;
                   4436:             p  = lock_user_string(arg2);
                   4437:             p2 = lock_user(VERIFY_WRITE, arg3, arg4, 0);
                   4438:             if (!p || !p2)
                   4439:                ret = -TARGET_EFAULT;
                   4440:             else
                   4441:                 ret = get_errno(sys_readlinkat(arg1, path(p), p2, arg4));
                   4442:             unlock_user(p2, arg3, ret);
                   4443:             unlock_user(p, arg2, 0);
                   4444:         }
                   4445:         break;
                   4446: #endif
                   4447: #ifdef TARGET_NR_uselib
1.1       root     4448:     case TARGET_NR_uselib:
                   4449:         goto unimplemented;
1.1.1.6   root     4450: #endif
                   4451: #ifdef TARGET_NR_swapon
1.1       root     4452:     case TARGET_NR_swapon:
1.1.1.6   root     4453:         if (!(p = lock_user_string(arg1)))
                   4454:             goto efault;
1.1.1.3   root     4455:         ret = get_errno(swapon(p, arg2));
                   4456:         unlock_user(p, arg1, 0);
1.1       root     4457:         break;
1.1.1.6   root     4458: #endif
1.1       root     4459:     case TARGET_NR_reboot:
                   4460:         goto unimplemented;
1.1.1.6   root     4461: #ifdef TARGET_NR_readdir
1.1       root     4462:     case TARGET_NR_readdir:
                   4463:         goto unimplemented;
1.1.1.6   root     4464: #endif
                   4465: #ifdef TARGET_NR_mmap
1.1       root     4466:     case TARGET_NR_mmap:
1.1.1.6   root     4467: #if (defined(TARGET_I386) && defined(TARGET_ABI32)) || defined(TARGET_ARM) || defined(TARGET_M68K) || defined(TARGET_CRIS)
1.1       root     4468:         {
1.1.1.6   root     4469:             abi_ulong *v;
                   4470:             abi_ulong v1, v2, v3, v4, v5, v6;
                   4471:             if (!(v = lock_user(VERIFY_READ, arg1, 6 * sizeof(abi_ulong), 1)))
                   4472:                 goto efault;
1.1.1.3   root     4473:             v1 = tswapl(v[0]);
                   4474:             v2 = tswapl(v[1]);
                   4475:             v3 = tswapl(v[2]);
                   4476:             v4 = tswapl(v[3]);
                   4477:             v5 = tswapl(v[4]);
                   4478:             v6 = tswapl(v[5]);
                   4479:             unlock_user(v, arg1, 0);
1.1.1.6   root     4480:             ret = get_errno(target_mmap(v1, v2, v3,
1.1       root     4481:                                         target_to_host_bitmask(v4, mmap_flags_tbl),
                   4482:                                         v5, v6));
                   4483:         }
                   4484: #else
1.1.1.6   root     4485:         ret = get_errno(target_mmap(arg1, arg2, arg3,
                   4486:                                     target_to_host_bitmask(arg4, mmap_flags_tbl),
1.1       root     4487:                                     arg5,
                   4488:                                     arg6));
                   4489: #endif
                   4490:         break;
1.1.1.6   root     4491: #endif
1.1       root     4492: #ifdef TARGET_NR_mmap2
                   4493:     case TARGET_NR_mmap2:
1.1.1.7 ! root     4494: #ifndef MMAP_SHIFT
1.1       root     4495: #define MMAP_SHIFT 12
                   4496: #endif
1.1.1.6   root     4497:         ret = get_errno(target_mmap(arg1, arg2, arg3,
                   4498:                                     target_to_host_bitmask(arg4, mmap_flags_tbl),
1.1       root     4499:                                     arg5,
                   4500:                                     arg6 << MMAP_SHIFT));
                   4501:         break;
                   4502: #endif
                   4503:     case TARGET_NR_munmap:
                   4504:         ret = get_errno(target_munmap(arg1, arg2));
                   4505:         break;
                   4506:     case TARGET_NR_mprotect:
                   4507:         ret = get_errno(target_mprotect(arg1, arg2, arg3));
                   4508:         break;
1.1.1.6   root     4509: #ifdef TARGET_NR_mremap
1.1       root     4510:     case TARGET_NR_mremap:
                   4511:         ret = get_errno(target_mremap(arg1, arg2, arg3, arg4, arg5));
                   4512:         break;
1.1.1.6   root     4513: #endif
1.1.1.3   root     4514:         /* ??? msync/mlock/munlock are broken for softmmu.  */
1.1.1.6   root     4515: #ifdef TARGET_NR_msync
1.1       root     4516:     case TARGET_NR_msync:
1.1.1.3   root     4517:         ret = get_errno(msync(g2h(arg1), arg2, arg3));
1.1       root     4518:         break;
1.1.1.6   root     4519: #endif
                   4520: #ifdef TARGET_NR_mlock
1.1       root     4521:     case TARGET_NR_mlock:
1.1.1.3   root     4522:         ret = get_errno(mlock(g2h(arg1), arg2));
1.1       root     4523:         break;
1.1.1.6   root     4524: #endif
                   4525: #ifdef TARGET_NR_munlock
1.1       root     4526:     case TARGET_NR_munlock:
1.1.1.3   root     4527:         ret = get_errno(munlock(g2h(arg1), arg2));
1.1       root     4528:         break;
1.1.1.6   root     4529: #endif
                   4530: #ifdef TARGET_NR_mlockall
1.1       root     4531:     case TARGET_NR_mlockall:
                   4532:         ret = get_errno(mlockall(arg1));
                   4533:         break;
1.1.1.6   root     4534: #endif
                   4535: #ifdef TARGET_NR_munlockall
1.1       root     4536:     case TARGET_NR_munlockall:
                   4537:         ret = get_errno(munlockall());
                   4538:         break;
1.1.1.6   root     4539: #endif
1.1       root     4540:     case TARGET_NR_truncate:
1.1.1.6   root     4541:         if (!(p = lock_user_string(arg1)))
                   4542:             goto efault;
1.1.1.3   root     4543:         ret = get_errno(truncate(p, arg2));
                   4544:         unlock_user(p, arg1, 0);
1.1       root     4545:         break;
                   4546:     case TARGET_NR_ftruncate:
                   4547:         ret = get_errno(ftruncate(arg1, arg2));
                   4548:         break;
                   4549:     case TARGET_NR_fchmod:
                   4550:         ret = get_errno(fchmod(arg1, arg2));
                   4551:         break;
1.1.1.6   root     4552: #if defined(TARGET_NR_fchmodat) && defined(__NR_fchmodat)
                   4553:     case TARGET_NR_fchmodat:
                   4554:         if (!(p = lock_user_string(arg2)))
                   4555:             goto efault;
                   4556:         ret = get_errno(sys_fchmodat(arg1, p, arg3, arg4));
                   4557:         unlock_user(p, arg2, 0);
                   4558:         break;
                   4559: #endif
1.1       root     4560:     case TARGET_NR_getpriority:
1.1.1.6   root     4561:         /* libc does special remapping of the return value of
                   4562:          * sys_getpriority() so it's just easiest to call
                   4563:          * sys_getpriority() directly rather than through libc. */
                   4564:         ret = sys_getpriority(arg1, arg2);
1.1       root     4565:         break;
                   4566:     case TARGET_NR_setpriority:
                   4567:         ret = get_errno(setpriority(arg1, arg2, arg3));
                   4568:         break;
                   4569: #ifdef TARGET_NR_profil
                   4570:     case TARGET_NR_profil:
                   4571:         goto unimplemented;
                   4572: #endif
                   4573:     case TARGET_NR_statfs:
1.1.1.6   root     4574:         if (!(p = lock_user_string(arg1)))
                   4575:             goto efault;
1.1.1.3   root     4576:         ret = get_errno(statfs(path(p), &stfs));
                   4577:         unlock_user(p, arg1, 0);
1.1       root     4578:     convert_statfs:
                   4579:         if (!is_error(ret)) {
1.1.1.3   root     4580:             struct target_statfs *target_stfs;
1.1.1.6   root     4581: 
                   4582:             if (!lock_user_struct(VERIFY_WRITE, target_stfs, arg2, 0))
                   4583:                 goto efault;
                   4584:             __put_user(stfs.f_type, &target_stfs->f_type);
                   4585:             __put_user(stfs.f_bsize, &target_stfs->f_bsize);
                   4586:             __put_user(stfs.f_blocks, &target_stfs->f_blocks);
                   4587:             __put_user(stfs.f_bfree, &target_stfs->f_bfree);
                   4588:             __put_user(stfs.f_bavail, &target_stfs->f_bavail);
                   4589:             __put_user(stfs.f_files, &target_stfs->f_files);
                   4590:             __put_user(stfs.f_ffree, &target_stfs->f_ffree);
                   4591:             __put_user(stfs.f_fsid.__val[0], &target_stfs->f_fsid.val[0]);
                   4592:             __put_user(stfs.f_fsid.__val[1], &target_stfs->f_fsid.val[1]);
                   4593:             __put_user(stfs.f_namelen, &target_stfs->f_namelen);
1.1.1.3   root     4594:             unlock_user_struct(target_stfs, arg2, 1);
1.1       root     4595:         }
                   4596:         break;
                   4597:     case TARGET_NR_fstatfs:
1.1.1.2   root     4598:         ret = get_errno(fstatfs(arg1, &stfs));
1.1       root     4599:         goto convert_statfs;
1.1.1.2   root     4600: #ifdef TARGET_NR_statfs64
                   4601:     case TARGET_NR_statfs64:
1.1.1.6   root     4602:         if (!(p = lock_user_string(arg1)))
                   4603:             goto efault;
1.1.1.3   root     4604:         ret = get_errno(statfs(path(p), &stfs));
                   4605:         unlock_user(p, arg1, 0);
1.1.1.2   root     4606:     convert_statfs64:
                   4607:         if (!is_error(ret)) {
1.1.1.3   root     4608:             struct target_statfs64 *target_stfs;
1.1.1.6   root     4609: 
                   4610:             if (!lock_user_struct(VERIFY_WRITE, target_stfs, arg3, 0))
                   4611:                 goto efault;
                   4612:             __put_user(stfs.f_type, &target_stfs->f_type);
                   4613:             __put_user(stfs.f_bsize, &target_stfs->f_bsize);
                   4614:             __put_user(stfs.f_blocks, &target_stfs->f_blocks);
                   4615:             __put_user(stfs.f_bfree, &target_stfs->f_bfree);
                   4616:             __put_user(stfs.f_bavail, &target_stfs->f_bavail);
                   4617:             __put_user(stfs.f_files, &target_stfs->f_files);
                   4618:             __put_user(stfs.f_ffree, &target_stfs->f_ffree);
                   4619:             __put_user(stfs.f_fsid.__val[0], &target_stfs->f_fsid.val[0]);
                   4620:             __put_user(stfs.f_fsid.__val[1], &target_stfs->f_fsid.val[1]);
                   4621:             __put_user(stfs.f_namelen, &target_stfs->f_namelen);
                   4622:             unlock_user_struct(target_stfs, arg3, 1);
1.1.1.2   root     4623:         }
                   4624:         break;
                   4625:     case TARGET_NR_fstatfs64:
                   4626:         ret = get_errno(fstatfs(arg1, &stfs));
                   4627:         goto convert_statfs64;
                   4628: #endif
1.1       root     4629: #ifdef TARGET_NR_ioperm
                   4630:     case TARGET_NR_ioperm:
                   4631:         goto unimplemented;
                   4632: #endif
1.1.1.6   root     4633: #ifdef TARGET_NR_socketcall
1.1       root     4634:     case TARGET_NR_socketcall:
1.1.1.3   root     4635:         ret = do_socketcall(arg1, arg2);
1.1       root     4636:         break;
1.1.1.6   root     4637: #endif
1.1.1.4   root     4638: #ifdef TARGET_NR_accept
                   4639:     case TARGET_NR_accept:
1.1.1.5   root     4640:         ret = do_accept(arg1, arg2, arg3);
1.1.1.4   root     4641:         break;
                   4642: #endif
                   4643: #ifdef TARGET_NR_bind
                   4644:     case TARGET_NR_bind:
                   4645:         ret = do_bind(arg1, arg2, arg3);
                   4646:         break;
                   4647: #endif
                   4648: #ifdef TARGET_NR_connect
                   4649:     case TARGET_NR_connect:
                   4650:         ret = do_connect(arg1, arg2, arg3);
                   4651:         break;
                   4652: #endif
                   4653: #ifdef TARGET_NR_getpeername
                   4654:     case TARGET_NR_getpeername:
1.1.1.5   root     4655:         ret = do_getpeername(arg1, arg2, arg3);
1.1.1.4   root     4656:         break;
                   4657: #endif
                   4658: #ifdef TARGET_NR_getsockname
                   4659:     case TARGET_NR_getsockname:
1.1.1.5   root     4660:         ret = do_getsockname(arg1, arg2, arg3);
1.1.1.4   root     4661:         break;
                   4662: #endif
                   4663: #ifdef TARGET_NR_getsockopt
                   4664:     case TARGET_NR_getsockopt:
                   4665:         ret = do_getsockopt(arg1, arg2, arg3, arg4, arg5);
                   4666:         break;
                   4667: #endif
                   4668: #ifdef TARGET_NR_listen
                   4669:     case TARGET_NR_listen:
1.1.1.5   root     4670:         ret = get_errno(listen(arg1, arg2));
1.1.1.4   root     4671:         break;
                   4672: #endif
                   4673: #ifdef TARGET_NR_recv
                   4674:     case TARGET_NR_recv:
1.1.1.6   root     4675:         ret = do_recvfrom(arg1, arg2, arg3, arg4, 0, 0);
1.1.1.4   root     4676:         break;
                   4677: #endif
                   4678: #ifdef TARGET_NR_recvfrom
                   4679:     case TARGET_NR_recvfrom:
1.1.1.6   root     4680:         ret = do_recvfrom(arg1, arg2, arg3, arg4, arg5, arg6);
1.1.1.4   root     4681:         break;
                   4682: #endif
                   4683: #ifdef TARGET_NR_recvmsg
                   4684:     case TARGET_NR_recvmsg:
                   4685:         ret = do_sendrecvmsg(arg1, arg2, arg3, 0);
                   4686:         break;
                   4687: #endif
                   4688: #ifdef TARGET_NR_send
                   4689:     case TARGET_NR_send:
1.1.1.5   root     4690:         ret = do_sendto(arg1, arg2, arg3, arg4, 0, 0);
1.1.1.4   root     4691:         break;
                   4692: #endif
                   4693: #ifdef TARGET_NR_sendmsg
                   4694:     case TARGET_NR_sendmsg:
                   4695:         ret = do_sendrecvmsg(arg1, arg2, arg3, 1);
                   4696:         break;
                   4697: #endif
                   4698: #ifdef TARGET_NR_sendto
                   4699:     case TARGET_NR_sendto:
1.1.1.5   root     4700:         ret = do_sendto(arg1, arg2, arg3, arg4, arg5, arg6);
1.1.1.4   root     4701:         break;
                   4702: #endif
                   4703: #ifdef TARGET_NR_shutdown
                   4704:     case TARGET_NR_shutdown:
1.1.1.5   root     4705:         ret = get_errno(shutdown(arg1, arg2));
1.1.1.4   root     4706:         break;
                   4707: #endif
                   4708: #ifdef TARGET_NR_socket
                   4709:     case TARGET_NR_socket:
                   4710:         ret = do_socket(arg1, arg2, arg3);
                   4711:         break;
                   4712: #endif
                   4713: #ifdef TARGET_NR_socketpair
                   4714:     case TARGET_NR_socketpair:
1.1.1.5   root     4715:         ret = do_socketpair(arg1, arg2, arg3, arg4);
1.1.1.4   root     4716:         break;
                   4717: #endif
                   4718: #ifdef TARGET_NR_setsockopt
                   4719:     case TARGET_NR_setsockopt:
                   4720:         ret = do_setsockopt(arg1, arg2, arg3, arg4, (socklen_t) arg5);
                   4721:         break;
                   4722: #endif
1.1.1.6   root     4723: 
1.1       root     4724:     case TARGET_NR_syslog:
1.1.1.6   root     4725:         if (!(p = lock_user_string(arg2)))
                   4726:             goto efault;
                   4727:         ret = get_errno(sys_syslog((int)arg1, p, (int)arg3));
                   4728:         unlock_user(p, arg2, 0);
                   4729:         break;
                   4730: 
1.1       root     4731:     case TARGET_NR_setitimer:
                   4732:         {
                   4733:             struct itimerval value, ovalue, *pvalue;
                   4734: 
1.1.1.3   root     4735:             if (arg2) {
1.1       root     4736:                 pvalue = &value;
1.1.1.6   root     4737:                 if (copy_from_user_timeval(&pvalue->it_interval, arg2)
                   4738:                     || copy_from_user_timeval(&pvalue->it_value,
                   4739:                                               arg2 + sizeof(struct target_timeval)))
                   4740:                     goto efault;
1.1       root     4741:             } else {
                   4742:                 pvalue = NULL;
                   4743:             }
                   4744:             ret = get_errno(setitimer(arg1, pvalue, &ovalue));
1.1.1.3   root     4745:             if (!is_error(ret) && arg3) {
1.1.1.6   root     4746:                 if (copy_to_user_timeval(arg3,
                   4747:                                          &ovalue.it_interval)
                   4748:                     || copy_to_user_timeval(arg3 + sizeof(struct target_timeval),
                   4749:                                             &ovalue.it_value))
                   4750:                     goto efault;
1.1       root     4751:             }
                   4752:         }
                   4753:         break;
                   4754:     case TARGET_NR_getitimer:
                   4755:         {
                   4756:             struct itimerval value;
1.1.1.6   root     4757: 
1.1       root     4758:             ret = get_errno(getitimer(arg1, &value));
1.1.1.3   root     4759:             if (!is_error(ret) && arg2) {
1.1.1.6   root     4760:                 if (copy_to_user_timeval(arg2,
                   4761:                                          &value.it_interval)
                   4762:                     || copy_to_user_timeval(arg2 + sizeof(struct target_timeval),
                   4763:                                             &value.it_value))
                   4764:                     goto efault;
1.1       root     4765:             }
                   4766:         }
                   4767:         break;
                   4768:     case TARGET_NR_stat:
1.1.1.6   root     4769:         if (!(p = lock_user_string(arg1)))
                   4770:             goto efault;
1.1.1.3   root     4771:         ret = get_errno(stat(path(p), &st));
                   4772:         unlock_user(p, arg1, 0);
1.1       root     4773:         goto do_stat;
                   4774:     case TARGET_NR_lstat:
1.1.1.6   root     4775:         if (!(p = lock_user_string(arg1)))
                   4776:             goto efault;
1.1.1.3   root     4777:         ret = get_errno(lstat(path(p), &st));
                   4778:         unlock_user(p, arg1, 0);
1.1       root     4779:         goto do_stat;
                   4780:     case TARGET_NR_fstat:
                   4781:         {
                   4782:             ret = get_errno(fstat(arg1, &st));
                   4783:         do_stat:
                   4784:             if (!is_error(ret)) {
1.1.1.3   root     4785:                 struct target_stat *target_st;
1.1.1.6   root     4786: 
                   4787:                 if (!lock_user_struct(VERIFY_WRITE, target_st, arg2, 0))
                   4788:                     goto efault;
                   4789:                 __put_user(st.st_dev, &target_st->st_dev);
                   4790:                 __put_user(st.st_ino, &target_st->st_ino);
                   4791:                 __put_user(st.st_mode, &target_st->st_mode);
                   4792:                 __put_user(st.st_uid, &target_st->st_uid);
                   4793:                 __put_user(st.st_gid, &target_st->st_gid);
                   4794:                 __put_user(st.st_nlink, &target_st->st_nlink);
                   4795:                 __put_user(st.st_rdev, &target_st->st_rdev);
                   4796:                 __put_user(st.st_size, &target_st->st_size);
                   4797:                 __put_user(st.st_blksize, &target_st->st_blksize);
                   4798:                 __put_user(st.st_blocks, &target_st->st_blocks);
                   4799:                 __put_user(st.st_atime, &target_st->target_st_atime);
                   4800:                 __put_user(st.st_mtime, &target_st->target_st_mtime);
                   4801:                 __put_user(st.st_ctime, &target_st->target_st_ctime);
1.1.1.3   root     4802:                 unlock_user_struct(target_st, arg2, 1);
1.1       root     4803:             }
                   4804:         }
                   4805:         break;
                   4806: #ifdef TARGET_NR_olduname
                   4807:     case TARGET_NR_olduname:
                   4808:         goto unimplemented;
                   4809: #endif
                   4810: #ifdef TARGET_NR_iopl
                   4811:     case TARGET_NR_iopl:
                   4812:         goto unimplemented;
                   4813: #endif
                   4814:     case TARGET_NR_vhangup:
                   4815:         ret = get_errno(vhangup());
                   4816:         break;
                   4817: #ifdef TARGET_NR_idle
                   4818:     case TARGET_NR_idle:
                   4819:         goto unimplemented;
                   4820: #endif
                   4821: #ifdef TARGET_NR_syscall
                   4822:     case TARGET_NR_syscall:
                   4823:        ret = do_syscall(cpu_env,arg1 & 0xffff,arg2,arg3,arg4,arg5,arg6,0);
                   4824:        break;
                   4825: #endif
                   4826:     case TARGET_NR_wait4:
                   4827:         {
                   4828:             int status;
1.1.1.6   root     4829:             abi_long status_ptr = arg2;
1.1       root     4830:             struct rusage rusage, *rusage_ptr;
1.1.1.6   root     4831:             abi_ulong target_rusage = arg4;
1.1       root     4832:             if (target_rusage)
                   4833:                 rusage_ptr = &rusage;
                   4834:             else
                   4835:                 rusage_ptr = NULL;
                   4836:             ret = get_errno(wait4(arg1, &status, arg3, rusage_ptr));
                   4837:             if (!is_error(ret)) {
1.1.1.6   root     4838:                 if (status_ptr) {
                   4839:                     if (put_user_s32(status, status_ptr))
                   4840:                         goto efault;
1.1       root     4841:                 }
1.1.1.6   root     4842:                 if (target_rusage)
                   4843:                     host_to_target_rusage(target_rusage, &rusage);
1.1       root     4844:             }
                   4845:         }
                   4846:         break;
1.1.1.6   root     4847: #ifdef TARGET_NR_swapoff
1.1       root     4848:     case TARGET_NR_swapoff:
1.1.1.6   root     4849:         if (!(p = lock_user_string(arg1)))
                   4850:             goto efault;
1.1.1.3   root     4851:         ret = get_errno(swapoff(p));
                   4852:         unlock_user(p, arg1, 0);
1.1       root     4853:         break;
1.1.1.6   root     4854: #endif
1.1       root     4855:     case TARGET_NR_sysinfo:
                   4856:         {
1.1.1.3   root     4857:             struct target_sysinfo *target_value;
1.1       root     4858:             struct sysinfo value;
                   4859:             ret = get_errno(sysinfo(&value));
1.1.1.3   root     4860:             if (!is_error(ret) && arg1)
1.1       root     4861:             {
1.1.1.6   root     4862:                 if (!lock_user_struct(VERIFY_WRITE, target_value, arg1, 0))
                   4863:                     goto efault;
1.1       root     4864:                 __put_user(value.uptime, &target_value->uptime);
                   4865:                 __put_user(value.loads[0], &target_value->loads[0]);
                   4866:                 __put_user(value.loads[1], &target_value->loads[1]);
                   4867:                 __put_user(value.loads[2], &target_value->loads[2]);
                   4868:                 __put_user(value.totalram, &target_value->totalram);
                   4869:                 __put_user(value.freeram, &target_value->freeram);
                   4870:                 __put_user(value.sharedram, &target_value->sharedram);
                   4871:                 __put_user(value.bufferram, &target_value->bufferram);
                   4872:                 __put_user(value.totalswap, &target_value->totalswap);
                   4873:                 __put_user(value.freeswap, &target_value->freeswap);
                   4874:                 __put_user(value.procs, &target_value->procs);
                   4875:                 __put_user(value.totalhigh, &target_value->totalhigh);
                   4876:                 __put_user(value.freehigh, &target_value->freehigh);
                   4877:                 __put_user(value.mem_unit, &target_value->mem_unit);
1.1.1.3   root     4878:                 unlock_user_struct(target_value, arg1, 1);
1.1       root     4879:             }
                   4880:         }
                   4881:         break;
1.1.1.6   root     4882: #ifdef TARGET_NR_ipc
1.1       root     4883:     case TARGET_NR_ipc:
                   4884:        ret = do_ipc(arg1, arg2, arg3, arg4, arg5, arg6);
                   4885:        break;
1.1.1.6   root     4886: #endif
1.1.1.7 ! root     4887: 
        !          4888: #ifdef TARGET_NR_msgctl
        !          4889:     case TARGET_NR_msgctl:
        !          4890:         ret = do_msgctl(arg1, arg2, arg3);
        !          4891:         break;
        !          4892: #endif
        !          4893: #ifdef TARGET_NR_msgget
        !          4894:     case TARGET_NR_msgget:
        !          4895:         ret = get_errno(msgget(arg1, arg2));
        !          4896:         break;
        !          4897: #endif
        !          4898: #ifdef TARGET_NR_msgrcv
        !          4899:     case TARGET_NR_msgrcv:
        !          4900:         ret = do_msgrcv(arg1, arg2, arg3, arg4, arg5);
        !          4901:         break;
        !          4902: #endif
        !          4903: #ifdef TARGET_NR_msgsnd
        !          4904:     case TARGET_NR_msgsnd:
        !          4905:         ret = do_msgsnd(arg1, arg2, arg3, arg4);
        !          4906:         break;
        !          4907: #endif
1.1       root     4908:     case TARGET_NR_fsync:
                   4909:         ret = get_errno(fsync(arg1));
                   4910:         break;
                   4911:     case TARGET_NR_clone:
1.1.1.7 ! root     4912: #if defined(TARGET_SH4)
        !          4913:         ret = get_errno(do_fork(cpu_env, arg1, arg2, arg3, arg5, arg4));
        !          4914: #elif defined(TARGET_CRIS)
        !          4915:         ret = get_errno(do_fork(cpu_env, arg2, arg1, arg3, arg4, arg5));
        !          4916: #else
        !          4917:         ret = get_errno(do_fork(cpu_env, arg1, arg2, arg3, arg4, arg5));
        !          4918: #endif
1.1       root     4919:         break;
                   4920: #ifdef __NR_exit_group
                   4921:         /* new thread calls */
                   4922:     case TARGET_NR_exit_group:
1.1.1.7 ! root     4923: #ifdef HAVE_GPROF
        !          4924:         _mcleanup();
        !          4925: #endif
1.1       root     4926:         gdb_exit(cpu_env, arg1);
                   4927:         ret = get_errno(exit_group(arg1));
                   4928:         break;
                   4929: #endif
                   4930:     case TARGET_NR_setdomainname:
1.1.1.6   root     4931:         if (!(p = lock_user_string(arg1)))
                   4932:             goto efault;
1.1.1.3   root     4933:         ret = get_errno(setdomainname(p, arg2));
                   4934:         unlock_user(p, arg1, 0);
1.1       root     4935:         break;
                   4936:     case TARGET_NR_uname:
                   4937:         /* no need to transcode because we use the linux syscall */
                   4938:         {
                   4939:             struct new_utsname * buf;
1.1.1.6   root     4940: 
                   4941:             if (!lock_user_struct(VERIFY_WRITE, buf, arg1, 0))
                   4942:                 goto efault;
1.1       root     4943:             ret = get_errno(sys_uname(buf));
                   4944:             if (!is_error(ret)) {
                   4945:                 /* Overrite the native machine name with whatever is being
                   4946:                    emulated. */
                   4947:                 strcpy (buf->machine, UNAME_MACHINE);
1.1.1.4   root     4948:                 /* Allow the user to override the reported release.  */
                   4949:                 if (qemu_uname_release && *qemu_uname_release)
                   4950:                   strcpy (buf->release, qemu_uname_release);
1.1       root     4951:             }
1.1.1.3   root     4952:             unlock_user_struct(buf, arg1, 1);
1.1       root     4953:         }
                   4954:         break;
                   4955: #ifdef TARGET_I386
                   4956:     case TARGET_NR_modify_ldt:
1.1.1.6   root     4957:         ret = do_modify_ldt(cpu_env, arg1, arg2, arg3);
1.1       root     4958:         break;
1.1.1.6   root     4959: #if !defined(TARGET_X86_64)
1.1       root     4960:     case TARGET_NR_vm86old:
                   4961:         goto unimplemented;
                   4962:     case TARGET_NR_vm86:
1.1.1.3   root     4963:         ret = do_vm86(cpu_env, arg1, arg2);
1.1       root     4964:         break;
                   4965: #endif
1.1.1.6   root     4966: #endif
1.1       root     4967:     case TARGET_NR_adjtimex:
                   4968:         goto unimplemented;
1.1.1.6   root     4969: #ifdef TARGET_NR_create_module
1.1       root     4970:     case TARGET_NR_create_module:
1.1.1.6   root     4971: #endif
1.1       root     4972:     case TARGET_NR_init_module:
                   4973:     case TARGET_NR_delete_module:
1.1.1.6   root     4974: #ifdef TARGET_NR_get_kernel_syms
1.1       root     4975:     case TARGET_NR_get_kernel_syms:
1.1.1.6   root     4976: #endif
1.1       root     4977:         goto unimplemented;
                   4978:     case TARGET_NR_quotactl:
                   4979:         goto unimplemented;
                   4980:     case TARGET_NR_getpgid:
                   4981:         ret = get_errno(getpgid(arg1));
                   4982:         break;
                   4983:     case TARGET_NR_fchdir:
                   4984:         ret = get_errno(fchdir(arg1));
                   4985:         break;
1.1.1.6   root     4986: #ifdef TARGET_NR_bdflush /* not on x86_64 */
1.1       root     4987:     case TARGET_NR_bdflush:
                   4988:         goto unimplemented;
1.1.1.6   root     4989: #endif
                   4990: #ifdef TARGET_NR_sysfs
1.1       root     4991:     case TARGET_NR_sysfs:
                   4992:         goto unimplemented;
1.1.1.6   root     4993: #endif
1.1       root     4994:     case TARGET_NR_personality:
                   4995:         ret = get_errno(personality(arg1));
                   4996:         break;
1.1.1.6   root     4997: #ifdef TARGET_NR_afs_syscall
1.1       root     4998:     case TARGET_NR_afs_syscall:
                   4999:         goto unimplemented;
1.1.1.6   root     5000: #endif
                   5001: #ifdef TARGET_NR__llseek /* Not on alpha */
1.1       root     5002:     case TARGET_NR__llseek:
                   5003:         {
                   5004: #if defined (__x86_64__)
                   5005:             ret = get_errno(lseek(arg1, ((uint64_t )arg2 << 32) | arg3, arg5));
1.1.1.6   root     5006:             if (put_user_s64(ret, arg4))
                   5007:                 goto efault;
1.1       root     5008: #else
                   5009:             int64_t res;
                   5010:             ret = get_errno(_llseek(arg1, arg2, arg3, &res, arg5));
1.1.1.6   root     5011:             if (put_user_s64(res, arg4))
                   5012:                 goto efault;
1.1       root     5013: #endif
                   5014:         }
                   5015:         break;
1.1.1.6   root     5016: #endif
1.1       root     5017:     case TARGET_NR_getdents:
1.1.1.6   root     5018: #if TARGET_ABI_BITS != 32
1.1.1.3   root     5019:         goto unimplemented;
1.1.1.6   root     5020: #elif TARGET_ABI_BITS == 32 && HOST_LONG_BITS == 64
1.1       root     5021:         {
1.1.1.3   root     5022:             struct target_dirent *target_dirp;
1.1.1.7 ! root     5023:             struct linux_dirent *dirp;
1.1.1.6   root     5024:             abi_long count = arg3;
1.1       root     5025: 
                   5026:            dirp = malloc(count);
1.1.1.6   root     5027:            if (!dirp) {
                   5028:                 ret = -TARGET_ENOMEM;
                   5029:                 goto fail;
                   5030:             }
                   5031: 
1.1       root     5032:             ret = get_errno(sys_getdents(arg1, dirp, count));
                   5033:             if (!is_error(ret)) {
1.1.1.7 ! root     5034:                 struct linux_dirent *de;
1.1       root     5035:                struct target_dirent *tde;
                   5036:                 int len = ret;
                   5037:                 int reclen, treclen;
                   5038:                int count1, tnamelen;
                   5039: 
                   5040:                count1 = 0;
                   5041:                 de = dirp;
1.1.1.6   root     5042:                 if (!(target_dirp = lock_user(VERIFY_WRITE, arg2, count, 0)))
                   5043:                     goto efault;
1.1       root     5044:                tde = target_dirp;
                   5045:                 while (len > 0) {
                   5046:                     reclen = de->d_reclen;
1.1.1.6   root     5047:                    treclen = reclen - (2 * (sizeof(long) - sizeof(abi_long)));
1.1       root     5048:                     tde->d_reclen = tswap16(treclen);
                   5049:                     tde->d_ino = tswapl(de->d_ino);
                   5050:                     tde->d_off = tswapl(de->d_off);
1.1.1.6   root     5051:                    tnamelen = treclen - (2 * sizeof(abi_long) + 2);
1.1       root     5052:                    if (tnamelen > 256)
                   5053:                         tnamelen = 256;
                   5054:                     /* XXX: may not be correct */
1.1.1.7 ! root     5055:                     pstrcpy(tde->d_name, tnamelen, de->d_name);
        !          5056:                     de = (struct linux_dirent *)((char *)de + reclen);
1.1       root     5057:                     len -= reclen;
1.1.1.6   root     5058:                     tde = (struct target_dirent *)((char *)tde + treclen);
1.1       root     5059:                    count1 += treclen;
                   5060:                 }
                   5061:                ret = count1;
1.1.1.6   root     5062:                 unlock_user(target_dirp, arg2, ret);
1.1       root     5063:             }
                   5064:            free(dirp);
                   5065:         }
                   5066: #else
                   5067:         {
1.1.1.7 ! root     5068:             struct linux_dirent *dirp;
1.1.1.6   root     5069:             abi_long count = arg3;
1.1       root     5070: 
1.1.1.6   root     5071:             if (!(dirp = lock_user(VERIFY_WRITE, arg2, count, 0)))
                   5072:                 goto efault;
1.1       root     5073:             ret = get_errno(sys_getdents(arg1, dirp, count));
                   5074:             if (!is_error(ret)) {
1.1.1.7 ! root     5075:                 struct linux_dirent *de;
1.1       root     5076:                 int len = ret;
                   5077:                 int reclen;
                   5078:                 de = dirp;
                   5079:                 while (len > 0) {
                   5080:                     reclen = de->d_reclen;
                   5081:                     if (reclen > len)
                   5082:                         break;
                   5083:                     de->d_reclen = tswap16(reclen);
                   5084:                     tswapls(&de->d_ino);
                   5085:                     tswapls(&de->d_off);
1.1.1.7 ! root     5086:                     de = (struct linux_dirent *)((char *)de + reclen);
1.1       root     5087:                     len -= reclen;
                   5088:                 }
                   5089:             }
1.1.1.3   root     5090:             unlock_user(dirp, arg2, ret);
1.1       root     5091:         }
                   5092: #endif
                   5093:         break;
1.1.1.6   root     5094: #if defined(TARGET_NR_getdents64) && defined(__NR_getdents64)
1.1       root     5095:     case TARGET_NR_getdents64:
                   5096:         {
1.1.1.7 ! root     5097:             struct linux_dirent64 *dirp;
1.1.1.6   root     5098:             abi_long count = arg3;
                   5099:             if (!(dirp = lock_user(VERIFY_WRITE, arg2, count, 0)))
                   5100:                 goto efault;
1.1       root     5101:             ret = get_errno(sys_getdents64(arg1, dirp, count));
                   5102:             if (!is_error(ret)) {
1.1.1.7 ! root     5103:                 struct linux_dirent64 *de;
1.1       root     5104:                 int len = ret;
                   5105:                 int reclen;
                   5106:                 de = dirp;
                   5107:                 while (len > 0) {
                   5108:                     reclen = de->d_reclen;
                   5109:                     if (reclen > len)
                   5110:                         break;
                   5111:                     de->d_reclen = tswap16(reclen);
1.1.1.6   root     5112:                     tswap64s((uint64_t *)&de->d_ino);
                   5113:                     tswap64s((uint64_t *)&de->d_off);
1.1.1.7 ! root     5114:                     de = (struct linux_dirent64 *)((char *)de + reclen);
1.1       root     5115:                     len -= reclen;
                   5116:                 }
                   5117:             }
1.1.1.3   root     5118:             unlock_user(dirp, arg2, ret);
1.1       root     5119:         }
                   5120:         break;
                   5121: #endif /* TARGET_NR_getdents64 */
1.1.1.6   root     5122: #ifdef TARGET_NR__newselect
1.1       root     5123:     case TARGET_NR__newselect:
1.1.1.3   root     5124:         ret = do_select(arg1, arg2, arg3, arg4, arg5);
1.1       root     5125:         break;
1.1.1.6   root     5126: #endif
                   5127: #ifdef TARGET_NR_poll
1.1       root     5128:     case TARGET_NR_poll:
                   5129:         {
1.1.1.3   root     5130:             struct target_pollfd *target_pfd;
1.1       root     5131:             unsigned int nfds = arg2;
                   5132:             int timeout = arg3;
                   5133:             struct pollfd *pfd;
                   5134:             unsigned int i;
                   5135: 
1.1.1.6   root     5136:             target_pfd = lock_user(VERIFY_WRITE, arg1, sizeof(struct target_pollfd) * nfds, 1);
                   5137:             if (!target_pfd)
                   5138:                 goto efault;
1.1       root     5139:             pfd = alloca(sizeof(struct pollfd) * nfds);
                   5140:             for(i = 0; i < nfds; i++) {
                   5141:                 pfd[i].fd = tswap32(target_pfd[i].fd);
                   5142:                 pfd[i].events = tswap16(target_pfd[i].events);
                   5143:             }
                   5144:             ret = get_errno(poll(pfd, nfds, timeout));
                   5145:             if (!is_error(ret)) {
                   5146:                 for(i = 0; i < nfds; i++) {
                   5147:                     target_pfd[i].revents = tswap16(pfd[i].revents);
                   5148:                 }
1.1.1.3   root     5149:                 ret += nfds * (sizeof(struct target_pollfd)
                   5150:                                - sizeof(struct pollfd));
1.1       root     5151:             }
1.1.1.3   root     5152:             unlock_user(target_pfd, arg1, ret);
1.1       root     5153:         }
                   5154:         break;
1.1.1.6   root     5155: #endif
1.1       root     5156:     case TARGET_NR_flock:
                   5157:         /* NOTE: the flock constant seems to be the same for every
                   5158:            Linux platform */
                   5159:         ret = get_errno(flock(arg1, arg2));
                   5160:         break;
                   5161:     case TARGET_NR_readv:
                   5162:         {
                   5163:             int count = arg3;
                   5164:             struct iovec *vec;
                   5165: 
                   5166:             vec = alloca(count * sizeof(struct iovec));
1.1.1.7 ! root     5167:             if (lock_iovec(VERIFY_WRITE, vec, arg2, count, 0) < 0)
        !          5168:                 goto efault;
1.1       root     5169:             ret = get_errno(readv(arg1, vec, count));
1.1.1.3   root     5170:             unlock_iovec(vec, arg2, count, 1);
1.1       root     5171:         }
                   5172:         break;
                   5173:     case TARGET_NR_writev:
                   5174:         {
                   5175:             int count = arg3;
                   5176:             struct iovec *vec;
                   5177: 
                   5178:             vec = alloca(count * sizeof(struct iovec));
1.1.1.7 ! root     5179:             if (lock_iovec(VERIFY_READ, vec, arg2, count, 1) < 0)
        !          5180:                 goto efault;
1.1       root     5181:             ret = get_errno(writev(arg1, vec, count));
1.1.1.3   root     5182:             unlock_iovec(vec, arg2, count, 0);
1.1       root     5183:         }
                   5184:         break;
                   5185:     case TARGET_NR_getsid:
                   5186:         ret = get_errno(getsid(arg1));
                   5187:         break;
1.1.1.6   root     5188: #if defined(TARGET_NR_fdatasync) /* Not on alpha (osf_datasync ?) */
1.1       root     5189:     case TARGET_NR_fdatasync:
                   5190:         ret = get_errno(fdatasync(arg1));
                   5191:         break;
1.1.1.6   root     5192: #endif
1.1       root     5193:     case TARGET_NR__sysctl:
1.1.1.6   root     5194:         /* We don't implement this, but ENOTDIR is always a safe
1.1       root     5195:            return value. */
1.1.1.6   root     5196:         ret = -TARGET_ENOTDIR;
                   5197:         break;
1.1       root     5198:     case TARGET_NR_sched_setparam:
                   5199:         {
1.1.1.3   root     5200:             struct sched_param *target_schp;
1.1       root     5201:             struct sched_param schp;
1.1.1.3   root     5202: 
1.1.1.6   root     5203:             if (!lock_user_struct(VERIFY_READ, target_schp, arg2, 1))
                   5204:                 goto efault;
1.1       root     5205:             schp.sched_priority = tswap32(target_schp->sched_priority);
1.1.1.3   root     5206:             unlock_user_struct(target_schp, arg2, 0);
1.1       root     5207:             ret = get_errno(sched_setparam(arg1, &schp));
                   5208:         }
                   5209:         break;
                   5210:     case TARGET_NR_sched_getparam:
                   5211:         {
1.1.1.3   root     5212:             struct sched_param *target_schp;
1.1       root     5213:             struct sched_param schp;
                   5214:             ret = get_errno(sched_getparam(arg1, &schp));
                   5215:             if (!is_error(ret)) {
1.1.1.6   root     5216:                 if (!lock_user_struct(VERIFY_WRITE, target_schp, arg2, 0))
                   5217:                     goto efault;
1.1       root     5218:                 target_schp->sched_priority = tswap32(schp.sched_priority);
1.1.1.3   root     5219:                 unlock_user_struct(target_schp, arg2, 1);
1.1       root     5220:             }
                   5221:         }
                   5222:         break;
                   5223:     case TARGET_NR_sched_setscheduler:
                   5224:         {
1.1.1.3   root     5225:             struct sched_param *target_schp;
1.1       root     5226:             struct sched_param schp;
1.1.1.6   root     5227:             if (!lock_user_struct(VERIFY_READ, target_schp, arg3, 1))
                   5228:                 goto efault;
1.1       root     5229:             schp.sched_priority = tswap32(target_schp->sched_priority);
1.1.1.3   root     5230:             unlock_user_struct(target_schp, arg3, 0);
1.1       root     5231:             ret = get_errno(sched_setscheduler(arg1, arg2, &schp));
                   5232:         }
                   5233:         break;
                   5234:     case TARGET_NR_sched_getscheduler:
                   5235:         ret = get_errno(sched_getscheduler(arg1));
                   5236:         break;
                   5237:     case TARGET_NR_sched_yield:
                   5238:         ret = get_errno(sched_yield());
                   5239:         break;
                   5240:     case TARGET_NR_sched_get_priority_max:
                   5241:         ret = get_errno(sched_get_priority_max(arg1));
                   5242:         break;
                   5243:     case TARGET_NR_sched_get_priority_min:
                   5244:         ret = get_errno(sched_get_priority_min(arg1));
                   5245:         break;
                   5246:     case TARGET_NR_sched_rr_get_interval:
                   5247:         {
                   5248:             struct timespec ts;
                   5249:             ret = get_errno(sched_rr_get_interval(arg1, &ts));
                   5250:             if (!is_error(ret)) {
1.1.1.3   root     5251:                 host_to_target_timespec(arg2, &ts);
1.1       root     5252:             }
                   5253:         }
                   5254:         break;
                   5255:     case TARGET_NR_nanosleep:
                   5256:         {
                   5257:             struct timespec req, rem;
1.1.1.3   root     5258:             target_to_host_timespec(&req, arg1);
1.1       root     5259:             ret = get_errno(nanosleep(&req, &rem));
1.1.1.3   root     5260:             if (is_error(ret) && arg2) {
                   5261:                 host_to_target_timespec(arg2, &rem);
1.1       root     5262:             }
                   5263:         }
                   5264:         break;
1.1.1.6   root     5265: #ifdef TARGET_NR_query_module
1.1       root     5266:     case TARGET_NR_query_module:
                   5267:         goto unimplemented;
1.1.1.6   root     5268: #endif
                   5269: #ifdef TARGET_NR_nfsservctl
1.1       root     5270:     case TARGET_NR_nfsservctl:
                   5271:         goto unimplemented;
1.1.1.6   root     5272: #endif
1.1       root     5273:     case TARGET_NR_prctl:
1.1.1.6   root     5274:         switch (arg1)
                   5275:             {
                   5276:             case PR_GET_PDEATHSIG:
                   5277:                 {
                   5278:                     int deathsig;
                   5279:                     ret = get_errno(prctl(arg1, &deathsig, arg3, arg4, arg5));
                   5280:                     if (!is_error(ret) && arg2
                   5281:                         && put_user_ual(deathsig, arg2))
                   5282:                         goto efault;
                   5283:                 }
                   5284:                 break;
                   5285:             default:
                   5286:                 ret = get_errno(prctl(arg1, arg2, arg3, arg4, arg5));
                   5287:                 break;
                   5288:             }
                   5289:         break;
                   5290: #ifdef TARGET_NR_arch_prctl
                   5291:     case TARGET_NR_arch_prctl:
                   5292: #if defined(TARGET_I386) && !defined(TARGET_ABI32)
                   5293:         ret = do_arch_prctl(cpu_env, arg1, arg2);
                   5294:         break;
                   5295: #else
1.1       root     5296:         goto unimplemented;
1.1.1.6   root     5297: #endif
                   5298: #endif
1.1       root     5299: #ifdef TARGET_NR_pread
                   5300:     case TARGET_NR_pread:
1.1.1.7 ! root     5301: #ifdef TARGET_ARM
        !          5302:         if (((CPUARMState *)cpu_env)->eabi)
        !          5303:             arg4 = arg5;
        !          5304: #endif
1.1.1.6   root     5305:         if (!(p = lock_user(VERIFY_WRITE, arg2, arg3, 0)))
                   5306:             goto efault;
1.1.1.3   root     5307:         ret = get_errno(pread(arg1, p, arg3, arg4));
                   5308:         unlock_user(p, arg2, ret);
1.1       root     5309:         break;
                   5310:     case TARGET_NR_pwrite:
1.1.1.7 ! root     5311: #ifdef TARGET_ARM
        !          5312:         if (((CPUARMState *)cpu_env)->eabi)
        !          5313:             arg4 = arg5;
        !          5314: #endif
1.1.1.6   root     5315:         if (!(p = lock_user(VERIFY_READ, arg2, arg3, 1)))
                   5316:             goto efault;
1.1.1.3   root     5317:         ret = get_errno(pwrite(arg1, p, arg3, arg4));
                   5318:         unlock_user(p, arg2, 0);
1.1       root     5319:         break;
                   5320: #endif
1.1.1.7 ! root     5321: #ifdef TARGET_NR_pread64
        !          5322:     case TARGET_NR_pread64:
        !          5323:         if (!(p = lock_user(VERIFY_WRITE, arg2, arg3, 0)))
        !          5324:             goto efault;
        !          5325:         ret = get_errno(pread64(arg1, p, arg3, target_offset64(arg4, arg5)));
        !          5326:         unlock_user(p, arg2, ret);
        !          5327:         break;
        !          5328:     case TARGET_NR_pwrite64:
        !          5329:         if (!(p = lock_user(VERIFY_READ, arg2, arg3, 1)))
        !          5330:             goto efault;
        !          5331:         ret = get_errno(pwrite64(arg1, p, arg3, target_offset64(arg4, arg5)));
        !          5332:         unlock_user(p, arg2, 0);
        !          5333:         break;
        !          5334: #endif
1.1       root     5335:     case TARGET_NR_getcwd:
1.1.1.6   root     5336:         if (!(p = lock_user(VERIFY_WRITE, arg1, arg2, 0)))
                   5337:             goto efault;
1.1.1.3   root     5338:         ret = get_errno(sys_getcwd1(p, arg2));
                   5339:         unlock_user(p, arg1, ret);
1.1       root     5340:         break;
                   5341:     case TARGET_NR_capget:
                   5342:         goto unimplemented;
                   5343:     case TARGET_NR_capset:
                   5344:         goto unimplemented;
                   5345:     case TARGET_NR_sigaltstack:
1.1.1.6   root     5346: #if defined(TARGET_I386) || defined(TARGET_ARM) || defined(TARGET_MIPS) || \
                   5347:     defined(TARGET_SPARC) || defined(TARGET_PPC) || defined(TARGET_ALPHA)
                   5348:         ret = do_sigaltstack(arg1, arg2, get_sp_from_cpustate((CPUState *)cpu_env));
                   5349:         break;
                   5350: #else
1.1       root     5351:         goto unimplemented;
1.1.1.6   root     5352: #endif
1.1       root     5353:     case TARGET_NR_sendfile:
                   5354:         goto unimplemented;
                   5355: #ifdef TARGET_NR_getpmsg
                   5356:     case TARGET_NR_getpmsg:
                   5357:         goto unimplemented;
                   5358: #endif
                   5359: #ifdef TARGET_NR_putpmsg
                   5360:     case TARGET_NR_putpmsg:
                   5361:         goto unimplemented;
                   5362: #endif
1.1.1.2   root     5363: #ifdef TARGET_NR_vfork
1.1       root     5364:     case TARGET_NR_vfork:
1.1.1.7 ! root     5365:         ret = get_errno(do_fork(cpu_env, CLONE_VFORK | CLONE_VM | SIGCHLD,
        !          5366:                         0, 0, 0, 0));
1.1       root     5367:         break;
1.1.1.2   root     5368: #endif
1.1       root     5369: #ifdef TARGET_NR_ugetrlimit
                   5370:     case TARGET_NR_ugetrlimit:
                   5371:     {
                   5372:        struct rlimit rlim;
                   5373:        ret = get_errno(getrlimit(arg1, &rlim));
                   5374:        if (!is_error(ret)) {
1.1.1.3   root     5375:            struct target_rlimit *target_rlim;
1.1.1.6   root     5376:             if (!lock_user_struct(VERIFY_WRITE, target_rlim, arg2, 0))
                   5377:                 goto efault;
1.1       root     5378:            target_rlim->rlim_cur = tswapl(rlim.rlim_cur);
                   5379:            target_rlim->rlim_max = tswapl(rlim.rlim_max);
1.1.1.3   root     5380:             unlock_user_struct(target_rlim, arg2, 1);
1.1       root     5381:        }
                   5382:        break;
                   5383:     }
                   5384: #endif
                   5385: #ifdef TARGET_NR_truncate64
                   5386:     case TARGET_NR_truncate64:
1.1.1.6   root     5387:         if (!(p = lock_user_string(arg1)))
                   5388:             goto efault;
1.1.1.3   root     5389:        ret = target_truncate64(cpu_env, p, arg2, arg3, arg4);
                   5390:         unlock_user(p, arg1, 0);
1.1       root     5391:        break;
                   5392: #endif
                   5393: #ifdef TARGET_NR_ftruncate64
                   5394:     case TARGET_NR_ftruncate64:
1.1.1.3   root     5395:        ret = target_ftruncate64(cpu_env, arg1, arg2, arg3, arg4);
1.1       root     5396:        break;
                   5397: #endif
                   5398: #ifdef TARGET_NR_stat64
                   5399:     case TARGET_NR_stat64:
1.1.1.6   root     5400:         if (!(p = lock_user_string(arg1)))
                   5401:             goto efault;
1.1.1.3   root     5402:         ret = get_errno(stat(path(p), &st));
                   5403:         unlock_user(p, arg1, 0);
1.1.1.7 ! root     5404:         if (!is_error(ret))
        !          5405:             ret = host_to_target_stat64(cpu_env, arg2, &st);
        !          5406:         break;
1.1       root     5407: #endif
                   5408: #ifdef TARGET_NR_lstat64
                   5409:     case TARGET_NR_lstat64:
1.1.1.6   root     5410:         if (!(p = lock_user_string(arg1)))
                   5411:             goto efault;
1.1.1.3   root     5412:         ret = get_errno(lstat(path(p), &st));
                   5413:         unlock_user(p, arg1, 0);
1.1.1.7 ! root     5414:         if (!is_error(ret))
        !          5415:             ret = host_to_target_stat64(cpu_env, arg2, &st);
        !          5416:         break;
1.1       root     5417: #endif
                   5418: #ifdef TARGET_NR_fstat64
                   5419:     case TARGET_NR_fstat64:
1.1.1.7 ! root     5420:         ret = get_errno(fstat(arg1, &st));
        !          5421:         if (!is_error(ret))
        !          5422:             ret = host_to_target_stat64(cpu_env, arg2, &st);
        !          5423:         break;
1.1       root     5424: #endif
1.1.1.7 ! root     5425: #if defined(TARGET_NR_fstatat64) && defined(__NR_fstatat64)
        !          5426:     case TARGET_NR_fstatat64:
        !          5427:         if (!(p = lock_user_string(arg2)))
        !          5428:             goto efault;
        !          5429:         ret = get_errno(sys_fstatat64(arg1, path(p), &st, arg4));
        !          5430:         if (!is_error(ret))
        !          5431:             ret = host_to_target_stat64(cpu_env, arg3, &st);
1.1       root     5432:         break;
                   5433: #endif
                   5434: #ifdef USE_UID16
                   5435:     case TARGET_NR_lchown:
1.1.1.6   root     5436:         if (!(p = lock_user_string(arg1)))
                   5437:             goto efault;
1.1.1.3   root     5438:         ret = get_errno(lchown(p, low2highuid(arg2), low2highgid(arg3)));
                   5439:         unlock_user(p, arg1, 0);
1.1       root     5440:         break;
                   5441:     case TARGET_NR_getuid:
                   5442:         ret = get_errno(high2lowuid(getuid()));
                   5443:         break;
                   5444:     case TARGET_NR_getgid:
                   5445:         ret = get_errno(high2lowgid(getgid()));
                   5446:         break;
                   5447:     case TARGET_NR_geteuid:
                   5448:         ret = get_errno(high2lowuid(geteuid()));
                   5449:         break;
                   5450:     case TARGET_NR_getegid:
                   5451:         ret = get_errno(high2lowgid(getegid()));
                   5452:         break;
                   5453:     case TARGET_NR_setreuid:
                   5454:         ret = get_errno(setreuid(low2highuid(arg1), low2highuid(arg2)));
                   5455:         break;
                   5456:     case TARGET_NR_setregid:
                   5457:         ret = get_errno(setregid(low2highgid(arg1), low2highgid(arg2)));
                   5458:         break;
                   5459:     case TARGET_NR_getgroups:
                   5460:         {
                   5461:             int gidsetsize = arg1;
1.1.1.3   root     5462:             uint16_t *target_grouplist;
1.1       root     5463:             gid_t *grouplist;
                   5464:             int i;
                   5465: 
                   5466:             grouplist = alloca(gidsetsize * sizeof(gid_t));
                   5467:             ret = get_errno(getgroups(gidsetsize, grouplist));
1.1.1.7 ! root     5468:             if (gidsetsize == 0)
        !          5469:                 break;
1.1       root     5470:             if (!is_error(ret)) {
1.1.1.6   root     5471:                 target_grouplist = lock_user(VERIFY_WRITE, arg2, gidsetsize * 2, 0);
                   5472:                 if (!target_grouplist)
                   5473:                     goto efault;
1.1.1.7 ! root     5474:                 for(i = 0;i < ret; i++)
1.1       root     5475:                     target_grouplist[i] = tswap16(grouplist[i]);
1.1.1.3   root     5476:                 unlock_user(target_grouplist, arg2, gidsetsize * 2);
1.1       root     5477:             }
                   5478:         }
                   5479:         break;
                   5480:     case TARGET_NR_setgroups:
                   5481:         {
                   5482:             int gidsetsize = arg1;
1.1.1.3   root     5483:             uint16_t *target_grouplist;
1.1       root     5484:             gid_t *grouplist;
                   5485:             int i;
                   5486: 
                   5487:             grouplist = alloca(gidsetsize * sizeof(gid_t));
1.1.1.6   root     5488:             target_grouplist = lock_user(VERIFY_READ, arg2, gidsetsize * 2, 1);
                   5489:             if (!target_grouplist) {
                   5490:                 ret = -TARGET_EFAULT;
                   5491:                 goto fail;
                   5492:             }
1.1       root     5493:             for(i = 0;i < gidsetsize; i++)
                   5494:                 grouplist[i] = tswap16(target_grouplist[i]);
1.1.1.3   root     5495:             unlock_user(target_grouplist, arg2, 0);
1.1       root     5496:             ret = get_errno(setgroups(gidsetsize, grouplist));
                   5497:         }
                   5498:         break;
                   5499:     case TARGET_NR_fchown:
                   5500:         ret = get_errno(fchown(arg1, low2highuid(arg2), low2highgid(arg3)));
                   5501:         break;
1.1.1.6   root     5502: #if defined(TARGET_NR_fchownat) && defined(__NR_fchownat)
                   5503:     case TARGET_NR_fchownat:
                   5504:         if (!(p = lock_user_string(arg2))) 
                   5505:             goto efault;
                   5506:         ret = get_errno(sys_fchownat(arg1, p, low2highuid(arg3), low2highgid(arg4), arg5));
                   5507:         unlock_user(p, arg2, 0);
                   5508:         break;
                   5509: #endif
1.1       root     5510: #ifdef TARGET_NR_setresuid
                   5511:     case TARGET_NR_setresuid:
1.1.1.6   root     5512:         ret = get_errno(setresuid(low2highuid(arg1),
                   5513:                                   low2highuid(arg2),
1.1       root     5514:                                   low2highuid(arg3)));
                   5515:         break;
                   5516: #endif
                   5517: #ifdef TARGET_NR_getresuid
                   5518:     case TARGET_NR_getresuid:
                   5519:         {
1.1.1.3   root     5520:             uid_t ruid, euid, suid;
1.1       root     5521:             ret = get_errno(getresuid(&ruid, &euid, &suid));
                   5522:             if (!is_error(ret)) {
1.1.1.6   root     5523:                 if (put_user_u16(high2lowuid(ruid), arg1)
                   5524:                     || put_user_u16(high2lowuid(euid), arg2)
                   5525:                     || put_user_u16(high2lowuid(suid), arg3))
                   5526:                     goto efault;
1.1       root     5527:             }
                   5528:         }
                   5529:         break;
                   5530: #endif
                   5531: #ifdef TARGET_NR_getresgid
                   5532:     case TARGET_NR_setresgid:
1.1.1.6   root     5533:         ret = get_errno(setresgid(low2highgid(arg1),
                   5534:                                   low2highgid(arg2),
1.1       root     5535:                                   low2highgid(arg3)));
                   5536:         break;
                   5537: #endif
                   5538: #ifdef TARGET_NR_getresgid
                   5539:     case TARGET_NR_getresgid:
                   5540:         {
1.1.1.3   root     5541:             gid_t rgid, egid, sgid;
1.1       root     5542:             ret = get_errno(getresgid(&rgid, &egid, &sgid));
                   5543:             if (!is_error(ret)) {
1.1.1.6   root     5544:                 if (put_user_u16(high2lowgid(rgid), arg1)
                   5545:                     || put_user_u16(high2lowgid(egid), arg2)
                   5546:                     || put_user_u16(high2lowgid(sgid), arg3))
                   5547:                     goto efault;
1.1       root     5548:             }
                   5549:         }
                   5550:         break;
                   5551: #endif
                   5552:     case TARGET_NR_chown:
1.1.1.6   root     5553:         if (!(p = lock_user_string(arg1)))
                   5554:             goto efault;
1.1.1.3   root     5555:         ret = get_errno(chown(p, low2highuid(arg2), low2highgid(arg3)));
                   5556:         unlock_user(p, arg1, 0);
1.1       root     5557:         break;
                   5558:     case TARGET_NR_setuid:
                   5559:         ret = get_errno(setuid(low2highuid(arg1)));
                   5560:         break;
                   5561:     case TARGET_NR_setgid:
                   5562:         ret = get_errno(setgid(low2highgid(arg1)));
                   5563:         break;
                   5564:     case TARGET_NR_setfsuid:
                   5565:         ret = get_errno(setfsuid(arg1));
                   5566:         break;
                   5567:     case TARGET_NR_setfsgid:
                   5568:         ret = get_errno(setfsgid(arg1));
                   5569:         break;
                   5570: #endif /* USE_UID16 */
                   5571: 
                   5572: #ifdef TARGET_NR_lchown32
                   5573:     case TARGET_NR_lchown32:
1.1.1.6   root     5574:         if (!(p = lock_user_string(arg1)))
                   5575:             goto efault;
1.1.1.3   root     5576:         ret = get_errno(lchown(p, arg2, arg3));
                   5577:         unlock_user(p, arg1, 0);
1.1       root     5578:         break;
                   5579: #endif
                   5580: #ifdef TARGET_NR_getuid32
                   5581:     case TARGET_NR_getuid32:
                   5582:         ret = get_errno(getuid());
                   5583:         break;
                   5584: #endif
1.1.1.7 ! root     5585: 
        !          5586: #if defined(TARGET_NR_getxuid) && defined(TARGET_ALPHA)
        !          5587:    /* Alpha specific */
        !          5588:     case TARGET_NR_getxuid:
        !          5589:         {
        !          5590:            uid_t euid;
        !          5591:            euid=geteuid();
        !          5592:            ((CPUAlphaState *)cpu_env)->ir[IR_A4]=euid;
        !          5593:         }
        !          5594:         ret = get_errno(getuid());
        !          5595:         break;
        !          5596: #endif
        !          5597: #if defined(TARGET_NR_getxgid) && defined(TARGET_ALPHA)
        !          5598:    /* Alpha specific */
        !          5599:     case TARGET_NR_getxgid:
        !          5600:         {
        !          5601:            uid_t egid;
        !          5602:            egid=getegid();
        !          5603:            ((CPUAlphaState *)cpu_env)->ir[IR_A4]=egid;
        !          5604:         }
        !          5605:         ret = get_errno(getgid());
        !          5606:         break;
        !          5607: #endif
        !          5608: 
1.1       root     5609: #ifdef TARGET_NR_getgid32
                   5610:     case TARGET_NR_getgid32:
                   5611:         ret = get_errno(getgid());
                   5612:         break;
                   5613: #endif
                   5614: #ifdef TARGET_NR_geteuid32
                   5615:     case TARGET_NR_geteuid32:
                   5616:         ret = get_errno(geteuid());
                   5617:         break;
                   5618: #endif
                   5619: #ifdef TARGET_NR_getegid32
                   5620:     case TARGET_NR_getegid32:
                   5621:         ret = get_errno(getegid());
                   5622:         break;
                   5623: #endif
                   5624: #ifdef TARGET_NR_setreuid32
                   5625:     case TARGET_NR_setreuid32:
                   5626:         ret = get_errno(setreuid(arg1, arg2));
                   5627:         break;
                   5628: #endif
                   5629: #ifdef TARGET_NR_setregid32
                   5630:     case TARGET_NR_setregid32:
                   5631:         ret = get_errno(setregid(arg1, arg2));
                   5632:         break;
                   5633: #endif
                   5634: #ifdef TARGET_NR_getgroups32
                   5635:     case TARGET_NR_getgroups32:
                   5636:         {
                   5637:             int gidsetsize = arg1;
1.1.1.3   root     5638:             uint32_t *target_grouplist;
1.1       root     5639:             gid_t *grouplist;
                   5640:             int i;
                   5641: 
                   5642:             grouplist = alloca(gidsetsize * sizeof(gid_t));
                   5643:             ret = get_errno(getgroups(gidsetsize, grouplist));
1.1.1.7 ! root     5644:             if (gidsetsize == 0)
        !          5645:                 break;
1.1       root     5646:             if (!is_error(ret)) {
1.1.1.6   root     5647:                 target_grouplist = lock_user(VERIFY_WRITE, arg2, gidsetsize * 4, 0);
                   5648:                 if (!target_grouplist) {
                   5649:                     ret = -TARGET_EFAULT;
                   5650:                     goto fail;
                   5651:                 }
1.1.1.7 ! root     5652:                 for(i = 0;i < ret; i++)
1.1.1.3   root     5653:                     target_grouplist[i] = tswap32(grouplist[i]);
                   5654:                 unlock_user(target_grouplist, arg2, gidsetsize * 4);
1.1       root     5655:             }
                   5656:         }
                   5657:         break;
                   5658: #endif
                   5659: #ifdef TARGET_NR_setgroups32
                   5660:     case TARGET_NR_setgroups32:
                   5661:         {
                   5662:             int gidsetsize = arg1;
1.1.1.3   root     5663:             uint32_t *target_grouplist;
1.1       root     5664:             gid_t *grouplist;
                   5665:             int i;
1.1.1.6   root     5666: 
1.1       root     5667:             grouplist = alloca(gidsetsize * sizeof(gid_t));
1.1.1.6   root     5668:             target_grouplist = lock_user(VERIFY_READ, arg2, gidsetsize * 4, 1);
                   5669:             if (!target_grouplist) {
                   5670:                 ret = -TARGET_EFAULT;
                   5671:                 goto fail;
                   5672:             }
1.1       root     5673:             for(i = 0;i < gidsetsize; i++)
1.1.1.3   root     5674:                 grouplist[i] = tswap32(target_grouplist[i]);
                   5675:             unlock_user(target_grouplist, arg2, 0);
1.1       root     5676:             ret = get_errno(setgroups(gidsetsize, grouplist));
                   5677:         }
                   5678:         break;
                   5679: #endif
                   5680: #ifdef TARGET_NR_fchown32
                   5681:     case TARGET_NR_fchown32:
                   5682:         ret = get_errno(fchown(arg1, arg2, arg3));
                   5683:         break;
                   5684: #endif
                   5685: #ifdef TARGET_NR_setresuid32
                   5686:     case TARGET_NR_setresuid32:
                   5687:         ret = get_errno(setresuid(arg1, arg2, arg3));
                   5688:         break;
                   5689: #endif
                   5690: #ifdef TARGET_NR_getresuid32
                   5691:     case TARGET_NR_getresuid32:
                   5692:         {
1.1.1.3   root     5693:             uid_t ruid, euid, suid;
1.1       root     5694:             ret = get_errno(getresuid(&ruid, &euid, &suid));
                   5695:             if (!is_error(ret)) {
1.1.1.6   root     5696:                 if (put_user_u32(ruid, arg1)
                   5697:                     || put_user_u32(euid, arg2)
                   5698:                     || put_user_u32(suid, arg3))
                   5699:                     goto efault;
1.1       root     5700:             }
                   5701:         }
                   5702:         break;
                   5703: #endif
                   5704: #ifdef TARGET_NR_setresgid32
                   5705:     case TARGET_NR_setresgid32:
                   5706:         ret = get_errno(setresgid(arg1, arg2, arg3));
                   5707:         break;
                   5708: #endif
                   5709: #ifdef TARGET_NR_getresgid32
                   5710:     case TARGET_NR_getresgid32:
                   5711:         {
1.1.1.3   root     5712:             gid_t rgid, egid, sgid;
1.1       root     5713:             ret = get_errno(getresgid(&rgid, &egid, &sgid));
                   5714:             if (!is_error(ret)) {
1.1.1.6   root     5715:                 if (put_user_u32(rgid, arg1)
                   5716:                     || put_user_u32(egid, arg2)
                   5717:                     || put_user_u32(sgid, arg3))
                   5718:                     goto efault;
1.1       root     5719:             }
                   5720:         }
                   5721:         break;
                   5722: #endif
                   5723: #ifdef TARGET_NR_chown32
                   5724:     case TARGET_NR_chown32:
1.1.1.6   root     5725:         if (!(p = lock_user_string(arg1)))
                   5726:             goto efault;
1.1.1.3   root     5727:         ret = get_errno(chown(p, arg2, arg3));
                   5728:         unlock_user(p, arg1, 0);
1.1       root     5729:         break;
                   5730: #endif
                   5731: #ifdef TARGET_NR_setuid32
                   5732:     case TARGET_NR_setuid32:
                   5733:         ret = get_errno(setuid(arg1));
                   5734:         break;
                   5735: #endif
                   5736: #ifdef TARGET_NR_setgid32
                   5737:     case TARGET_NR_setgid32:
                   5738:         ret = get_errno(setgid(arg1));
                   5739:         break;
                   5740: #endif
                   5741: #ifdef TARGET_NR_setfsuid32
                   5742:     case TARGET_NR_setfsuid32:
                   5743:         ret = get_errno(setfsuid(arg1));
                   5744:         break;
                   5745: #endif
                   5746: #ifdef TARGET_NR_setfsgid32
                   5747:     case TARGET_NR_setfsgid32:
                   5748:         ret = get_errno(setfsgid(arg1));
                   5749:         break;
                   5750: #endif
                   5751: 
                   5752:     case TARGET_NR_pivot_root:
                   5753:         goto unimplemented;
                   5754: #ifdef TARGET_NR_mincore
                   5755:     case TARGET_NR_mincore:
1.1.1.7 ! root     5756:         {
        !          5757:             void *a;
        !          5758:             ret = -TARGET_EFAULT;
        !          5759:             if (!(a = lock_user(VERIFY_READ, arg1,arg2, 0)))
        !          5760:                 goto efault;
        !          5761:             if (!(p = lock_user_string(arg3)))
        !          5762:                 goto mincore_fail;
        !          5763:             ret = get_errno(mincore(a, arg2, p));
        !          5764:             unlock_user(p, arg3, ret);
        !          5765:             mincore_fail:
        !          5766:             unlock_user(a, arg1, 0);
        !          5767:         }
        !          5768:         break;
        !          5769: #endif
        !          5770: #ifdef TARGET_NR_arm_fadvise64_64
        !          5771:     case TARGET_NR_arm_fadvise64_64:
        !          5772:        {
        !          5773:                /*
        !          5774:                 * arm_fadvise64_64 looks like fadvise64_64 but
        !          5775:                 * with different argument order
        !          5776:                 */
        !          5777:                abi_long temp;
        !          5778:                temp = arg3;
        !          5779:                arg3 = arg4;
        !          5780:                arg4 = temp;
        !          5781:        }
        !          5782: #endif
        !          5783: #if defined(TARGET_NR_fadvise64_64) || defined(TARGET_NR_arm_fadvise64_64)
        !          5784: #ifdef TARGET_NR_fadvise64_64
        !          5785:     case TARGET_NR_fadvise64_64:
        !          5786: #endif
        !          5787:         /* This is a hint, so ignoring and returning success is ok.  */
        !          5788:        ret = get_errno(0);
        !          5789:        break;
1.1       root     5790: #endif
                   5791: #ifdef TARGET_NR_madvise
                   5792:     case TARGET_NR_madvise:
1.1.1.3   root     5793:         /* A straight passthrough may not be safe because qemu sometimes
                   5794:            turns private flie-backed mappings into anonymous mappings.
                   5795:            This will break MADV_DONTNEED.
                   5796:            This is a hint, so ignoring and returning success is ok.  */
                   5797:         ret = get_errno(0);
                   5798:         break;
1.1       root     5799: #endif
1.1.1.6   root     5800: #if TARGET_ABI_BITS == 32
1.1       root     5801:     case TARGET_NR_fcntl64:
                   5802:     {
1.1.1.6   root     5803:        int cmd;
1.1       root     5804:        struct flock64 fl;
1.1.1.3   root     5805:        struct target_flock64 *target_fl;
                   5806: #ifdef TARGET_ARM
                   5807:        struct target_eabi_flock64 *target_efl;
                   5808: #endif
1.1       root     5809: 
1.1.1.6   root     5810:         switch(arg2){
                   5811:         case TARGET_F_GETLK64:
                   5812:             cmd = F_GETLK64;
                   5813:             break;
                   5814:         case TARGET_F_SETLK64:
                   5815:             cmd = F_SETLK64;
                   5816:             break;
                   5817:         case TARGET_F_SETLKW64:
                   5818:             cmd = F_SETLK64;
                   5819:             break;
                   5820:         default:
                   5821:             cmd = arg2;
                   5822:             break;
                   5823:         }
                   5824: 
1.1       root     5825:         switch(arg2) {
1.1.1.6   root     5826:         case TARGET_F_GETLK64:
                   5827: #ifdef TARGET_ARM
                   5828:             if (((CPUARMState *)cpu_env)->eabi) {
                   5829:                 if (!lock_user_struct(VERIFY_READ, target_efl, arg3, 1)) 
                   5830:                     goto efault;
                   5831:                 fl.l_type = tswap16(target_efl->l_type);
                   5832:                 fl.l_whence = tswap16(target_efl->l_whence);
                   5833:                 fl.l_start = tswap64(target_efl->l_start);
                   5834:                 fl.l_len = tswap64(target_efl->l_len);
                   5835:                 fl.l_pid = tswapl(target_efl->l_pid);
                   5836:                 unlock_user_struct(target_efl, arg3, 0);
                   5837:             } else
                   5838: #endif
                   5839:             {
                   5840:                 if (!lock_user_struct(VERIFY_READ, target_fl, arg3, 1)) 
                   5841:                     goto efault;
                   5842:                 fl.l_type = tswap16(target_fl->l_type);
                   5843:                 fl.l_whence = tswap16(target_fl->l_whence);
                   5844:                 fl.l_start = tswap64(target_fl->l_start);
                   5845:                 fl.l_len = tswap64(target_fl->l_len);
                   5846:                 fl.l_pid = tswapl(target_fl->l_pid);
                   5847:                 unlock_user_struct(target_fl, arg3, 0);
                   5848:             }
                   5849:             ret = get_errno(fcntl(arg1, cmd, &fl));
1.1       root     5850:            if (ret == 0) {
1.1.1.3   root     5851: #ifdef TARGET_ARM
                   5852:                 if (((CPUARMState *)cpu_env)->eabi) {
1.1.1.6   root     5853:                     if (!lock_user_struct(VERIFY_WRITE, target_efl, arg3, 0)) 
                   5854:                         goto efault;
1.1.1.3   root     5855:                     target_efl->l_type = tswap16(fl.l_type);
                   5856:                     target_efl->l_whence = tswap16(fl.l_whence);
                   5857:                     target_efl->l_start = tswap64(fl.l_start);
                   5858:                     target_efl->l_len = tswap64(fl.l_len);
                   5859:                     target_efl->l_pid = tswapl(fl.l_pid);
                   5860:                     unlock_user_struct(target_efl, arg3, 1);
                   5861:                 } else
                   5862: #endif
                   5863:                 {
1.1.1.6   root     5864:                     if (!lock_user_struct(VERIFY_WRITE, target_fl, arg3, 0)) 
                   5865:                         goto efault;
1.1.1.3   root     5866:                     target_fl->l_type = tswap16(fl.l_type);
                   5867:                     target_fl->l_whence = tswap16(fl.l_whence);
                   5868:                     target_fl->l_start = tswap64(fl.l_start);
                   5869:                     target_fl->l_len = tswap64(fl.l_len);
                   5870:                     target_fl->l_pid = tswapl(fl.l_pid);
                   5871:                     unlock_user_struct(target_fl, arg3, 1);
                   5872:                 }
1.1       root     5873:            }
                   5874:            break;
                   5875: 
1.1.1.6   root     5876:         case TARGET_F_SETLK64:
                   5877:         case TARGET_F_SETLKW64:
1.1.1.3   root     5878: #ifdef TARGET_ARM
                   5879:             if (((CPUARMState *)cpu_env)->eabi) {
1.1.1.6   root     5880:                 if (!lock_user_struct(VERIFY_READ, target_efl, arg3, 1)) 
                   5881:                     goto efault;
1.1.1.3   root     5882:                 fl.l_type = tswap16(target_efl->l_type);
                   5883:                 fl.l_whence = tswap16(target_efl->l_whence);
                   5884:                 fl.l_start = tswap64(target_efl->l_start);
                   5885:                 fl.l_len = tswap64(target_efl->l_len);
                   5886:                 fl.l_pid = tswapl(target_efl->l_pid);
                   5887:                 unlock_user_struct(target_efl, arg3, 0);
                   5888:             } else
                   5889: #endif
                   5890:             {
1.1.1.6   root     5891:                 if (!lock_user_struct(VERIFY_READ, target_fl, arg3, 1)) 
                   5892:                     goto efault;
1.1.1.3   root     5893:                 fl.l_type = tswap16(target_fl->l_type);
                   5894:                 fl.l_whence = tswap16(target_fl->l_whence);
                   5895:                 fl.l_start = tswap64(target_fl->l_start);
                   5896:                 fl.l_len = tswap64(target_fl->l_len);
                   5897:                 fl.l_pid = tswapl(target_fl->l_pid);
                   5898:                 unlock_user_struct(target_fl, arg3, 0);
                   5899:             }
1.1.1.6   root     5900:             ret = get_errno(fcntl(arg1, cmd, &fl));
1.1       root     5901:            break;
                   5902:         default:
1.1.1.6   root     5903:             ret = do_fcntl(arg1, cmd, arg3);
1.1       root     5904:             break;
                   5905:         }
                   5906:        break;
                   5907:     }
                   5908: #endif
1.1.1.5   root     5909: #ifdef TARGET_NR_cacheflush
                   5910:     case TARGET_NR_cacheflush:
                   5911:         /* self-modifying code is handled automatically, so nothing needed */
                   5912:         ret = 0;
                   5913:         break;
                   5914: #endif
1.1       root     5915: #ifdef TARGET_NR_security
                   5916:     case TARGET_NR_security:
                   5917:         goto unimplemented;
                   5918: #endif
                   5919: #ifdef TARGET_NR_getpagesize
                   5920:     case TARGET_NR_getpagesize:
                   5921:         ret = TARGET_PAGE_SIZE;
                   5922:         break;
                   5923: #endif
                   5924:     case TARGET_NR_gettid:
                   5925:         ret = get_errno(gettid());
                   5926:         break;
1.1.1.6   root     5927: #ifdef TARGET_NR_readahead
1.1       root     5928:     case TARGET_NR_readahead:
1.1.1.7 ! root     5929: #if TARGET_ABI_BITS == 32
        !          5930: #ifdef TARGET_ARM
        !          5931:         if (((CPUARMState *)cpu_env)->eabi)
        !          5932:         {
        !          5933:             arg2 = arg3;
        !          5934:             arg3 = arg4;
        !          5935:             arg4 = arg5;
        !          5936:         }
        !          5937: #endif
        !          5938:         ret = get_errno(readahead(arg1, ((off64_t)arg3 << 32) | arg2, arg4));
        !          5939: #else
        !          5940:         ret = get_errno(readahead(arg1, arg2, arg3));
        !          5941: #endif
        !          5942:         break;
1.1.1.6   root     5943: #endif
1.1       root     5944: #ifdef TARGET_NR_setxattr
                   5945:     case TARGET_NR_setxattr:
                   5946:     case TARGET_NR_lsetxattr:
                   5947:     case TARGET_NR_fsetxattr:
                   5948:     case TARGET_NR_getxattr:
                   5949:     case TARGET_NR_lgetxattr:
                   5950:     case TARGET_NR_fgetxattr:
                   5951:     case TARGET_NR_listxattr:
                   5952:     case TARGET_NR_llistxattr:
                   5953:     case TARGET_NR_flistxattr:
                   5954:     case TARGET_NR_removexattr:
                   5955:     case TARGET_NR_lremovexattr:
                   5956:     case TARGET_NR_fremovexattr:
                   5957:         goto unimplemented_nowarn;
                   5958: #endif
                   5959: #ifdef TARGET_NR_set_thread_area
                   5960:     case TARGET_NR_set_thread_area:
1.1.1.6   root     5961: #if defined(TARGET_MIPS)
                   5962:       ((CPUMIPSState *) cpu_env)->tls_value = arg1;
                   5963:       ret = 0;
                   5964:       break;
1.1.1.7 ! root     5965: #elif defined(TARGET_CRIS)
        !          5966:       if (arg1 & 0xff)
        !          5967:           ret = -TARGET_EINVAL;
        !          5968:       else {
        !          5969:           ((CPUCRISState *) cpu_env)->pregs[PR_PID] = arg1;
        !          5970:           ret = 0;
        !          5971:       }
        !          5972:       break;
1.1.1.6   root     5973: #elif defined(TARGET_I386) && defined(TARGET_ABI32)
                   5974:       ret = do_set_thread_area(cpu_env, arg1);
                   5975:       break;
                   5976: #else
                   5977:       goto unimplemented_nowarn;
                   5978: #endif
                   5979: #endif
                   5980: #ifdef TARGET_NR_get_thread_area
1.1       root     5981:     case TARGET_NR_get_thread_area:
1.1.1.6   root     5982: #if defined(TARGET_I386) && defined(TARGET_ABI32)
                   5983:         ret = do_get_thread_area(cpu_env, arg1);
                   5984: #else
1.1       root     5985:         goto unimplemented_nowarn;
                   5986: #endif
1.1.1.6   root     5987: #endif
1.1.1.4   root     5988: #ifdef TARGET_NR_getdomainname
                   5989:     case TARGET_NR_getdomainname:
                   5990:         goto unimplemented_nowarn;
                   5991: #endif
1.1.1.6   root     5992: 
                   5993: #ifdef TARGET_NR_clock_gettime
                   5994:     case TARGET_NR_clock_gettime:
                   5995:     {
                   5996:         struct timespec ts;
                   5997:         ret = get_errno(clock_gettime(arg1, &ts));
                   5998:         if (!is_error(ret)) {
                   5999:             host_to_target_timespec(arg2, &ts);
                   6000:         }
                   6001:         break;
                   6002:     }
                   6003: #endif
                   6004: #ifdef TARGET_NR_clock_getres
                   6005:     case TARGET_NR_clock_getres:
                   6006:     {
                   6007:         struct timespec ts;
                   6008:         ret = get_errno(clock_getres(arg1, &ts));
                   6009:         if (!is_error(ret)) {
                   6010:             host_to_target_timespec(arg2, &ts);
                   6011:         }
                   6012:         break;
                   6013:     }
                   6014: #endif
1.1.1.7 ! root     6015: #ifdef TARGET_NR_clock_nanosleep
        !          6016:     case TARGET_NR_clock_nanosleep:
        !          6017:     {
        !          6018:         struct timespec ts;
        !          6019:         target_to_host_timespec(&ts, arg3);
        !          6020:         ret = get_errno(clock_nanosleep(arg1, arg2, &ts, arg4 ? &ts : NULL));
        !          6021:         if (arg4)
        !          6022:             host_to_target_timespec(arg4, &ts);
        !          6023:         break;
        !          6024:     }
        !          6025: #endif
1.1.1.6   root     6026: 
                   6027: #if defined(TARGET_NR_set_tid_address) && defined(__NR_set_tid_address)
                   6028:     case TARGET_NR_set_tid_address:
                   6029:         ret = get_errno(set_tid_address((int *)g2h(arg1)));
                   6030:         break;
                   6031: #endif
                   6032: 
                   6033: #if defined(TARGET_NR_tkill) && defined(__NR_tkill)
                   6034:     case TARGET_NR_tkill:
1.1.1.7 ! root     6035:         ret = get_errno(sys_tkill((int)arg1, target_to_host_signal(arg2)));
1.1.1.6   root     6036:         break;
                   6037: #endif
                   6038: 
                   6039: #if defined(TARGET_NR_tgkill) && defined(__NR_tgkill)
                   6040:     case TARGET_NR_tgkill:
1.1.1.7 ! root     6041:        ret = get_errno(sys_tgkill((int)arg1, (int)arg2,
        !          6042:                         target_to_host_signal(arg3)));
1.1.1.6   root     6043:        break;
                   6044: #endif
                   6045: 
                   6046: #ifdef TARGET_NR_set_robust_list
                   6047:     case TARGET_NR_set_robust_list:
                   6048:        goto unimplemented_nowarn;
                   6049: #endif
                   6050: 
                   6051: #if defined(TARGET_NR_utimensat) && defined(__NR_utimensat)
                   6052:     case TARGET_NR_utimensat:
                   6053:         {
                   6054:             struct timespec ts[2];
                   6055:             target_to_host_timespec(ts, arg3);
                   6056:             target_to_host_timespec(ts+1, arg3+sizeof(struct target_timespec));
                   6057:             if (!arg2)
                   6058:                 ret = get_errno(sys_utimensat(arg1, NULL, ts, arg4));
                   6059:             else {
                   6060:                 if (!(p = lock_user_string(arg2))) {
                   6061:                     ret = -TARGET_EFAULT;
                   6062:                     goto fail;
                   6063:                 }
                   6064:                 ret = get_errno(sys_utimensat(arg1, path(p), ts, arg4));
                   6065:                 unlock_user(p, arg2, 0);
                   6066:             }
                   6067:         }
                   6068:        break;
                   6069: #endif
1.1.1.7 ! root     6070: #if defined(USE_NPTL)
        !          6071:     case TARGET_NR_futex:
        !          6072:         ret = do_futex(arg1, arg2, arg3, arg4, arg5, arg6);
        !          6073:         break;
        !          6074: #endif
        !          6075: #ifdef TARGET_NR_inotify_init
        !          6076:     case TARGET_NR_inotify_init:
        !          6077:         ret = get_errno(sys_inotify_init());
        !          6078:         break;
        !          6079: #endif
        !          6080: #ifdef TARGET_NR_inotify_add_watch
        !          6081:     case TARGET_NR_inotify_add_watch:
        !          6082:         p = lock_user_string(arg2);
        !          6083:         ret = get_errno(sys_inotify_add_watch(arg1, path(p), arg3));
        !          6084:         unlock_user(p, arg2, 0);
        !          6085:         break;
        !          6086: #endif
        !          6087: #ifdef TARGET_NR_inotify_rm_watch
        !          6088:     case TARGET_NR_inotify_rm_watch:
        !          6089:         ret = get_errno(sys_inotify_rm_watch(arg1, arg2));
        !          6090:         break;
        !          6091: #endif
1.1.1.6   root     6092: 
1.1       root     6093:     default:
                   6094:     unimplemented:
                   6095:         gemu_log("qemu: Unsupported syscall: %d\n", num);
1.1.1.6   root     6096: #if defined(TARGET_NR_setxattr) || defined(TARGET_NR_get_thread_area) || defined(TARGET_NR_getdomainname) || defined(TARGET_NR_set_robust_list)
1.1       root     6097:     unimplemented_nowarn:
                   6098: #endif
1.1.1.6   root     6099:         ret = -TARGET_ENOSYS;
1.1       root     6100:         break;
                   6101:     }
1.1.1.6   root     6102: fail:
1.1       root     6103: #ifdef DEBUG
                   6104:     gemu_log(" = %ld\n", ret);
                   6105: #endif
1.1.1.6   root     6106:     if(do_strace)
                   6107:         print_syscall_ret(num, ret);
1.1       root     6108:     return ret;
1.1.1.6   root     6109: efault:
                   6110:     ret = -TARGET_EFAULT;
                   6111:     goto fail;
1.1       root     6112: }

unix.superglobalmegacorp.com

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