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