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