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