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