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_ipc_perm
2421{
2422    abi_long __key;
2423    abi_ulong uid;
2424    abi_ulong gid;
2425    abi_ulong cuid;
2426    abi_ulong cgid;
2427    unsigned short int mode;
2428    unsigned short int __pad1;
2429    unsigned short int __seq;
2430    unsigned short int __pad2;
2431    abi_ulong __unused1;
2432    abi_ulong __unused2;
2433};
2434
2435struct target_semid_ds
2436{
2437  struct target_ipc_perm sem_perm;
2438  abi_ulong sem_otime;
2439  abi_ulong __unused1;
2440  abi_ulong sem_ctime;
2441  abi_ulong __unused2;
2442  abi_ulong sem_nsems;
2443  abi_ulong __unused3;
2444  abi_ulong __unused4;
2445};
2446
2447static inline abi_long target_to_host_ipc_perm(struct ipc_perm *host_ip,
2448                                               abi_ulong target_addr)
2449{
2450    struct target_ipc_perm *target_ip;
2451    struct target_semid_ds *target_sd;
2452
2453    if (!lock_user_struct(VERIFY_READ, target_sd, target_addr, 1))
2454        return -TARGET_EFAULT;
2455    target_ip = &(target_sd->sem_perm);
2456    host_ip->__key = tswapal(target_ip->__key);
2457    host_ip->uid = tswapal(target_ip->uid);
2458    host_ip->gid = tswapal(target_ip->gid);
2459    host_ip->cuid = tswapal(target_ip->cuid);
2460    host_ip->cgid = tswapal(target_ip->cgid);
2461    host_ip->mode = tswap16(target_ip->mode);
2462    unlock_user_struct(target_sd, target_addr, 0);
2463    return 0;
2464}
2465
2466static inline abi_long host_to_target_ipc_perm(abi_ulong target_addr,
2467                                               struct ipc_perm *host_ip)
2468{
2469    struct target_ipc_perm *target_ip;
2470    struct target_semid_ds *target_sd;
2471
2472    if (!lock_user_struct(VERIFY_WRITE, target_sd, target_addr, 0))
2473        return -TARGET_EFAULT;
2474    target_ip = &(target_sd->sem_perm);
2475    target_ip->__key = tswapal(host_ip->__key);
2476    target_ip->uid = tswapal(host_ip->uid);
2477    target_ip->gid = tswapal(host_ip->gid);
2478    target_ip->cuid = tswapal(host_ip->cuid);
2479    target_ip->cgid = tswapal(host_ip->cgid);
2480    target_ip->mode = tswap16(host_ip->mode);
2481    unlock_user_struct(target_sd, target_addr, 1);
2482    return 0;
2483}
2484
2485static inline abi_long target_to_host_semid_ds(struct semid_ds *host_sd,
2486                                               abi_ulong target_addr)
2487{
2488    struct target_semid_ds *target_sd;
2489
2490    if (!lock_user_struct(VERIFY_READ, target_sd, target_addr, 1))
2491        return -TARGET_EFAULT;
2492    if (target_to_host_ipc_perm(&(host_sd->sem_perm),target_addr))
2493        return -TARGET_EFAULT;
2494    host_sd->sem_nsems = tswapal(target_sd->sem_nsems);
2495    host_sd->sem_otime = tswapal(target_sd->sem_otime);
2496    host_sd->sem_ctime = tswapal(target_sd->sem_ctime);
2497    unlock_user_struct(target_sd, target_addr, 0);
2498    return 0;
2499}
2500
2501static inline abi_long host_to_target_semid_ds(abi_ulong target_addr,
2502                                               struct semid_ds *host_sd)
2503{
2504    struct target_semid_ds *target_sd;
2505
2506    if (!lock_user_struct(VERIFY_WRITE, target_sd, target_addr, 0))
2507        return -TARGET_EFAULT;
2508    if (host_to_target_ipc_perm(target_addr,&(host_sd->sem_perm)))
2509        return -TARGET_EFAULT;
2510    target_sd->sem_nsems = tswapal(host_sd->sem_nsems);
2511    target_sd->sem_otime = tswapal(host_sd->sem_otime);
2512    target_sd->sem_ctime = tswapal(host_sd->sem_ctime);
2513    unlock_user_struct(target_sd, target_addr, 1);
2514    return 0;
2515}
2516
2517struct target_seminfo {
2518    int semmap;
2519    int semmni;
2520    int semmns;
2521    int semmnu;
2522    int semmsl;
2523    int semopm;
2524    int semume;
2525    int semusz;
2526    int semvmx;
2527    int semaem;
2528};
2529
2530static inline abi_long host_to_target_seminfo(abi_ulong target_addr,
2531                                              struct seminfo *host_seminfo)
2532{
2533    struct target_seminfo *target_seminfo;
2534    if (!lock_user_struct(VERIFY_WRITE, target_seminfo, target_addr, 0))
2535        return -TARGET_EFAULT;
2536    __put_user(host_seminfo->semmap, &target_seminfo->semmap);
2537    __put_user(host_seminfo->semmni, &target_seminfo->semmni);
2538    __put_user(host_seminfo->semmns, &target_seminfo->semmns);
2539    __put_user(host_seminfo->semmnu, &target_seminfo->semmnu);
2540    __put_user(host_seminfo->semmsl, &target_seminfo->semmsl);
2541    __put_user(host_seminfo->semopm, &target_seminfo->semopm);
2542    __put_user(host_seminfo->semume, &target_seminfo->semume);
2543    __put_user(host_seminfo->semusz, &target_seminfo->semusz);
2544    __put_user(host_seminfo->semvmx, &target_seminfo->semvmx);
2545    __put_user(host_seminfo->semaem, &target_seminfo->semaem);
2546    unlock_user_struct(target_seminfo, target_addr, 1);
2547    return 0;
2548}
2549
2550union semun {
2551        int val;
2552        struct semid_ds *buf;
2553        unsigned short *array;
2554        struct seminfo *__buf;
2555};
2556
2557union target_semun {
2558        int val;
2559        abi_ulong buf;
2560        abi_ulong array;
2561        abi_ulong __buf;
2562};
2563
2564static inline abi_long target_to_host_semarray(int semid, unsigned short **host_array,
2565                                               abi_ulong target_addr)
2566{
2567    int nsems;
2568    unsigned short *array;
2569    union semun semun;
2570    struct semid_ds semid_ds;
2571    int i, ret;
2572
2573    semun.buf = &semid_ds;
2574
2575    ret = semctl(semid, 0, IPC_STAT, semun);
2576    if (ret == -1)
2577        return get_errno(ret);
2578
2579    nsems = semid_ds.sem_nsems;
2580
2581    *host_array = malloc(nsems*sizeof(unsigned short));
2582    array = lock_user(VERIFY_READ, target_addr,
2583                      nsems*sizeof(unsigned short), 1);
2584    if (!array)
2585        return -TARGET_EFAULT;
2586
2587    for(i=0; i<nsems; i++) {
2588        __get_user((*host_array)[i], &array[i]);
2589    }
2590    unlock_user(array, target_addr, 0);
2591
2592    return 0;
2593}
2594
2595static inline abi_long host_to_target_semarray(int semid, abi_ulong target_addr,
2596                                               unsigned short **host_array)
2597{
2598    int nsems;
2599    unsigned short *array;
2600    union semun semun;
2601    struct semid_ds semid_ds;
2602    int i, ret;
2603
2604    semun.buf = &semid_ds;
2605
2606    ret = semctl(semid, 0, IPC_STAT, semun);
2607    if (ret == -1)
2608        return get_errno(ret);
2609
2610    nsems = semid_ds.sem_nsems;
2611
2612    array = lock_user(VERIFY_WRITE, target_addr,
2613                      nsems*sizeof(unsigned short), 0);
2614    if (!array)
2615        return -TARGET_EFAULT;
2616
2617    for(i=0; i<nsems; i++) {
2618        __put_user((*host_array)[i], &array[i]);
2619    }
2620    free(*host_array);
2621    unlock_user(array, target_addr, 1);
2622
2623    return 0;
2624}
2625
2626static inline abi_long do_semctl(int semid, int semnum, int cmd,
2627                                 union target_semun target_su)
2628{
2629    union semun arg;
2630    struct semid_ds dsarg;
2631    unsigned short *array = NULL;
2632    struct seminfo seminfo;
2633    abi_long ret = -TARGET_EINVAL;
2634    abi_long err;
2635    cmd &= 0xff;
2636
2637    switch( cmd ) {
2638        case GETVAL:
2639        case SETVAL:
2640            arg.val = tswap32(target_su.val);
2641            ret = get_errno(semctl(semid, semnum, cmd, arg));
2642            target_su.val = tswap32(arg.val);
2643            break;
2644        case GETALL:
2645        case SETALL:
2646            err = target_to_host_semarray(semid, &array, target_su.array);
2647            if (err)
2648                return err;
2649            arg.array = array;
2650            ret = get_errno(semctl(semid, semnum, cmd, arg));
2651            err = host_to_target_semarray(semid, target_su.array, &array);
2652            if (err)
2653                return err;
2654            break;
2655        case IPC_STAT:
2656        case IPC_SET:
2657        case SEM_STAT:
2658            err = target_to_host_semid_ds(&dsarg, target_su.buf);
2659            if (err)
2660                return err;
2661            arg.buf = &dsarg;
2662            ret = get_errno(semctl(semid, semnum, cmd, arg));
2663            err = host_to_target_semid_ds(target_su.buf, &dsarg);
2664            if (err)
2665                return err;
2666            break;
2667        case IPC_INFO:
2668        case SEM_INFO:
2669            arg.__buf = &seminfo;
2670            ret = get_errno(semctl(semid, semnum, cmd, arg));
2671            err = host_to_target_seminfo(target_su.__buf, &seminfo);
2672            if (err)
2673                return err;
2674            break;
2675        case IPC_RMID:
2676        case GETPID:
2677        case GETNCNT:
2678        case GETZCNT:
2679            ret = get_errno(semctl(semid, semnum, cmd, NULL));
2680            break;
2681    }
2682
2683    return ret;
2684}
2685
2686struct target_sembuf {
2687    unsigned short sem_num;
2688    short sem_op;
2689    short sem_flg;
2690};
2691
2692static inline abi_long target_to_host_sembuf(struct sembuf *host_sembuf,
2693                                             abi_ulong target_addr,
2694                                             unsigned nsops)
2695{
2696    struct target_sembuf *target_sembuf;
2697    int i;
2698
2699    target_sembuf = lock_user(VERIFY_READ, target_addr,
2700                              nsops*sizeof(struct target_sembuf), 1);
2701    if (!target_sembuf)
2702        return -TARGET_EFAULT;
2703
2704    for(i=0; i<nsops; i++) {
2705        __get_user(host_sembuf[i].sem_num, &target_sembuf[i].sem_num);
2706        __get_user(host_sembuf[i].sem_op, &target_sembuf[i].sem_op);
2707        __get_user(host_sembuf[i].sem_flg, &target_sembuf[i].sem_flg);
2708    }
2709
2710    unlock_user(target_sembuf, target_addr, 0);
2711
2712    return 0;
2713}
2714
2715static inline abi_long do_semop(int semid, abi_long ptr, unsigned nsops)
2716{
2717    struct sembuf sops[nsops];
2718
2719    if (target_to_host_sembuf(sops, ptr, nsops))
2720        return -TARGET_EFAULT;
2721
2722    return get_errno(semop(semid, sops, nsops));
2723}
2724
2725struct target_msqid_ds
2726{
2727    struct target_ipc_perm msg_perm;
2728    abi_ulong msg_stime;
2729#if TARGET_ABI_BITS == 32
2730    abi_ulong __unused1;
2731#endif
2732    abi_ulong msg_rtime;
2733#if TARGET_ABI_BITS == 32
2734    abi_ulong __unused2;
2735#endif
2736    abi_ulong msg_ctime;
2737#if TARGET_ABI_BITS == 32
2738    abi_ulong __unused3;
2739#endif
2740    abi_ulong __msg_cbytes;
2741    abi_ulong msg_qnum;
2742    abi_ulong msg_qbytes;
2743    abi_ulong msg_lspid;
2744    abi_ulong msg_lrpid;
2745    abi_ulong __unused4;
2746    abi_ulong __unused5;
2747};
2748
2749static inline abi_long target_to_host_msqid_ds(struct msqid_ds *host_md,
2750                                               abi_ulong target_addr)
2751{
2752    struct target_msqid_ds *target_md;
2753
2754    if (!lock_user_struct(VERIFY_READ, target_md, target_addr, 1))
2755        return -TARGET_EFAULT;
2756    if (target_to_host_ipc_perm(&(host_md->msg_perm),target_addr))
2757        return -TARGET_EFAULT;
2758    host_md->msg_stime = tswapal(target_md->msg_stime);
2759    host_md->msg_rtime = tswapal(target_md->msg_rtime);
2760    host_md->msg_ctime = tswapal(target_md->msg_ctime);
2761    host_md->__msg_cbytes = tswapal(target_md->__msg_cbytes);
2762    host_md->msg_qnum = tswapal(target_md->msg_qnum);
2763    host_md->msg_qbytes = tswapal(target_md->msg_qbytes);
2764    host_md->msg_lspid = tswapal(target_md->msg_lspid);
2765    host_md->msg_lrpid = tswapal(target_md->msg_lrpid);
2766    unlock_user_struct(target_md, target_addr, 0);
2767    return 0;
2768}
2769
2770static inline abi_long host_to_target_msqid_ds(abi_ulong target_addr,
2771                                               struct msqid_ds *host_md)
2772{
2773    struct target_msqid_ds *target_md;
2774
2775    if (!lock_user_struct(VERIFY_WRITE, target_md, target_addr, 0))
2776        return -TARGET_EFAULT;
2777    if (host_to_target_ipc_perm(target_addr,&(host_md->msg_perm)))
2778        return -TARGET_EFAULT;
2779    target_md->msg_stime = tswapal(host_md->msg_stime);
2780    target_md->msg_rtime = tswapal(host_md->msg_rtime);
2781    target_md->msg_ctime = tswapal(host_md->msg_ctime);
2782    target_md->__msg_cbytes = tswapal(host_md->__msg_cbytes);
2783    target_md->msg_qnum = tswapal(host_md->msg_qnum);
2784    target_md->msg_qbytes = tswapal(host_md->msg_qbytes);
2785    target_md->msg_lspid = tswapal(host_md->msg_lspid);
2786    target_md->msg_lrpid = tswapal(host_md->msg_lrpid);
2787    unlock_user_struct(target_md, target_addr, 1);
2788    return 0;
2789}
2790
2791struct target_msginfo {
2792    int msgpool;
2793    int msgmap;
2794    int msgmax;
2795    int msgmnb;
2796    int msgmni;
2797    int msgssz;
2798    int msgtql;
2799    unsigned short int msgseg;
2800};
2801
2802static inline abi_long host_to_target_msginfo(abi_ulong target_addr,
2803                                              struct msginfo *host_msginfo)
2804{
2805    struct target_msginfo *target_msginfo;
2806    if (!lock_user_struct(VERIFY_WRITE, target_msginfo, target_addr, 0))
2807        return -TARGET_EFAULT;
2808    __put_user(host_msginfo->msgpool, &target_msginfo->msgpool);
2809    __put_user(host_msginfo->msgmap, &target_msginfo->msgmap);
2810    __put_user(host_msginfo->msgmax, &target_msginfo->msgmax);
2811    __put_user(host_msginfo->msgmnb, &target_msginfo->msgmnb);
2812    __put_user(host_msginfo->msgmni, &target_msginfo->msgmni);
2813    __put_user(host_msginfo->msgssz, &target_msginfo->msgssz);
2814    __put_user(host_msginfo->msgtql, &target_msginfo->msgtql);
2815    __put_user(host_msginfo->msgseg, &target_msginfo->msgseg);
2816    unlock_user_struct(target_msginfo, target_addr, 1);
2817    return 0;
2818}
2819
2820static inline abi_long do_msgctl(int msgid, int cmd, abi_long ptr)
2821{
2822    struct msqid_ds dsarg;
2823    struct msginfo msginfo;
2824    abi_long ret = -TARGET_EINVAL;
2825
2826    cmd &= 0xff;
2827
2828    switch (cmd) {
2829    case IPC_STAT:
2830    case IPC_SET:
2831    case MSG_STAT:
2832        if (target_to_host_msqid_ds(&dsarg,ptr))
2833            return -TARGET_EFAULT;
2834        ret = get_errno(msgctl(msgid, cmd, &dsarg));
2835        if (host_to_target_msqid_ds(ptr,&dsarg))
2836            return -TARGET_EFAULT;
2837        break;
2838    case IPC_RMID:
2839        ret = get_errno(msgctl(msgid, cmd, NULL));
2840        break;
2841    case IPC_INFO:
2842    case MSG_INFO:
2843        ret = get_errno(msgctl(msgid, cmd, (struct msqid_ds *)&msginfo));
2844        if (host_to_target_msginfo(ptr, &msginfo))
2845            return -TARGET_EFAULT;
2846        break;
2847    }
2848
2849    return ret;
2850}
2851
2852struct target_msgbuf {
2853    abi_long mtype;
2854    char        mtext[1];
2855};
2856
2857static inline abi_long do_msgsnd(int msqid, abi_long msgp,
2858                                 unsigned int msgsz, int msgflg)
2859{
2860    struct target_msgbuf *target_mb;
2861    struct msgbuf *host_mb;
2862    abi_long ret = 0;
2863
2864    if (!lock_user_struct(VERIFY_READ, target_mb, msgp, 0))
2865        return -TARGET_EFAULT;
2866    host_mb = malloc(msgsz+sizeof(long));
2867    host_mb->mtype = (abi_long) tswapal(target_mb->mtype);
2868    memcpy(host_mb->mtext, target_mb->mtext, msgsz);
2869    ret = get_errno(msgsnd(msqid, host_mb, msgsz, msgflg));
2870    free(host_mb);
2871    unlock_user_struct(target_mb, msgp, 0);
2872
2873    return ret;
2874}
2875
2876static inline abi_long do_msgrcv(int msqid, abi_long msgp,
2877                                 unsigned int msgsz, abi_long msgtyp,
2878                                 int msgflg)
2879{
2880    struct target_msgbuf *target_mb;
2881    char *target_mtext;
2882    struct msgbuf *host_mb;
2883    abi_long ret = 0;
2884
2885    if (!lock_user_struct(VERIFY_WRITE, target_mb, msgp, 0))
2886        return -TARGET_EFAULT;
2887
2888    host_mb = g_malloc(msgsz+sizeof(long));
2889    ret = get_errno(msgrcv(msqid, host_mb, msgsz, msgtyp, msgflg));
2890
2891    if (ret > 0) {
2892        abi_ulong target_mtext_addr = msgp + sizeof(abi_ulong);
2893        target_mtext = lock_user(VERIFY_WRITE, target_mtext_addr, ret, 0);
2894        if (!target_mtext) {
2895            ret = -TARGET_EFAULT;
2896            goto end;
2897        }
2898        memcpy(target_mb->mtext, host_mb->mtext, ret);
2899        unlock_user(target_mtext, target_mtext_addr, ret);
2900    }
2901
2902    target_mb->mtype = tswapal(host_mb->mtype);
2903
2904end:
2905    if (target_mb)
2906        unlock_user_struct(target_mb, msgp, 1);
2907    g_free(host_mb);
2908    return ret;
2909}
2910
2911struct target_shmid_ds
2912{
2913    struct target_ipc_perm shm_perm;
2914    abi_ulong shm_segsz;
2915    abi_ulong shm_atime;
2916#if TARGET_ABI_BITS == 32
2917    abi_ulong __unused1;
2918#endif
2919    abi_ulong shm_dtime;
2920#if TARGET_ABI_BITS == 32
2921    abi_ulong __unused2;
2922#endif
2923    abi_ulong shm_ctime;
2924#if TARGET_ABI_BITS == 32
2925    abi_ulong __unused3;
2926#endif
2927    int shm_cpid;
2928    int shm_lpid;
2929    abi_ulong shm_nattch;
2930    unsigned long int __unused4;
2931    unsigned long int __unused5;
2932};
2933
2934static inline abi_long target_to_host_shmid_ds(struct shmid_ds *host_sd,
2935                                               abi_ulong target_addr)
2936{
2937    struct target_shmid_ds *target_sd;
2938
2939    if (!lock_user_struct(VERIFY_READ, target_sd, target_addr, 1))
2940        return -TARGET_EFAULT;
2941    if (target_to_host_ipc_perm(&(host_sd->shm_perm), target_addr))
2942        return -TARGET_EFAULT;
2943    __get_user(host_sd->shm_segsz, &target_sd->shm_segsz);
2944    __get_user(host_sd->shm_atime, &target_sd->shm_atime);
2945    __get_user(host_sd->shm_dtime, &target_sd->shm_dtime);
2946    __get_user(host_sd->shm_ctime, &target_sd->shm_ctime);
2947    __get_user(host_sd->shm_cpid, &target_sd->shm_cpid);
2948    __get_user(host_sd->shm_lpid, &target_sd->shm_lpid);
2949    __get_user(host_sd->shm_nattch, &target_sd->shm_nattch);
2950    unlock_user_struct(target_sd, target_addr, 0);
2951    return 0;
2952}
2953
2954static inline abi_long host_to_target_shmid_ds(abi_ulong target_addr,
2955                                               struct shmid_ds *host_sd)
2956{
2957    struct target_shmid_ds *target_sd;
2958
2959    if (!lock_user_struct(VERIFY_WRITE, target_sd, target_addr, 0))
2960        return -TARGET_EFAULT;
2961    if (host_to_target_ipc_perm(target_addr, &(host_sd->shm_perm)))
2962        return -TARGET_EFAULT;
2963    __put_user(host_sd->shm_segsz, &target_sd->shm_segsz);
2964    __put_user(host_sd->shm_atime, &target_sd->shm_atime);
2965    __put_user(host_sd->shm_dtime, &target_sd->shm_dtime);
2966    __put_user(host_sd->shm_ctime, &target_sd->shm_ctime);
2967    __put_user(host_sd->shm_cpid, &target_sd->shm_cpid);
2968    __put_user(host_sd->shm_lpid, &target_sd->shm_lpid);
2969    __put_user(host_sd->shm_nattch, &target_sd->shm_nattch);
2970    unlock_user_struct(target_sd, target_addr, 1);
2971    return 0;
2972}
2973
2974struct  target_shminfo {
2975    abi_ulong shmmax;
2976    abi_ulong shmmin;
2977    abi_ulong shmmni;
2978    abi_ulong shmseg;
2979    abi_ulong shmall;
2980};
2981
2982static inline abi_long host_to_target_shminfo(abi_ulong target_addr,
2983                                              struct shminfo *host_shminfo)
2984{
2985    struct target_shminfo *target_shminfo;
2986    if (!lock_user_struct(VERIFY_WRITE, target_shminfo, target_addr, 0))
2987        return -TARGET_EFAULT;
2988    __put_user(host_shminfo->shmmax, &target_shminfo->shmmax);
2989    __put_user(host_shminfo->shmmin, &target_shminfo->shmmin);
2990    __put_user(host_shminfo->shmmni, &target_shminfo->shmmni);
2991    __put_user(host_shminfo->shmseg, &target_shminfo->shmseg);
2992    __put_user(host_shminfo->shmall, &target_shminfo->shmall);
2993    unlock_user_struct(target_shminfo, target_addr, 1);
2994    return 0;
2995}
2996
2997struct target_shm_info {
2998    int used_ids;
2999    abi_ulong shm_tot;
3000    abi_ulong shm_rss;
3001    abi_ulong shm_swp;
3002    abi_ulong swap_attempts;
3003    abi_ulong swap_successes;
3004};
3005
3006static inline abi_long host_to_target_shm_info(abi_ulong target_addr,
3007                                               struct shm_info *host_shm_info)
3008{
3009    struct target_shm_info *target_shm_info;
3010    if (!lock_user_struct(VERIFY_WRITE, target_shm_info, target_addr, 0))
3011        return -TARGET_EFAULT;
3012    __put_user(host_shm_info->used_ids, &target_shm_info->used_ids);
3013    __put_user(host_shm_info->shm_tot, &target_shm_info->shm_tot);
3014    __put_user(host_shm_info->shm_rss, &target_shm_info->shm_rss);
3015    __put_user(host_shm_info->shm_swp, &target_shm_info->shm_swp);
3016    __put_user(host_shm_info->swap_attempts, &target_shm_info->swap_attempts);
3017    __put_user(host_shm_info->swap_successes, &target_shm_info->swap_successes);
3018    unlock_user_struct(target_shm_info, target_addr, 1);
3019    return 0;
3020}
3021
3022static inline abi_long do_shmctl(int shmid, int cmd, abi_long buf)
3023{
3024    struct shmid_ds dsarg;
3025    struct shminfo shminfo;
3026    struct shm_info shm_info;
3027    abi_long ret = -TARGET_EINVAL;
3028
3029    cmd &= 0xff;
3030
3031    switch(cmd) {
3032    case IPC_STAT:
3033    case IPC_SET:
3034    case SHM_STAT:
3035        if (target_to_host_shmid_ds(&dsarg, buf))
3036            return -TARGET_EFAULT;
3037        ret = get_errno(shmctl(shmid, cmd, &dsarg));
3038        if (host_to_target_shmid_ds(buf, &dsarg))
3039            return -TARGET_EFAULT;
3040        break;
3041    case IPC_INFO:
3042        ret = get_errno(shmctl(shmid, cmd, (struct shmid_ds *)&shminfo));
3043        if (host_to_target_shminfo(buf, &shminfo))
3044            return -TARGET_EFAULT;
3045        break;
3046    case SHM_INFO:
3047        ret = get_errno(shmctl(shmid, cmd, (struct shmid_ds *)&shm_info));
3048        if (host_to_target_shm_info(buf, &shm_info))
3049            return -TARGET_EFAULT;
3050        break;
3051    case IPC_RMID:
3052    case SHM_LOCK:
3053    case SHM_UNLOCK:
3054        ret = get_errno(shmctl(shmid, cmd, NULL));
3055        break;
3056    }
3057
3058    return ret;
3059}
3060
3061static inline abi_ulong do_shmat(int shmid, abi_ulong shmaddr, int shmflg)
3062{
3063    abi_long raddr;
3064    void *host_raddr;
3065    struct shmid_ds shm_info;
3066    int i,ret;
3067
3068    /* find out the length of the shared memory segment */
3069    ret = get_errno(shmctl(shmid, IPC_STAT, &shm_info));
3070    if (is_error(ret)) {
3071        /* can't get length, bail out */
3072        return ret;
3073    }
3074
3075    mmap_lock();
3076
3077    if (shmaddr)
3078        host_raddr = shmat(shmid, (void *)g2h(shmaddr), shmflg);
3079    else {
3080        abi_ulong mmap_start;
3081
3082        mmap_start = mmap_find_vma(0, shm_info.shm_segsz);
3083
3084        if (mmap_start == -1) {
3085            errno = ENOMEM;
3086            host_raddr = (void *)-1;
3087        } else
3088            host_raddr = shmat(shmid, g2h(mmap_start), shmflg | SHM_REMAP);
3089    }
3090
3091    if (host_raddr == (void *)-1) {
3092        mmap_unlock();
3093        return get_errno((long)host_raddr);
3094    }
3095    raddr=h2g((unsigned long)host_raddr);
3096
3097    page_set_flags(raddr, raddr + shm_info.shm_segsz,
3098                   PAGE_VALID | PAGE_READ |
3099                   ((shmflg & SHM_RDONLY)? 0 : PAGE_WRITE));
3100
3101    for (i = 0; i < N_SHM_REGIONS; i++) {
3102        if (shm_regions[i].start == 0) {
3103            shm_regions[i].start = raddr;
3104            shm_regions[i].size = shm_info.shm_segsz;
3105            break;
3106        }
3107    }
3108
3109    mmap_unlock();
3110    return raddr;
3111
3112}
3113
3114static inline abi_long do_shmdt(abi_ulong shmaddr)
3115{
3116    int i;
3117
3118    for (i = 0; i < N_SHM_REGIONS; ++i) {
3119        if (shm_regions[i].start == shmaddr) {
3120            shm_regions[i].start = 0;
3121            page_set_flags(shmaddr, shmaddr + shm_regions[i].size, 0);
3122            break;
3123        }
3124    }
3125
3126    return get_errno(shmdt(g2h(shmaddr)));
3127}
3128
3129#ifdef TARGET_NR_ipc
3130/* ??? This only works with linear mappings.  */
3131/* do_ipc() must return target values and target errnos. */
3132static abi_long do_ipc(unsigned int call, int first,
3133                       int second, int third,
3134                       abi_long ptr, abi_long fifth)
3135{
3136    int version;
3137    abi_long ret = 0;
3138
3139    version = call >> 16;
3140    call &= 0xffff;
3141
3142    switch (call) {
3143    case IPCOP_semop:
3144        ret = do_semop(first, ptr, second);
3145        break;
3146
3147    case IPCOP_semget:
3148        ret = get_errno(semget(first, second, third));
3149        break;
3150
3151    case IPCOP_semctl:
3152        ret = do_semctl(first, second, third, (union target_semun)(abi_ulong) ptr);
3153        break;
3154
3155    case IPCOP_msgget:
3156        ret = get_errno(msgget(first, second));
3157        break;
3158
3159    case IPCOP_msgsnd:
3160        ret = do_msgsnd(first, ptr, second, third);
3161        break;
3162
3163    case IPCOP_msgctl:
3164        ret = do_msgctl(first, second, ptr);
3165        break;
3166
3167    case IPCOP_msgrcv:
3168        switch (version) {
3169        case 0:
3170            {
3171                struct target_ipc_kludge {
3172                    abi_long msgp;
3173                    abi_long msgtyp;
3174                } *tmp;
3175
3176                if (!lock_user_struct(VERIFY_READ, tmp, ptr, 1)) {
3177                    ret = -TARGET_EFAULT;
3178                    break;
3179                }
3180
3181                ret = do_msgrcv(first, tswapal(tmp->msgp), second, tswapal(tmp->msgtyp), third);
3182
3183                unlock_user_struct(tmp, ptr, 0);
3184                break;
3185            }
3186        default:
3187            ret = do_msgrcv(first, ptr, second, fifth, third);
3188        }
3189        break;
3190
3191    case IPCOP_shmat:
3192        switch (version) {
3193        default:
3194        {
3195            abi_ulong raddr;
3196            raddr = do_shmat(first, ptr, second);
3197            if (is_error(raddr))
3198                return get_errno(raddr);
3199            if (put_user_ual(raddr, third))
3200                return -TARGET_EFAULT;
3201            break;
3202        }
3203        case 1:
3204            ret = -TARGET_EINVAL;
3205            break;
3206        }
3207        break;
3208    case IPCOP_shmdt:
3209        ret = do_shmdt(ptr);
3210        break;
3211
3212    case IPCOP_shmget:
3213        /* IPC_* flag values are the same on all linux platforms */
3214        ret = get_errno(shmget(first, second, third));
3215        break;
3216
3217        /* IPC_* and SHM_* command values are the same on all linux platforms */
3218    case IPCOP_shmctl:
3219        ret = do_shmctl(first, second, third);
3220        break;
3221    default:
3222        gemu_log("Unsupported ipc call: %d (version %d)\n", call, version);
3223        ret = -TARGET_ENOSYS;
3224        break;
3225    }
3226    return ret;
3227}
3228#endif
3229
3230/* kernel structure types definitions */
3231
3232#define STRUCT(name, ...) STRUCT_ ## name,
3233#define STRUCT_SPECIAL(name) STRUCT_ ## name,
3234enum {
3235#include "syscall_types.h"
3236};
3237#undef STRUCT
3238#undef STRUCT_SPECIAL
3239
3240#define STRUCT(name, ...) static const argtype struct_ ## name ## _def[] = {  __VA_ARGS__, TYPE_NULL };
3241#define STRUCT_SPECIAL(name)
3242#include "syscall_types.h"
3243#undef STRUCT
3244#undef STRUCT_SPECIAL
3245
3246typedef struct IOCTLEntry IOCTLEntry;
3247
3248typedef abi_long do_ioctl_fn(const IOCTLEntry *ie, uint8_t *buf_temp,
3249                             int fd, abi_long cmd, abi_long arg);
3250
3251struct IOCTLEntry {
3252    unsigned int target_cmd;
3253    unsigned int host_cmd;
3254    const char *name;
3255    int access;
3256    do_ioctl_fn *do_ioctl;
3257    const argtype arg_type[5];
3258};
3259
3260#define IOC_R 0x0001
3261#define IOC_W 0x0002
3262#define IOC_RW (IOC_R | IOC_W)
3263
3264#define MAX_STRUCT_SIZE 4096
3265
3266#ifdef CONFIG_FIEMAP
3267/* So fiemap access checks don't overflow on 32 bit systems.
3268 * This is very slightly smaller than the limit imposed by
3269 * the underlying kernel.
3270 */
3271#define FIEMAP_MAX_EXTENTS ((UINT_MAX - sizeof(struct fiemap))  \
3272                            / sizeof(struct fiemap_extent))
3273
3274static abi_long do_ioctl_fs_ioc_fiemap(const IOCTLEntry *ie, uint8_t *buf_temp,
3275                                       int fd, abi_long cmd, abi_long arg)
3276{
3277    /* The parameter for this ioctl is a struct fiemap followed
3278     * by an array of struct fiemap_extent whose size is set
3279     * in fiemap->fm_extent_count. The array is filled in by the
3280     * ioctl.
3281     */
3282    int target_size_in, target_size_out;
3283    struct fiemap *fm;
3284    const argtype *arg_type = ie->arg_type;
3285    const argtype extent_arg_type[] = { MK_STRUCT(STRUCT_fiemap_extent) };
3286    void *argptr, *p;
3287    abi_long ret;
3288    int i, extent_size = thunk_type_size(extent_arg_type, 0);
3289    uint32_t outbufsz;
3290    int free_fm = 0;
3291
3292    assert(arg_type[0] == TYPE_PTR);
3293    assert(ie->access == IOC_RW);
3294    arg_type++;
3295    target_size_in = thunk_type_size(arg_type, 0);
3296    argptr = lock_user(VERIFY_READ, arg, target_size_in, 1);
3297    if (!argptr) {
3298        return -TARGET_EFAULT;
3299    }
3300    thunk_convert(buf_temp, argptr, arg_type, THUNK_HOST);
3301    unlock_user(argptr, arg, 0);
3302    fm = (struct fiemap *)buf_temp;
3303    if (fm->fm_extent_count > FIEMAP_MAX_EXTENTS) {
3304        return -TARGET_EINVAL;
3305    }
3306
3307    outbufsz = sizeof (*fm) +
3308        (sizeof(struct fiemap_extent) * fm->fm_extent_count);
3309
3310    if (outbufsz > MAX_STRUCT_SIZE) {
3311        /* We can't fit all the extents into the fixed size buffer.
3312         * Allocate one that is large enough and use it instead.
3313         */
3314        fm = malloc(outbufsz);
3315        if (!fm) {
3316            return -TARGET_ENOMEM;
3317        }
3318        memcpy(fm, buf_temp, sizeof(struct fiemap));
3319        free_fm = 1;
3320    }
3321    ret = get_errno(ioctl(fd, ie->host_cmd, fm));
3322    if (!is_error(ret)) {
3323        target_size_out = target_size_in;
3324        /* An extent_count of 0 means we were only counting the extents
3325         * so there are no structs to copy
3326         */
3327        if (fm->fm_extent_count != 0) {
3328            target_size_out += fm->fm_mapped_extents * extent_size;
3329        }
3330        argptr = lock_user(VERIFY_WRITE, arg, target_size_out, 0);
3331        if (!argptr) {
3332            ret = -TARGET_EFAULT;
3333        } else {
3334            /* Convert the struct fiemap */
3335            thunk_convert(argptr, fm, arg_type, THUNK_TARGET);
3336            if (fm->fm_extent_count != 0) {
3337                p = argptr + target_size_in;
3338                /* ...and then all the struct fiemap_extents */
3339                for (i = 0; i < fm->fm_mapped_extents; i++) {
3340                    thunk_convert(p, &fm->fm_extents[i], extent_arg_type,
3341                                  THUNK_TARGET);
3342                    p += extent_size;
3343                }
3344            }
3345            unlock_user(argptr, arg, target_size_out);
3346        }
3347    }
3348    if (free_fm) {
3349        free(fm);
3350    }
3351    return ret;
3352}
3353#endif
3354
3355static abi_long do_ioctl_ifconf(const IOCTLEntry *ie, uint8_t *buf_temp,
3356                                int fd, abi_long cmd, abi_long arg)
3357{
3358    const argtype *arg_type = ie->arg_type;
3359    int target_size;
3360    void *argptr;
3361    int ret;
3362    struct ifconf *host_ifconf;
3363    uint32_t outbufsz;
3364    const argtype ifreq_arg_type[] = { MK_STRUCT(STRUCT_sockaddr_ifreq) };
3365    int target_ifreq_size;
3366    int nb_ifreq;
3367    int free_buf = 0;
3368    int i;
3369    int target_ifc_len;
3370    abi_long target_ifc_buf;
3371    int host_ifc_len;
3372    char *host_ifc_buf;
3373
3374    assert(arg_type[0] == TYPE_PTR);
3375    assert(ie->access == IOC_RW);
3376
3377    arg_type++;
3378    target_size = thunk_type_size(arg_type, 0);
3379
3380    argptr = lock_user(VERIFY_READ, arg, target_size, 1);
3381    if (!argptr)
3382        return -TARGET_EFAULT;
3383    thunk_convert(buf_temp, argptr, arg_type, THUNK_HOST);
3384    unlock_user(argptr, arg, 0);
3385
3386    host_ifconf = (struct ifconf *)(unsigned long)buf_temp;
3387    target_ifc_len = host_ifconf->ifc_len;
3388    target_ifc_buf = (abi_long)(unsigned long)host_ifconf->ifc_buf;
3389
3390    target_ifreq_size = thunk_type_size(ifreq_arg_type, 0);
3391    nb_ifreq = target_ifc_len / target_ifreq_size;
3392    host_ifc_len = nb_ifreq * sizeof(struct ifreq);
3393
3394    outbufsz = sizeof(*host_ifconf) + host_ifc_len;
3395    if (outbufsz > MAX_STRUCT_SIZE) {
3396        /* We can't fit all the extents into the fixed size buffer.
3397         * Allocate one that is large enough and use it instead.
3398         */
3399        host_ifconf = malloc(outbufsz);
3400        if (!host_ifconf) {
3401            return -TARGET_ENOMEM;
3402        }
3403        memcpy(host_ifconf, buf_temp, sizeof(*host_ifconf));
3404        free_buf = 1;
3405    }
3406    host_ifc_buf = (char*)host_ifconf + sizeof(*host_ifconf);
3407
3408    host_ifconf->ifc_len = host_ifc_len;
3409    host_ifconf->ifc_buf = host_ifc_buf;
3410
3411    ret = get_errno(ioctl(fd, ie->host_cmd, host_ifconf));
3412    if (!is_error(ret)) {
3413        /* convert host ifc_len to target ifc_len */
3414
3415        nb_ifreq = host_ifconf->ifc_len / sizeof(struct ifreq);
3416        target_ifc_len = nb_ifreq * target_ifreq_size;
3417        host_ifconf->ifc_len = target_ifc_len;
3418
3419        /* restore target ifc_buf */
3420
3421        host_ifconf->ifc_buf = (char *)(unsigned long)target_ifc_buf;
3422
3423        /* copy struct ifconf to target user */
3424
3425        argptr = lock_user(VERIFY_WRITE, arg, target_size, 0);
3426        if (!argptr)
3427            return -TARGET_EFAULT;
3428        thunk_convert(argptr, host_ifconf, arg_type, THUNK_TARGET);
3429        unlock_user(argptr, arg, target_size);
3430
3431        /* copy ifreq[] to target user */
3432
3433        argptr = lock_user(VERIFY_WRITE, target_ifc_buf, target_ifc_len, 0);
3434        for (i = 0; i < nb_ifreq ; i++) {
3435            thunk_convert(argptr + i * target_ifreq_size,
3436                          host_ifc_buf + i * sizeof(struct ifreq),
3437                          ifreq_arg_type, THUNK_TARGET);
3438        }
3439        unlock_user(argptr, target_ifc_buf, target_ifc_len);
3440    }
3441
3442    if (free_buf) {
3443        free(host_ifconf);
3444    }
3445
3446    return ret;
3447}
3448
3449static abi_long do_ioctl_dm(const IOCTLEntry *ie, uint8_t *buf_temp, int fd,
3450                            abi_long cmd, abi_long arg)
3451{
3452    void *argptr;
3453    struct dm_ioctl *host_dm;
3454    abi_long guest_data;
3455    uint32_t guest_data_size;
3456    int target_size;
3457    const argtype *arg_type = ie->arg_type;
3458    abi_long ret;
3459    void *big_buf = NULL;
3460    char *host_data;
3461
3462    arg_type++;
3463    target_size = thunk_type_size(arg_type, 0);
3464    argptr = lock_user(VERIFY_READ, arg, target_size, 1);
3465    if (!argptr) {
3466        ret = -TARGET_EFAULT;
3467        goto out;
3468    }
3469    thunk_convert(buf_temp, argptr, arg_type, THUNK_HOST);
3470    unlock_user(argptr, arg, 0);
3471
3472    /* buf_temp is too small, so fetch things into a bigger buffer */
3473    big_buf = g_malloc0(((struct dm_ioctl*)buf_temp)->data_size * 2);
3474    memcpy(big_buf, buf_temp, target_size);
3475    buf_temp = big_buf;
3476    host_dm = big_buf;
3477
3478    guest_data = arg + host_dm->data_start;
3479    if ((guest_data - arg) < 0) {
3480        ret = -EINVAL;
3481        goto out;
3482    }
3483    guest_data_size = host_dm->data_size - host_dm->data_start;
3484    host_data = (char*)host_dm + host_dm->data_start;
3485
3486    argptr = lock_user(VERIFY_READ, guest_data, guest_data_size, 1);
3487    switch (ie->host_cmd) {
3488    case DM_REMOVE_ALL:
3489    case DM_LIST_DEVICES:
3490    case DM_DEV_CREATE:
3491    case DM_DEV_REMOVE:
3492    case DM_DEV_SUSPEND:
3493    case DM_DEV_STATUS:
3494    case DM_DEV_WAIT:
3495    case DM_TABLE_STATUS:
3496    case DM_TABLE_CLEAR:
3497    case DM_TABLE_DEPS:
3498    case DM_LIST_VERSIONS:
3499        /* no input data */
3500        break;
3501    case DM_DEV_RENAME:
3502    case DM_DEV_SET_GEOMETRY:
3503        /* data contains only strings */
3504        memcpy(host_data, argptr, guest_data_size);
3505        break;
3506    case DM_TARGET_MSG:
3507        memcpy(host_data, argptr, guest_data_size);
3508        *(uint64_t*)host_data = tswap64(*(uint64_t*)argptr);
3509        break;
3510    case DM_TABLE_LOAD:
3511    {
3512        void *gspec = argptr;
3513        void *cur_data = host_data;
3514        const argtype arg_type[] = { MK_STRUCT(STRUCT_dm_target_spec) };
3515        int spec_size = thunk_type_size(arg_type, 0);
3516        int i;
3517
3518        for (i = 0; i < host_dm->target_count; i++) {
3519            struct dm_target_spec *spec = cur_data;
3520            uint32_t next;
3521            int slen;
3522
3523            thunk_convert(spec, gspec, arg_type, THUNK_HOST);
3524            slen = strlen((char*)gspec + spec_size) + 1;
3525            next = spec->next;
3526            spec->next = sizeof(*spec) + slen;
3527            strcpy((char*)&spec[1], gspec + spec_size);
3528            gspec += next;
3529            cur_data += spec->next;
3530        }
3531        break;
3532    }
3533    default:
3534        ret = -TARGET_EINVAL;
3535        goto out;
3536    }
3537    unlock_user(argptr, guest_data, 0);
3538
3539    ret = get_errno(ioctl(fd, ie->host_cmd, buf_temp));
3540    if (!is_error(ret)) {
3541        guest_data = arg + host_dm->data_start;
3542        guest_data_size = host_dm->data_size - host_dm->data_start;
3543        argptr = lock_user(VERIFY_WRITE, guest_data, guest_data_size, 0);
3544        switch (ie->host_cmd) {
3545        case DM_REMOVE_ALL:
3546        case DM_DEV_CREATE:
3547        case DM_DEV_REMOVE:
3548        case DM_DEV_RENAME:
3549        case DM_DEV_SUSPEND:
3550        case DM_DEV_STATUS:
3551        case DM_TABLE_LOAD:
3552        case DM_TABLE_CLEAR:
3553        case DM_TARGET_MSG:
3554        case DM_DEV_SET_GEOMETRY:
3555            /* no return data */
3556            break;
3557        case DM_LIST_DEVICES:
3558        {
3559            struct dm_name_list *nl = (void*)host_dm + host_dm->data_start;
3560            uint32_t remaining_data = guest_data_size;
3561            void *cur_data = argptr;
3562            const argtype arg_type[] = { MK_STRUCT(STRUCT_dm_name_list) };
3563            int nl_size = 12; /* can't use thunk_size due to alignment */
3564
3565            while (1) {
3566                uint32_t next = nl->next;
3567                if (next) {
3568                    nl->next = nl_size + (strlen(nl->name) + 1);
3569                }
3570                if (remaining_data < nl->next) {
3571                    host_dm->flags |= DM_BUFFER_FULL_FLAG;
3572                    break;
3573                }
3574                thunk_convert(cur_data, nl, arg_type, THUNK_TARGET);
3575                strcpy(cur_data + nl_size, nl->name);
3576                cur_data += nl->next;
3577                remaining_data -= nl->next;
3578                if (!next) {
3579                    break;
3580                }
3581                nl = (void*)nl + next;
3582            }
3583            break;
3584        }
3585        case DM_DEV_WAIT:
3586        case DM_TABLE_STATUS:
3587        {
3588            struct dm_target_spec *spec = (void*)host_dm + host_dm->data_start;
3589            void *cur_data = argptr;
3590            const argtype arg_type[] = { MK_STRUCT(STRUCT_dm_target_spec) };
3591            int spec_size = thunk_type_size(arg_type, 0);
3592            int i;
3593
3594            for (i = 0; i < host_dm->target_count; i++) {
3595                uint32_t next = spec->next;
3596                int slen = strlen((char*)&spec[1]) + 1;
3597                spec->next = (cur_data - argptr) + spec_size + slen;
3598                if (guest_data_size < spec->next) {
3599                    host_dm->flags |= DM_BUFFER_FULL_FLAG;
3600                    break;
3601                }
3602                thunk_convert(cur_data, spec, arg_type, THUNK_TARGET);
3603                strcpy(cur_data + spec_size, (char*)&spec[1]);
3604                cur_data = argptr + spec->next;
3605                spec = (void*)host_dm + host_dm->data_start + next;
3606            }
3607            break;
3608        }
3609        case DM_TABLE_DEPS:
3610        {
3611            void *hdata = (void*)host_dm + host_dm->data_start;
3612            int count = *(uint32_t*)hdata;
3613            uint64_t *hdev = hdata + 8;
3614            uint64_t *gdev = argptr + 8;
3615            int i;
3616
3617            *(uint32_t*)argptr = tswap32(count);
3618            for (i = 0; i < count; i++) {
3619                *gdev = tswap64(*hdev);
3620                gdev++;
3621                hdev++;
3622            }
3623            break;
3624        }
3625        case DM_LIST_VERSIONS:
3626        {
3627            struct dm_target_versions *vers = (void*)host_dm + host_dm->data_start;
3628            uint32_t remaining_data = guest_data_size;
3629            void *cur_data = argptr;
3630            const argtype arg_type[] = { MK_STRUCT(STRUCT_dm_target_versions) };
3631            int vers_size = thunk_type_size(arg_type, 0);
3632
3633            while (1) {
3634                uint32_t next = vers->next;
3635                if (next) {
3636                    vers->next = vers_size + (strlen(vers->name) + 1);
3637                }
3638                if (remaining_data < vers->next) {
3639                    host_dm->flags |= DM_BUFFER_FULL_FLAG;
3640                    break;
3641                }
3642                thunk_convert(cur_data, vers, arg_type, THUNK_TARGET);
3643                strcpy(cur_data + vers_size, vers->name);
3644                cur_data += vers->next;
3645                remaining_data -= vers->next;
3646                if (!next) {
3647                    break;
3648                }
3649                vers = (void*)vers + next;
3650            }
3651            break;
3652        }
3653        default:
3654            ret = -TARGET_EINVAL;
3655            goto out;
3656        }
3657        unlock_user(argptr, guest_data, guest_data_size);
3658
3659        argptr = lock_user(VERIFY_WRITE, arg, target_size, 0);
3660        if (!argptr) {
3661            ret = -TARGET_EFAULT;
3662            goto out;
3663        }
3664        thunk_convert(argptr, buf_temp, arg_type, THUNK_TARGET);
3665        unlock_user(argptr, arg, target_size);
3666    }
3667out:
3668    g_free(big_buf);
3669    return ret;
3670}
3671
3672static abi_long do_ioctl_rt(const IOCTLEntry *ie, uint8_t *buf_temp,
3673                                int fd, abi_long cmd, abi_long arg)
3674{
3675    const argtype *arg_type = ie->arg_type;
3676    const StructEntry *se;
3677    const argtype *field_types;
3678    const int *dst_offsets, *src_offsets;
3679    int target_size;
3680    void *argptr;
3681    abi_ulong *target_rt_dev_ptr;
3682    unsigned long *host_rt_dev_ptr;
3683    abi_long ret;
3684    int i;
3685
3686    assert(ie->access == IOC_W);
3687    assert(*arg_type == TYPE_PTR);
3688    arg_type++;
3689    assert(*arg_type == TYPE_STRUCT);
3690    target_size = thunk_type_size(arg_type, 0);
3691    argptr = lock_user(VERIFY_READ, arg, target_size, 1);
3692    if (!argptr) {
3693        return -TARGET_EFAULT;
3694    }
3695    arg_type++;
3696    assert(*arg_type == (int)STRUCT_rtentry);
3697    se = struct_entries + *arg_type++;
3698    assert(se->convert[0] == NULL);
3699    /* convert struct here to be able to catch rt_dev string */
3700    field_types = se->field_types;
3701    dst_offsets = se->field_offsets[THUNK_HOST];
3702    src_offsets = se->field_offsets[THUNK_TARGET];
3703    for (i = 0; i < se->nb_fields; i++) {
3704        if (dst_offsets[i] == offsetof(struct rtentry, rt_dev)) {
3705            assert(*field_types == TYPE_PTRVOID);
3706            target_rt_dev_ptr = (abi_ulong *)(argptr + src_offsets[i]);
3707            host_rt_dev_ptr = (unsigned long *)(buf_temp + dst_offsets[i]);
3708            if (*target_rt_dev_ptr != 0) {
3709                *host_rt_dev_ptr = (unsigned long)lock_user_string(
3710                                                  tswapal(*target_rt_dev_ptr));
3711                if (!*host_rt_dev_ptr) {
3712                    unlock_user(argptr, arg, 0);
3713                    return -TARGET_EFAULT;
3714                }
3715            } else {
3716                *host_rt_dev_ptr = 0;
3717            }
3718            field_types++;
3719            continue;
3720        }
3721        field_types = thunk_convert(buf_temp + dst_offsets[i],
3722                                    argptr + src_offsets[i],
3723                                    field_types, THUNK_HOST);
3724    }
3725    unlock_user(argptr, arg, 0);
3726
3727    ret = get_errno(ioctl(fd, ie->host_cmd, buf_temp));
3728    if (*host_rt_dev_ptr != 0) {
3729        unlock_user((void *)*host_rt_dev_ptr,
3730                    *target_rt_dev_ptr, 0);
3731    }
3732    return ret;
3733}
3734
3735static IOCTLEntry ioctl_entries[] = {
3736#define IOCTL(cmd, access, ...) \
3737    { TARGET_ ## cmd, cmd, #cmd, access, 0, {  __VA_ARGS__ } },
3738#define IOCTL_SPECIAL(cmd, access, dofn, ...)                      \
3739    { TARGET_ ## cmd, cmd, #cmd, access, dofn, {  __VA_ARGS__ } },
3740#include "ioctls.h"
3741    { 0, 0, },
3742};
3743
3744/* ??? Implement proper locking for ioctls.  */
3745/* do_ioctl() Must return target values and target errnos. */
3746static abi_long do_ioctl(int fd, abi_long cmd, abi_long arg)
3747{
3748    const IOCTLEntry *ie;
3749    const argtype *arg_type;
3750    abi_long ret;
3751    uint8_t buf_temp[MAX_STRUCT_SIZE];
3752    int target_size;
3753    void *argptr;
3754
3755    ie = ioctl_entries;
3756    for(;;) {
3757        if (ie->target_cmd == 0) {
3758            gemu_log("Unsupported ioctl: cmd=0x%04lx\n", (long)cmd);
3759            return -TARGET_ENOSYS;
3760        }
3761        if (ie->target_cmd == cmd)
3762            break;
3763        ie++;
3764    }
3765    arg_type = ie->arg_type;
3766#if defined(DEBUG)
3767    gemu_log("ioctl: cmd=0x%04lx (%s)\n", (long)cmd, ie->name);
3768#endif
3769    if (ie->do_ioctl) {
3770        return ie->do_ioctl(ie, buf_temp, fd, cmd, arg);
3771    }
3772
3773    switch(arg_type[0]) {
3774    case TYPE_NULL:
3775        /* no argument */
3776        ret = get_errno(ioctl(fd, ie->host_cmd));
3777        break;
3778    case TYPE_PTRVOID:
3779    case TYPE_INT:
3780        /* int argment */
3781        ret = get_errno(ioctl(fd, ie->host_cmd, arg));
3782        break;
3783    case TYPE_PTR:
3784        arg_type++;
3785        target_size = thunk_type_size(arg_type, 0);
3786        switch(ie->access) {
3787        case IOC_R:
3788            ret = get_errno(ioctl(fd, ie->host_cmd, buf_temp));
3789            if (!is_error(ret)) {
3790                argptr = lock_user(VERIFY_WRITE, arg, target_size, 0);
3791                if (!argptr)
3792                    return -TARGET_EFAULT;
3793                thunk_convert(argptr, buf_temp, arg_type, THUNK_TARGET);
3794                unlock_user(argptr, arg, target_size);
3795            }
3796            break;
3797        case IOC_W:
3798            argptr = lock_user(VERIFY_READ, arg, target_size, 1);
3799            if (!argptr)
3800                return -TARGET_EFAULT;
3801            thunk_convert(buf_temp, argptr, arg_type, THUNK_HOST);
3802            unlock_user(argptr, arg, 0);
3803            ret = get_errno(ioctl(fd, ie->host_cmd, buf_temp));
3804            break;
3805        default:
3806        case IOC_RW:
3807            argptr = lock_user(VERIFY_READ, arg, target_size, 1);
3808            if (!argptr)
3809                return -TARGET_EFAULT;
3810            thunk_convert(buf_temp, argptr, arg_type, THUNK_HOST);
3811            unlock_user(argptr, arg, 0);
3812            ret = get_errno(ioctl(fd, ie->host_cmd, buf_temp));
3813            if (!is_error(ret)) {
3814                argptr = lock_user(VERIFY_WRITE, arg, target_size, 0);
3815                if (!argptr)
3816                    return -TARGET_EFAULT;
3817                thunk_convert(argptr, buf_temp, arg_type, THUNK_TARGET);
3818                unlock_user(argptr, arg, target_size);
3819            }
3820            break;
3821        }
3822        break;
3823    default:
3824        gemu_log("Unsupported ioctl type: cmd=0x%04lx type=%d\n",
3825                 (long)cmd, arg_type[0]);
3826        ret = -TARGET_ENOSYS;
3827        break;
3828    }
3829    return ret;
3830}
3831
3832static const bitmask_transtbl iflag_tbl[] = {
3833        { TARGET_IGNBRK, TARGET_IGNBRK, IGNBRK, IGNBRK },
3834        { TARGET_BRKINT, TARGET_BRKINT, BRKINT, BRKINT },
3835        { TARGET_IGNPAR, TARGET_IGNPAR, IGNPAR, IGNPAR },
3836        { TARGET_PARMRK, TARGET_PARMRK, PARMRK, PARMRK },
3837        { TARGET_INPCK, TARGET_INPCK, INPCK, INPCK },
3838        { TARGET_ISTRIP, TARGET_ISTRIP, ISTRIP, ISTRIP },
3839        { TARGET_INLCR, TARGET_INLCR, INLCR, INLCR },
3840        { TARGET_IGNCR, TARGET_IGNCR, IGNCR, IGNCR },
3841        { TARGET_ICRNL, TARGET_ICRNL, ICRNL, ICRNL },
3842        { TARGET_IUCLC, TARGET_IUCLC, IUCLC, IUCLC },
3843        { TARGET_IXON, TARGET_IXON, IXON, IXON },
3844        { TARGET_IXANY, TARGET_IXANY, IXANY, IXANY },
3845        { TARGET_IXOFF, TARGET_IXOFF, IXOFF, IXOFF },
3846        { TARGET_IMAXBEL, TARGET_IMAXBEL, IMAXBEL, IMAXBEL },
3847        { 0, 0, 0, 0 }
3848};
3849
3850static const bitmask_transtbl oflag_tbl[] = {
3851        { TARGET_OPOST, TARGET_OPOST, OPOST, OPOST },
3852        { TARGET_OLCUC, TARGET_OLCUC, OLCUC, OLCUC },
3853        { TARGET_ONLCR, TARGET_ONLCR, ONLCR, ONLCR },
3854        { TARGET_OCRNL, TARGET_OCRNL, OCRNL, OCRNL },
3855        { TARGET_ONOCR, TARGET_ONOCR, ONOCR, ONOCR },
3856        { TARGET_ONLRET, TARGET_ONLRET, ONLRET, ONLRET },
3857        { TARGET_OFILL, TARGET_OFILL, OFILL, OFILL },
3858        { TARGET_OFDEL, TARGET_OFDEL, OFDEL, OFDEL },
3859        { TARGET_NLDLY, TARGET_NL0, NLDLY, NL0 },
3860        { TARGET_NLDLY, TARGET_NL1, NLDLY, NL1 },
3861        { TARGET_CRDLY, TARGET_CR0, CRDLY, CR0 },
3862        { TARGET_CRDLY, TARGET_CR1, CRDLY, CR1 },
3863        { TARGET_CRDLY, TARGET_CR2, CRDLY, CR2 },
3864        { TARGET_CRDLY, TARGET_CR3, CRDLY, CR3 },
3865        { TARGET_TABDLY, TARGET_TAB0, TABDLY, TAB0 },
3866        { TARGET_TABDLY, TARGET_TAB1, TABDLY, TAB1 },
3867        { TARGET_TABDLY, TARGET_TAB2, TABDLY, TAB2 },
3868        { TARGET_TABDLY, TARGET_TAB3, TABDLY, TAB3 },
3869        { TARGET_BSDLY, TARGET_BS0, BSDLY, BS0 },
3870        { TARGET_BSDLY, TARGET_BS1, BSDLY, BS1 },
3871        { TARGET_VTDLY, TARGET_VT0, VTDLY, VT0 },
3872        { TARGET_VTDLY, TARGET_VT1, VTDLY, VT1 },
3873        { TARGET_FFDLY, TARGET_FF0, FFDLY, FF0 },
3874        { TARGET_FFDLY, TARGET_FF1, FFDLY, FF1 },
3875        { 0, 0, 0, 0 }
3876};
3877
3878static const bitmask_transtbl cflag_tbl[] = {
3879        { TARGET_CBAUD, TARGET_B0, CBAUD, B0 },
3880        { TARGET_CBAUD, TARGET_B50, CBAUD, B50 },
3881        { TARGET_CBAUD, TARGET_B75, CBAUD, B75 },
3882        { TARGET_CBAUD, TARGET_B110, CBAUD, B110 },
3883        { TARGET_CBAUD, TARGET_B134, CBAUD, B134 },
3884        { TARGET_CBAUD, TARGET_B150, CBAUD, B150 },
3885        { TARGET_CBAUD, TARGET_B200, CBAUD, B200 },
3886        { TARGET_CBAUD, TARGET_B300, CBAUD, B300 },
3887        { TARGET_CBAUD, TARGET_B600, CBAUD, B600 },
3888        { TARGET_CBAUD, TARGET_B1200, CBAUD, B1200 },
3889        { TARGET_CBAUD, TARGET_B1800, CBAUD, B1800 },
3890        { TARGET_CBAUD, TARGET_B2400, CBAUD, B2400 },
3891        { TARGET_CBAUD, TARGET_B4800, CBAUD, B4800 },
3892        { TARGET_CBAUD, TARGET_B9600, CBAUD, B9600 },
3893        { TARGET_CBAUD, TARGET_B19200, CBAUD, B19200 },
3894        { TARGET_CBAUD, TARGET_B38400, CBAUD, B38400 },
3895        { TARGET_CBAUD, TARGET_B57600, CBAUD, B57600 },
3896        { TARGET_CBAUD, TARGET_B115200, CBAUD, B115200 },
3897        { TARGET_CBAUD, TARGET_B230400, CBAUD, B230400 },
3898        { TARGET_CBAUD, TARGET_B460800, CBAUD, B460800 },
3899        { TARGET_CSIZE, TARGET_CS5, CSIZE, CS5 },
3900        { TARGET_CSIZE, TARGET_CS6, CSIZE, CS6 },
3901        { TARGET_CSIZE, TARGET_CS7, CSIZE, CS7 },
3902        { TARGET_CSIZE, TARGET_CS8, CSIZE, CS8 },
3903        { TARGET_CSTOPB, TARGET_CSTOPB, CSTOPB, CSTOPB },
3904        { TARGET_CREAD, TARGET_CREAD, CREAD, CREAD },
3905        { TARGET_PARENB, TARGET_PARENB, PARENB, PARENB },
3906        { TARGET_PARODD, TARGET_PARODD, PARODD, PARODD },
3907        { TARGET_HUPCL, TARGET_HUPCL, HUPCL, HUPCL },
3908        { TARGET_CLOCAL, TARGET_CLOCAL, CLOCAL, CLOCAL },
3909        { TARGET_CRTSCTS, TARGET_CRTSCTS, CRTSCTS, CRTSCTS },
3910        { 0, 0, 0, 0 }
3911};
3912
3913static const bitmask_transtbl lflag_tbl[] = {
3914        { TARGET_ISIG, TARGET_ISIG, ISIG, ISIG },
3915        { TARGET_ICANON, TARGET_ICANON, ICANON, ICANON },
3916        { TARGET_XCASE, TARGET_XCASE, XCASE, XCASE },
3917        { TARGET_ECHO, TARGET_ECHO, ECHO, ECHO },
3918        { TARGET_ECHOE, TARGET_ECHOE, ECHOE, ECHOE },
3919        { TARGET_ECHOK, TARGET_ECHOK, ECHOK, ECHOK },
3920        { TARGET_ECHONL, TARGET_ECHONL, ECHONL, ECHONL },
3921        { TARGET_NOFLSH, TARGET_NOFLSH, NOFLSH, NOFLSH },
3922        { TARGET_TOSTOP, TARGET_TOSTOP, TOSTOP, TOSTOP },
3923        { TARGET_ECHOCTL, TARGET_ECHOCTL, ECHOCTL, ECHOCTL },
3924        { TARGET_ECHOPRT, TARGET_ECHOPRT, ECHOPRT, ECHOPRT },
3925        { TARGET_ECHOKE, TARGET_ECHOKE, ECHOKE, ECHOKE },
3926        { TARGET_FLUSHO, TARGET_FLUSHO, FLUSHO, FLUSHO },
3927        { TARGET_PENDIN, TARGET_PENDIN, PENDIN, PENDIN },
3928        { TARGET_IEXTEN, TARGET_IEXTEN, IEXTEN, IEXTEN },
3929        { 0, 0, 0, 0 }
3930};
3931
3932static void target_to_host_termios (void *dst, const void *src)
3933{
3934    struct host_termios *host = dst;
3935    const struct target_termios *target = src;
3936
3937    host->c_iflag =
3938        target_to_host_bitmask(tswap32(target->c_iflag), iflag_tbl);
3939    host->c_oflag =
3940        target_to_host_bitmask(tswap32(target->c_oflag), oflag_tbl);
3941    host->c_cflag =
3942        target_to_host_bitmask(tswap32(target->c_cflag), cflag_tbl);
3943    host->c_lflag =
3944        target_to_host_bitmask(tswap32(target->c_lflag), lflag_tbl);
3945    host->c_line = target->c_line;
3946
3947    memset(host->c_cc, 0, sizeof(host->c_cc));
3948    host->c_cc[VINTR] = target->c_cc[TARGET_VINTR];
3949    host->c_cc[VQUIT] = target->c_cc[TARGET_VQUIT];
3950    host->c_cc[VERASE] = target->c_cc[TARGET_VERASE];
3951    host->c_cc[VKILL] = target->c_cc[TARGET_VKILL];
3952    host->c_cc[VEOF] = target->c_cc[TARGET_VEOF];
3953    host->c_cc[VTIME] = target->c_cc[TARGET_VTIME];
3954    host->c_cc[VMIN] = target->c_cc[TARGET_VMIN];
3955    host->c_cc[VSWTC] = target->c_cc[TARGET_VSWTC];
3956    host->c_cc[VSTART] = target->c_cc[TARGET_VSTART];
3957    host->c_cc[VSTOP] = target->c_cc[TARGET_VSTOP];
3958    host->c_cc[VSUSP] = target->c_cc[TARGET_VSUSP];
3959    host->c_cc[VEOL] = target->c_cc[TARGET_VEOL];
3960    host->c_cc[VREPRINT] = target->c_cc[TARGET_VREPRINT];
3961    host->c_cc[VDISCARD] = target->c_cc[TARGET_VDISCARD];
3962    host->c_cc[VWERASE] = target->c_cc[TARGET_VWERASE];
3963    host->c_cc[VLNEXT] = target->c_cc[TARGET_VLNEXT];
3964    host->c_cc[VEOL2] = target->c_cc[TARGET_VEOL2];
3965}
3966
3967static void host_to_target_termios (void *dst, const void *src)
3968{
3969    struct target_termios *target = dst;
3970    const struct host_termios *host = src;
3971
3972    target->c_iflag =
3973        tswap32(host_to_target_bitmask(host->c_iflag, iflag_tbl));
3974    target->c_oflag =
3975        tswap32(host_to_target_bitmask(host->c_oflag, oflag_tbl));
3976    target->c_cflag =
3977        tswap32(host_to_target_bitmask(host->c_cflag, cflag_tbl));
3978    target->c_lflag =
3979        tswap32(host_to_target_bitmask(host->c_lflag, lflag_tbl));
3980    target->c_line = host->c_line;
3981
3982    memset(target->c_cc, 0, sizeof(target->c_cc));
3983    target->c_cc[TARGET_VINTR] = host->c_cc[VINTR];
3984    target->c_cc[TARGET_VQUIT] = host->c_cc[VQUIT];
3985    target->c_cc[TARGET_VERASE] = host->c_cc[VERASE];
3986    target->c_cc[TARGET_VKILL] = host->c_cc[VKILL];
3987    target->c_cc[TARGET_VEOF] = host->c_cc[VEOF];
3988    target->c_cc[TARGET_VTIME] = host->c_cc[VTIME];
3989    target->c_cc[TARGET_VMIN] = host->c_cc[VMIN];
3990    target->c_cc[TARGET_VSWTC] = host->c_cc[VSWTC];
3991    target->c_cc[TARGET_VSTART] = host->c_cc[VSTART];
3992    target->c_cc[TARGET_VSTOP] = host->c_cc[VSTOP];
3993    target->c_cc[TARGET_VSUSP] = host->c_cc[VSUSP];
3994    target->c_cc[TARGET_VEOL] = host->c_cc[VEOL];
3995    target->c_cc[TARGET_VREPRINT] = host->c_cc[VREPRINT];
3996    target->c_cc[TARGET_VDISCARD] = host->c_cc[VDISCARD];
3997    target->c_cc[TARGET_VWERASE] = host->c_cc[VWERASE];
3998    target->c_cc[TARGET_VLNEXT] = host->c_cc[VLNEXT];
3999    target->c_cc[TARGET_VEOL2] = host->c_cc[VEOL2];
4000}
4001
4002static const StructEntry struct_termios_def = {
4003    .convert = { host_to_target_termios, target_to_host_termios },
4004    .size = { sizeof(struct target_termios), sizeof(struct host_termios) },
4005    .align = { __alignof__(struct target_termios), __alignof__(struct host_termios) },
4006};
4007
4008static bitmask_transtbl mmap_flags_tbl[] = {
4009        { TARGET_MAP_SHARED, TARGET_MAP_SHARED, MAP_SHARED, MAP_SHARED },
4010        { TARGET_MAP_PRIVATE, TARGET_MAP_PRIVATE, MAP_PRIVATE, MAP_PRIVATE },
4011        { TARGET_MAP_FIXED, TARGET_MAP_FIXED, MAP_FIXED, MAP_FIXED },
4012        { TARGET_MAP_ANONYMOUS, TARGET_MAP_ANONYMOUS, MAP_ANONYMOUS, MAP_ANONYMOUS },
4013        { TARGET_MAP_GROWSDOWN, TARGET_MAP_GROWSDOWN, MAP_GROWSDOWN, MAP_GROWSDOWN },
4014        { TARGET_MAP_DENYWRITE, TARGET_MAP_DENYWRITE, MAP_DENYWRITE, MAP_DENYWRITE },
4015        { TARGET_MAP_EXECUTABLE, TARGET_MAP_EXECUTABLE, MAP_EXECUTABLE, MAP_EXECUTABLE },
4016        { TARGET_MAP_LOCKED, TARGET_MAP_LOCKED, MAP_LOCKED, MAP_LOCKED },
4017        { 0, 0, 0, 0 }
4018};
4019
4020#if defined(TARGET_I386)
4021
4022/* NOTE: there is really one LDT for all the threads */
4023static uint8_t *ldt_table;
4024
4025static abi_long read_ldt(abi_ulong ptr, unsigned long bytecount)
4026{
4027    int size;
4028    void *p;
4029
4030    if (!ldt_table)
4031        return 0;
4032    size = TARGET_LDT_ENTRIES * TARGET_LDT_ENTRY_SIZE;
4033    if (size > bytecount)
4034        size = bytecount;
4035    p = lock_user(VERIFY_WRITE, ptr, size, 0);
4036    if (!p)
4037        return -TARGET_EFAULT;
4038    /* ??? Should this by byteswapped?  */
4039    memcpy(p, ldt_table, size);
4040    unlock_user(p, ptr, size);
4041    return size;
4042}
4043
4044/* XXX: add locking support */
4045static abi_long write_ldt(CPUX86State *env,
4046                          abi_ulong ptr, unsigned long bytecount, int oldmode)
4047{
4048    struct target_modify_ldt_ldt_s ldt_info;
4049    struct target_modify_ldt_ldt_s *target_ldt_info;
4050    int seg_32bit, contents, read_exec_only, limit_in_pages;
4051    int seg_not_present, useable, lm;
4052    uint32_t *lp, entry_1, entry_2;
4053
4054    if (bytecount != sizeof(ldt_info))
4055        return -TARGET_EINVAL;
4056    if (!lock_user_struct(VERIFY_READ, target_ldt_info, ptr, 1))
4057        return -TARGET_EFAULT;
4058    ldt_info.entry_number = tswap32(target_ldt_info->entry_number);
4059    ldt_info.base_addr = tswapal(target_ldt_info->base_addr);
4060    ldt_info.limit = tswap32(target_ldt_info->limit);
4061    ldt_info.flags = tswap32(target_ldt_info->flags);
4062    unlock_user_struct(target_ldt_info, ptr, 0);
4063
4064    if (ldt_info.entry_number >= TARGET_LDT_ENTRIES)
4065        return -TARGET_EINVAL;
4066    seg_32bit = ldt_info.flags & 1;
4067    contents = (ldt_info.flags >> 1) & 3;
4068    read_exec_only = (ldt_info.flags >> 3) & 1;
4069    limit_in_pages = (ldt_info.flags >> 4) & 1;
4070    seg_not_present = (ldt_info.flags >> 5) & 1;
4071    useable = (ldt_info.flags >> 6) & 1;
4072#ifdef TARGET_ABI32
4073    lm = 0;
4074#else
4075    lm = (ldt_info.flags >> 7) & 1;
4076#endif
4077    if (contents == 3) {
4078        if (oldmode)
4079            return -TARGET_EINVAL;
4080        if (seg_not_present == 0)
4081            return -TARGET_EINVAL;
4082    }
4083    /* allocate the LDT */
4084    if (!ldt_table) {
4085        env->ldt.base = target_mmap(0,
4086                                    TARGET_LDT_ENTRIES * TARGET_LDT_ENTRY_SIZE,
4087                                    PROT_READ|PROT_WRITE,
4088                                    MAP_ANONYMOUS|MAP_PRIVATE, -1, 0);
4089        if (env->ldt.base == -1)
4090            return -TARGET_ENOMEM;
4091        memset(g2h(env->ldt.base), 0,
4092               TARGET_LDT_ENTRIES * TARGET_LDT_ENTRY_SIZE);
4093        env->ldt.limit = 0xffff;
4094        ldt_table = g2h(env->ldt.base);
4095    }
4096
4097    /* NOTE: same code as Linux kernel */
4098    /* Allow LDTs to be cleared by the user. */
4099    if (ldt_info.base_addr == 0 && ldt_info.limit == 0) {
4100        if (oldmode ||
4101            (contents == 0              &&
4102             read_exec_only == 1        &&
4103             seg_32bit == 0             &&
4104             limit_in_pages == 0        &&
4105             seg_not_present == 1       &&
4106             useable == 0 )) {
4107            entry_1 = 0;
4108            entry_2 = 0;
4109            goto install;
4110        }
4111    }
4112
4113    entry_1 = ((ldt_info.base_addr & 0x0000ffff) << 16) |
4114        (ldt_info.limit & 0x0ffff);
4115    entry_2 = (ldt_info.base_addr & 0xff000000) |
4116        ((ldt_info.base_addr & 0x00ff0000) >> 16) |
4117        (ldt_info.limit & 0xf0000) |
4118        ((read_exec_only ^ 1) << 9) |
4119        (contents << 10) |
4120        ((seg_not_present ^ 1) << 15) |
4121        (seg_32bit << 22) |
4122        (limit_in_pages << 23) |
4123        (lm << 21) |
4124        0x7000;
4125    if (!oldmode)
4126        entry_2 |= (useable << 20);
4127
4128    /* Install the new entry ...  */
4129install:
4130    lp = (uint32_t *)(ldt_table + (ldt_info.entry_number << 3));
4131    lp[0] = tswap32(entry_1);
4132    lp[1] = tswap32(entry_2);
4133    return 0;
4134}
4135
4136/* specific and weird i386 syscalls */
4137static abi_long do_modify_ldt(CPUX86State *env, int func, abi_ulong ptr,
4138                              unsigned long bytecount)
4139{
4140    abi_long ret;
4141
4142    switch (func) {
4143    case 0:
4144        ret = read_ldt(ptr, bytecount);
4145        break;
4146    case 1:
4147        ret = write_ldt(env, ptr, bytecount, 1);
4148        break;
4149    case 0x11:
4150        ret = write_ldt(env, ptr, bytecount, 0);
4151        break;
4152    default:
4153        ret = -TARGET_ENOSYS;
4154        break;
4155    }
4156    return ret;
4157}
4158
4159#if defined(TARGET_I386) && defined(TARGET_ABI32)
4160abi_long do_set_thread_area(CPUX86State *env, abi_ulong ptr)
4161{
4162    uint64_t *gdt_table = g2h(env->gdt.base);
4163    struct target_modify_ldt_ldt_s ldt_info;
4164    struct target_modify_ldt_ldt_s *target_ldt_info;
4165    int seg_32bit, contents, read_exec_only, limit_in_pages;
4166    int seg_not_present, useable, lm;
4167    uint32_t *lp, entry_1, entry_2;
4168    int i;
4169
4170    lock_user_struct(VERIFY_WRITE, target_ldt_info, ptr, 1);
4171    if (!target_ldt_info)
4172        return -TARGET_EFAULT;
4173    ldt_info.entry_number = tswap32(target_ldt_info->entry_number);
4174    ldt_info.base_addr = tswapal(target_ldt_info->base_addr);
4175    ldt_info.limit = tswap32(target_ldt_info->limit);
4176    ldt_info.flags = tswap32(target_ldt_info->flags);
4177    if (ldt_info.entry_number == -1) {
4178        for (i=TARGET_GDT_ENTRY_TLS_MIN; i<=TARGET_GDT_ENTRY_TLS_MAX; i++) {
4179            if (gdt_table[i] == 0) {
4180                ldt_info.entry_number = i;
4181                target_ldt_info->entry_number = tswap32(i);
4182                break;
4183            }
4184        }
4185    }
4186    unlock_user_struct(target_ldt_info, ptr, 1);
4187
4188    if (ldt_info.entry_number < TARGET_GDT_ENTRY_TLS_MIN || 
4189        ldt_info.entry_number > TARGET_GDT_ENTRY_TLS_MAX)
4190           return -TARGET_EINVAL;
4191    seg_32bit = ldt_info.flags & 1;
4192    contents = (ldt_info.flags >> 1) & 3;
4193    read_exec_only = (ldt_info.flags >> 3) & 1;
4194    limit_in_pages = (ldt_info.flags >> 4) & 1;
4195    seg_not_present = (ldt_info.flags >> 5) & 1;
4196    useable = (ldt_info.flags >> 6) & 1;
4197#ifdef TARGET_ABI32
4198    lm = 0;
4199#else
4200    lm = (ldt_info.flags >> 7) & 1;
4201#endif
4202
4203    if (contents == 3) {
4204        if (seg_not_present == 0)
4205            return -TARGET_EINVAL;
4206    }
4207
4208    /* NOTE: same code as Linux kernel */
4209    /* Allow LDTs to be cleared by the user. */
4210    if (ldt_info.base_addr == 0 && ldt_info.limit == 0) {
4211        if ((contents == 0             &&
4212             read_exec_only == 1       &&
4213             seg_32bit == 0            &&
4214             limit_in_pages == 0       &&
4215             seg_not_present == 1      &&
4216             useable == 0 )) {
4217            entry_1 = 0;
4218            entry_2 = 0;
4219            goto install;
4220        }
4221    }
4222
4223    entry_1 = ((ldt_info.base_addr & 0x0000ffff) << 16) |
4224        (ldt_info.limit & 0x0ffff);
4225    entry_2 = (ldt_info.base_addr & 0xff000000) |
4226        ((ldt_info.base_addr & 0x00ff0000) >> 16) |
4227        (ldt_info.limit & 0xf0000) |
4228        ((read_exec_only ^ 1) << 9) |
4229        (contents << 10) |
4230        ((seg_not_present ^ 1) << 15) |
4231        (seg_32bit << 22) |
4232        (limit_in_pages << 23) |
4233        (useable << 20) |
4234        (lm << 21) |
4235        0x7000;
4236
4237    /* Install the new entry ...  */
4238install:
4239    lp = (uint32_t *)(gdt_table + ldt_info.entry_number);
4240    lp[0] = tswap32(entry_1);
4241    lp[1] = tswap32(entry_2);
4242    return 0;
4243}
4244
4245static abi_long do_get_thread_area(CPUX86State *env, abi_ulong ptr)
4246{
4247    struct target_modify_ldt_ldt_s *target_ldt_info;
4248    uint64_t *gdt_table = g2h(env->gdt.base);
4249    uint32_t base_addr, limit, flags;
4250    int seg_32bit, contents, read_exec_only, limit_in_pages, idx;
4251    int seg_not_present, useable, lm;
4252    uint32_t *lp, entry_1, entry_2;
4253
4254    lock_user_struct(VERIFY_WRITE, target_ldt_info, ptr, 1);
4255    if (!target_ldt_info)
4256        return -TARGET_EFAULT;
4257    idx = tswap32(target_ldt_info->entry_number);
4258    if (idx < TARGET_GDT_ENTRY_TLS_MIN ||
4259        idx > TARGET_GDT_ENTRY_TLS_MAX) {
4260        unlock_user_struct(target_ldt_info, ptr, 1);
4261        return -TARGET_EINVAL;
4262    }
4263    lp = (uint32_t *)(gdt_table + idx);
4264    entry_1 = tswap32(lp[0]);
4265    entry_2 = tswap32(lp[1]);
4266    
4267    read_exec_only = ((entry_2 >> 9) & 1) ^ 1;
4268    contents = (entry_2 >> 10) & 3;
4269    seg_not_present = ((entry_2 >> 15) & 1) ^ 1;
4270    seg_32bit = (entry_2 >> 22) & 1;
4271    limit_in_pages = (entry_2 >> 23) & 1;
4272    useable = (entry_2 >> 20) & 1;
4273#ifdef TARGET_ABI32
4274    lm = 0;
4275#else
4276    lm = (entry_2 >> 21) & 1;
4277#endif
4278    flags = (seg_32bit << 0) | (contents << 1) |
4279        (read_exec_only << 3) | (limit_in_pages << 4) |
4280        (seg_not_present << 5) | (useable << 6) | (lm << 7);
4281    limit = (entry_1 & 0xffff) | (entry_2  & 0xf0000);
4282    base_addr = (entry_1 >> 16) | 
4283        (entry_2 & 0xff000000) | 
4284        ((entry_2 & 0xff) << 16);
4285    target_ldt_info->base_addr = tswapal(base_addr);
4286    target_ldt_info->limit = tswap32(limit);
4287    target_ldt_info->flags = tswap32(flags);
4288    unlock_user_struct(target_ldt_info, ptr, 1);
4289    return 0;
4290}
4291#endif /* TARGET_I386 && TARGET_ABI32 */
4292
4293#ifndef TARGET_ABI32
4294abi_long do_arch_prctl(CPUX86State *env, int code, abi_ulong addr)
4295{
4296    abi_long ret = 0;
4297    abi_ulong val;
4298    int idx;
4299
4300    switch(code) {
4301    case TARGET_ARCH_SET_GS:
4302    case TARGET_ARCH_SET_FS:
4303        if (code == TARGET_ARCH_SET_GS)
4304            idx = R_GS;
4305        else
4306            idx = R_FS;
4307        cpu_x86_load_seg(env, idx, 0);
4308        env->segs[idx].base = addr;
4309        break;
4310    case TARGET_ARCH_GET_GS:
4311    case TARGET_ARCH_GET_FS:
4312        if (code == TARGET_ARCH_GET_GS)
4313            idx = R_GS;
4314        else
4315            idx = R_FS;
4316        val = env->segs[idx].base;
4317        if (put_user(val, addr, abi_ulong))
4318            ret = -TARGET_EFAULT;
4319        break;
4320    default:
4321        ret = -TARGET_EINVAL;
4322        break;
4323    }
4324    return ret;
4325}
4326#endif
4327
4328#endif /* defined(TARGET_I386) */
4329
4330#define NEW_STACK_SIZE 0x40000
4331
4332
4333static pthread_mutex_t clone_lock = PTHREAD_MUTEX_INITIALIZER;
4334typedef struct {
4335    CPUArchState *env;
4336    pthread_mutex_t mutex;
4337    pthread_cond_t cond;
4338    pthread_t thread;
4339    uint32_t tid;
4340    abi_ulong child_tidptr;
4341    abi_ulong parent_tidptr;
4342    sigset_t sigmask;
4343} new_thread_info;
4344
4345static void *clone_func(void *arg)
4346{
4347    new_thread_info *info = arg;
4348    CPUArchState *env;
4349    CPUState *cpu;
4350    TaskState *ts;
4351
4352    env = info->env;
4353    cpu = ENV_GET_CPU(env);
4354    thread_cpu = cpu;
4355    ts = (TaskState *)env->opaque;
4356    info->tid = gettid();
4357    cpu->host_tid = info->tid;
4358    task_settid(ts);
4359    if (info->child_tidptr)
4360        put_user_u32(info->tid, info->child_tidptr);
4361    if (info->parent_tidptr)
4362        put_user_u32(info->tid, info->parent_tidptr);
4363    /* Enable signals.  */
4364    sigprocmask(SIG_SETMASK, &info->sigmask, NULL);
4365    /* Signal to the parent that we're ready.  */
4366    pthread_mutex_lock(&info->mutex);
4367    pthread_cond_broadcast(&info->cond);
4368    pthread_mutex_unlock(&info->mutex);
4369    /* Wait until the parent has finshed initializing the tls state.  */
4370    pthread_mutex_lock(&clone_lock);
4371    pthread_mutex_unlock(&clone_lock);
4372    cpu_loop(env);
4373    /* never exits */
4374    return NULL;
4375}
4376
4377/* do_fork() Must return host values and target errnos (unlike most
4378   do_*() functions). */
4379static int do_fork(CPUArchState *env, unsigned int flags, abi_ulong newsp,
4380                   abi_ulong parent_tidptr, target_ulong newtls,
4381                   abi_ulong child_tidptr)
4382{
4383    int ret;
4384    TaskState *ts;
4385    CPUArchState *new_env;
4386    unsigned int nptl_flags;
4387    sigset_t sigmask;
4388
4389    /* Emulate vfork() with fork() */
4390    if (flags & CLONE_VFORK)
4391        flags &= ~(CLONE_VFORK | CLONE_VM);
4392
4393    if (flags & CLONE_VM) {
4394        TaskState *parent_ts = (TaskState *)env->opaque;
4395        new_thread_info info;
4396        pthread_attr_t attr;
4397
4398        ts = g_malloc0(sizeof(TaskState));
4399        init_task_state(ts);
4400        /* we create a new CPU instance. */
4401        new_env = cpu_copy(env);
4402        /* Init regs that differ from the parent.  */
4403        cpu_clone_regs(new_env, newsp);
4404        new_env->opaque = ts;
4405        ts->bprm = parent_ts->bprm;
4406        ts->info = parent_ts->info;
4407        nptl_flags = flags;
4408        flags &= ~CLONE_NPTL_FLAGS2;
4409
4410        if (nptl_flags & CLONE_CHILD_CLEARTID) {
4411            ts->child_tidptr = child_tidptr;
4412        }
4413
4414        if (nptl_flags & CLONE_SETTLS)
4415            cpu_set_tls (new_env, newtls);
4416
4417        /* Grab a mutex so that thread setup appears atomic.  */
4418        pthread_mutex_lock(&clone_lock);
4419
4420        memset(&info, 0, sizeof(info));
4421        pthread_mutex_init(&info.mutex, NULL);
4422        pthread_mutex_lock(&info.mutex);
4423        pthread_cond_init(&info.cond, NULL);
4424        info.env = new_env;
4425        if (nptl_flags & CLONE_CHILD_SETTID)
4426            info.child_tidptr = child_tidptr;
4427        if (nptl_flags & CLONE_PARENT_SETTID)
4428            info.parent_tidptr = parent_tidptr;
4429
4430        ret = pthread_attr_init(&attr);
4431        ret = pthread_attr_setstacksize(&attr, NEW_STACK_SIZE);
4432        ret = pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED);
4433        /* It is not safe to deliver signals until the child has finished
4434           initializing, so temporarily block all signals.  */
4435        sigfillset(&sigmask);
4436        sigprocmask(SIG_BLOCK, &sigmask, &info.sigmask);
4437
4438        ret = pthread_create(&info.thread, &attr, clone_func, &info);
4439        /* TODO: Free new CPU state if thread creation failed.  */
4440
4441        sigprocmask(SIG_SETMASK, &info.sigmask, NULL);
4442        pthread_attr_destroy(&attr);
4443        if (ret == 0) {
4444            /* Wait for the child to initialize.  */
4445            pthread_cond_wait(&info.cond, &info.mutex);
4446            ret = info.tid;
4447            if (flags & CLONE_PARENT_SETTID)
4448                put_user_u32(ret, parent_tidptr);
4449        } else {
4450            ret = -1;
4451        }
4452        pthread_mutex_unlock(&info.mutex);
4453        pthread_cond_destroy(&info.cond);
4454        pthread_mutex_destroy(&info.mutex);
4455        pthread_mutex_unlock(&clone_lock);
4456    } else {
4457        /* if no CLONE_VM, we consider it is a fork */
4458        if ((flags & ~(CSIGNAL | CLONE_NPTL_FLAGS2)) != 0)
4459            return -EINVAL;
4460        fork_start();
4461        ret = fork();
4462        if (ret == 0) {
4463            /* Child Process.  */
4464            cpu_clone_regs(env, newsp);
4465            fork_end(1);
4466            /* There is a race condition here.  The parent process could
4467               theoretically read the TID in the child process before the child
4468               tid is set.  This would require using either ptrace
4469               (not implemented) or having *_tidptr to point at a shared memory
4470               mapping.  We can't repeat the spinlock hack used above because
4471               the child process gets its own copy of the lock.  */
4472            if (flags & CLONE_CHILD_SETTID)
4473                put_user_u32(gettid(), child_tidptr);
4474            if (flags & CLONE_PARENT_SETTID)
4475                put_user_u32(gettid(), parent_tidptr);
4476            ts = (TaskState *)env->opaque;
4477            if (flags & CLONE_SETTLS)
4478                cpu_set_tls (env, newtls);
4479            if (flags & CLONE_CHILD_CLEARTID)
4480                ts->child_tidptr = child_tidptr;
4481        } else {
4482            fork_end(0);
4483        }
4484    }
4485    return ret;
4486}
4487
4488/* warning : doesn't handle linux specific flags... */
4489static int target_to_host_fcntl_cmd(int cmd)
4490{
4491    switch(cmd) {
4492        case TARGET_F_DUPFD:
4493        case TARGET_F_GETFD:
4494        case TARGET_F_SETFD:
4495        case TARGET_F_GETFL:
4496        case TARGET_F_SETFL:
4497            return cmd;
4498        case TARGET_F_GETLK:
4499            return F_GETLK;
4500        case TARGET_F_SETLK:
4501            return F_SETLK;
4502        case TARGET_F_SETLKW:
4503            return F_SETLKW;
4504        case TARGET_F_GETOWN:
4505            return F_GETOWN;
4506        case TARGET_F_SETOWN:
4507            return F_SETOWN;
4508        case TARGET_F_GETSIG:
4509            return F_GETSIG;
4510        case TARGET_F_SETSIG:
4511            return F_SETSIG;
4512#if TARGET_ABI_BITS == 32
4513        case TARGET_F_GETLK64:
4514            return F_GETLK64;
4515        case TARGET_F_SETLK64:
4516            return F_SETLK64;
4517        case TARGET_F_SETLKW64:
4518            return F_SETLKW64;
4519#endif
4520        case TARGET_F_SETLEASE:
4521            return F_SETLEASE;
4522        case TARGET_F_GETLEASE:
4523            return F_GETLEASE;
4524#ifdef F_DUPFD_CLOEXEC
4525        case TARGET_F_DUPFD_CLOEXEC:
4526            return F_DUPFD_CLOEXEC;
4527#endif
4528        case TARGET_F_NOTIFY:
4529            return F_NOTIFY;
4530        default:
4531            return -TARGET_EINVAL;
4532    }
4533    return -TARGET_EINVAL;
4534}
4535
4536#define TRANSTBL_CONVERT(a) { -1, TARGET_##a, -1, a }
4537static const bitmask_transtbl flock_tbl[] = {
4538    TRANSTBL_CONVERT(F_RDLCK),
4539    TRANSTBL_CONVERT(F_WRLCK),
4540    TRANSTBL_CONVERT(F_UNLCK),
4541    TRANSTBL_CONVERT(F_EXLCK),
4542    TRANSTBL_CONVERT(F_SHLCK),
4543    { 0, 0, 0, 0 }
4544};
4545
4546static abi_long do_fcntl(int fd, int cmd, abi_ulong arg)
4547{
4548    struct flock fl;
4549    struct target_flock *target_fl;
4550    struct flock64 fl64;
4551    struct target_flock64 *target_fl64;
4552    abi_long ret;
4553    int host_cmd = target_to_host_fcntl_cmd(cmd);
4554
4555    if (host_cmd == -TARGET_EINVAL)
4556            return host_cmd;
4557
4558    switch(cmd) {
4559    case TARGET_F_GETLK:
4560        if (!lock_user_struct(VERIFY_READ, target_fl, arg, 1))
4561            return -TARGET_EFAULT;
4562        fl.l_type =
4563                  target_to_host_bitmask(tswap16(target_fl->l_type), flock_tbl);
4564        fl.l_whence = tswap16(target_fl->l_whence);
4565        fl.l_start = tswapal(target_fl->l_start);
4566        fl.l_len = tswapal(target_fl->l_len);
4567        fl.l_pid = tswap32(target_fl->l_pid);
4568        unlock_user_struct(target_fl, arg, 0);
4569        ret = get_errno(fcntl(fd, host_cmd, &fl));
4570        if (ret == 0) {
4571            if (!lock_user_struct(VERIFY_WRITE, target_fl, arg, 0))
4572                return -TARGET_EFAULT;
4573            target_fl->l_type =
4574                          host_to_target_bitmask(tswap16(fl.l_type), flock_tbl);
4575            target_fl->l_whence = tswap16(fl.l_whence);
4576            target_fl->l_start = tswapal(fl.l_start);
4577            target_fl->l_len = tswapal(fl.l_len);
4578            target_fl->l_pid = tswap32(fl.l_pid);
4579            unlock_user_struct(target_fl, arg, 1);
4580        }
4581        break;
4582
4583    case TARGET_F_SETLK:
4584    case TARGET_F_SETLKW:
4585        if (!lock_user_struct(VERIFY_READ, target_fl, arg, 1))
4586            return -TARGET_EFAULT;
4587        fl.l_type =
4588                  target_to_host_bitmask(tswap16(target_fl->l_type), flock_tbl);
4589        fl.l_whence = tswap16(target_fl->l_whence);
4590        fl.l_start = tswapal(target_fl->l_start);
4591        fl.l_len = tswapal(target_fl->l_len);
4592        fl.l_pid = tswap32(target_fl->l_pid);
4593        unlock_user_struct(target_fl, arg, 0);
4594        ret = get_errno(fcntl(fd, host_cmd, &fl));
4595        break;
4596
4597    case TARGET_F_GETLK64:
4598        if (!lock_user_struct(VERIFY_READ, target_fl64, arg, 1))
4599            return -TARGET_EFAULT;
4600        fl64.l_type =
4601           target_to_host_bitmask(tswap16(target_fl64->l_type), flock_tbl) >> 1;
4602        fl64.l_whence = tswap16(target_fl64->l_whence);
4603        fl64.l_start = tswap64(target_fl64->l_start);
4604        fl64.l_len = tswap64(target_fl64->l_len);
4605        fl64.l_pid = tswap32(target_fl64->l_pid);
4606        unlock_user_struct(target_fl64, arg, 0);
4607        ret = get_errno(fcntl(fd, host_cmd, &fl64));
4608        if (ret == 0) {
4609            if (!lock_user_struct(VERIFY_WRITE, target_fl64, arg, 0))
4610                return -TARGET_EFAULT;
4611            target_fl64->l_type =
4612                   host_to_target_bitmask(tswap16(fl64.l_type), flock_tbl) >> 1;
4613            target_fl64->l_whence = tswap16(fl64.l_whence);
4614            target_fl64->l_start = tswap64(fl64.l_start);
4615            target_fl64->l_len = tswap64(fl64.l_len);
4616            target_fl64->l_pid = tswap32(fl64.l_pid);
4617            unlock_user_struct(target_fl64, arg, 1);
4618        }
4619        break;
4620    case TARGET_F_SETLK64:
4621    case TARGET_F_SETLKW64:
4622        if (!lock_user_struct(VERIFY_READ, target_fl64, arg, 1))
4623            return -TARGET_EFAULT;
4624        fl64.l_type =
4625           target_to_host_bitmask(tswap16(target_fl64->l_type), flock_tbl) >> 1;
4626        fl64.l_whence = tswap16(target_fl64->l_whence);
4627        fl64.l_start = tswap64(target_fl64->l_start);
4628        fl64.l_len = tswap64(target_fl64->l_len);
4629        fl64.l_pid = tswap32(target_fl64->l_pid);
4630        unlock_user_struct(target_fl64, arg, 0);
4631        ret = get_errno(fcntl(fd, host_cmd, &fl64));
4632        break;
4633
4634    case TARGET_F_GETFL:
4635        ret = get_errno(fcntl(fd, host_cmd, arg));
4636        if (ret >= 0) {
4637            ret = host_to_target_bitmask(ret, fcntl_flags_tbl);
4638        }
4639        break;
4640
4641    case TARGET_F_SETFL:
4642        ret = get_errno(fcntl(fd, host_cmd, target_to_host_bitmask(arg, fcntl_flags_tbl)));
4643        break;
4644
4645    case TARGET_F_SETOWN:
4646    case TARGET_F_GETOWN:
4647    case TARGET_F_SETSIG:
4648    case TARGET_F_GETSIG:
4649    case TARGET_F_SETLEASE:
4650    case TARGET_F_GETLEASE:
4651        ret = get_errno(fcntl(fd, host_cmd, arg));
4652        break;
4653
4654    default:
4655        ret = get_errno(fcntl(fd, cmd, arg));
4656        break;
4657    }
4658    return ret;
4659}
4660
4661#ifdef USE_UID16
4662
4663static inline int high2lowuid(int uid)
4664{
4665    if (uid > 65535)
4666        return 65534;
4667    else
4668        return uid;
4669}
4670
4671static inline int high2lowgid(int gid)
4672{
4673    if (gid > 65535)
4674        return 65534;
4675    else
4676        return gid;
4677}
4678
4679static inline int low2highuid(int uid)
4680{
4681    if ((int16_t)uid == -1)
4682        return -1;
4683    else
4684        return uid;
4685}
4686
4687static inline int low2highgid(int gid)
4688{
4689    if ((int16_t)gid == -1)
4690        return -1;
4691    else
4692        return gid;
4693}
4694static inline int tswapid(int id)
4695{
4696    return tswap16(id);
4697}
4698#else /* !USE_UID16 */
4699static inline int high2lowuid(int uid)
4700{
4701    return uid;
4702}
4703static inline int high2lowgid(int gid)
4704{
4705    return gid;
4706}
4707static inline int low2highuid(int uid)
4708{
4709    return uid;
4710}
4711static inline int low2highgid(int gid)
4712{
4713    return gid;
4714}
4715static inline int tswapid(int id)
4716{
4717    return tswap32(id);
4718}
4719#endif /* USE_UID16 */
4720
4721void syscall_init(void)
4722{
4723    IOCTLEntry *ie;
4724    const argtype *arg_type;
4725    int size;
4726    int i;
4727
4728#define STRUCT(name, ...) thunk_register_struct(STRUCT_ ## name, #name, struct_ ## name ## _def);
4729#define STRUCT_SPECIAL(name) thunk_register_struct_direct(STRUCT_ ## name, #name, &struct_ ## name ## _def);
4730#include "syscall_types.h"
4731#undef STRUCT
4732#undef STRUCT_SPECIAL
4733
4734    /* Build target_to_host_errno_table[] table from
4735     * host_to_target_errno_table[]. */
4736    for (i = 0; i < ERRNO_TABLE_SIZE; i++) {
4737        target_to_host_errno_table[host_to_target_errno_table[i]] = i;
4738    }
4739
4740    /* we patch the ioctl size if necessary. We rely on the fact that
4741       no ioctl has all the bits at '1' in the size field */
4742    ie = ioctl_entries;
4743    while (ie->target_cmd != 0) {
4744        if (((ie->target_cmd >> TARGET_IOC_SIZESHIFT) & TARGET_IOC_SIZEMASK) ==
4745            TARGET_IOC_SIZEMASK) {
4746            arg_type = ie->arg_type;
4747            if (arg_type[0] != TYPE_PTR) {
4748                fprintf(stderr, "cannot patch size for ioctl 0x%x\n",
4749                        ie->target_cmd);
4750                exit(1);
4751            }
4752            arg_type++;
4753            size = thunk_type_size(arg_type, 0);
4754            ie->target_cmd = (ie->target_cmd &
4755                              ~(TARGET_IOC_SIZEMASK << TARGET_IOC_SIZESHIFT)) |
4756                (size << TARGET_IOC_SIZESHIFT);
4757        }
4758
4759        /* automatic consistency check if same arch */
4760#if (defined(__i386__) && defined(TARGET_I386) && defined(TARGET_ABI32)) || \
4761    (defined(__x86_64__) && defined(TARGET_X86_64))
4762        if (unlikely(ie->target_cmd != ie->host_cmd)) {
4763            fprintf(stderr, "ERROR: ioctl(%s): target=0x%x host=0x%x\n",
4764                    ie->name, ie->target_cmd, ie->host_cmd);
4765        }
4766#endif
4767        ie++;
4768    }
4769}
4770
4771#if TARGET_ABI_BITS == 32
4772static inline uint64_t target_offset64(uint32_t word0, uint32_t word1)
4773{
4774#ifdef TARGET_WORDS_BIGENDIAN
4775    return ((uint64_t)word0 << 32) | word1;
4776#else
4777    return ((uint64_t)word1 << 32) | word0;
4778#endif
4779}
4780#else /* TARGET_ABI_BITS == 32 */
4781static inline uint64_t target_offset64(uint64_t word0, uint64_t word1)
4782{
4783    return word0;
4784}
4785#endif /* TARGET_ABI_BITS != 32 */
4786
4787#ifdef TARGET_NR_truncate64
4788static inline abi_long target_truncate64(void *cpu_env, const char *arg1,
4789                                         abi_long arg2,
4790                                         abi_long arg3,
4791                                         abi_long arg4)
4792{
4793    if (regpairs_aligned(cpu_env)) {
4794        arg2 = arg3;
4795        arg3 = arg4;
4796    }
4797    return get_errno(truncate64(arg1, target_offset64(arg2, arg3)));
4798}
4799#endif
4800
4801#ifdef TARGET_NR_ftruncate64
4802static inline abi_long target_ftruncate64(void *cpu_env, abi_long arg1,
4803                                          abi_long arg2,
4804                                          abi_long arg3,
4805                                          abi_long arg4)
4806{
4807    if (regpairs_aligned(cpu_env)) {
4808        arg2 = arg3;
4809        arg3 = arg4;
4810    }
4811    return get_errno(ftruncate64(arg1, target_offset64(arg2, arg3)));
4812}
4813#endif
4814
4815static inline abi_long target_to_host_timespec(struct timespec *host_ts,
4816                                               abi_ulong target_addr)
4817{
4818    struct target_timespec *target_ts;
4819
4820    if (!lock_user_struct(VERIFY_READ, target_ts, target_addr, 1))
4821        return -TARGET_EFAULT;
4822    host_ts->tv_sec = tswapal(target_ts->tv_sec);
4823    host_ts->tv_nsec = tswapal(target_ts->tv_nsec);
4824    unlock_user_struct(target_ts, target_addr, 0);
4825    return 0;
4826}
4827
4828static inline abi_long host_to_target_timespec(abi_ulong target_addr,
4829                                               struct timespec *host_ts)
4830{
4831    struct target_timespec *target_ts;
4832
4833    if (!lock_user_struct(VERIFY_WRITE, target_ts, target_addr, 0))
4834        return -TARGET_EFAULT;
4835    target_ts->tv_sec = tswapal(host_ts->tv_sec);
4836    target_ts->tv_nsec = tswapal(host_ts->tv_nsec);
4837    unlock_user_struct(target_ts, target_addr, 1);
4838    return 0;
4839}
4840
4841#if defined(TARGET_NR_stat64) || defined(TARGET_NR_newfstatat)
4842static inline abi_long host_to_target_stat64(void *cpu_env,
4843                                             abi_ulong target_addr,
4844                                             struct stat *host_st)
4845{
4846#if defined(TARGET_ARM) && defined(TARGET_ABI32)
4847    if (((CPUARMState *)cpu_env)->eabi) {
4848        struct target_eabi_stat64 *target_st;
4849
4850        if (!lock_user_struct(VERIFY_WRITE, target_st, target_addr, 0))
4851            return -TARGET_EFAULT;
4852        memset(target_st, 0, sizeof(struct target_eabi_stat64));
4853        __put_user(host_st->st_dev, &target_st->st_dev);
4854        __put_user(host_st->st_ino, &target_st->st_ino);
4855#ifdef TARGET_STAT64_HAS_BROKEN_ST_INO
4856        __put_user(host_st->st_ino, &target_st->__st_ino);
4857#endif
4858        __put_user(host_st->st_mode, &target_st->st_mode);
4859        __put_user(host_st->st_nlink, &target_st->st_nlink);
4860        __put_user(host_st->st_uid, &target_st->st_uid);
4861        __put_user(host_st->st_gid, &target_st->st_gid);
4862        __put_user(host_st->st_rdev, &target_st->st_rdev);
4863        __put_user(host_st->st_size, &target_st->st_size);
4864        __put_user(host_st->st_blksize, &target_st->st_blksize);
4865        __put_user(host_st->st_blocks, &target_st->st_blocks);
4866        __put_user(host_st->st_atime, &target_st->target_st_atime);
4867        __put_user(host_st->st_mtime, &target_st->target_st_mtime);
4868        __put_user(host_st->st_ctime, &target_st->target_st_ctime);
4869        unlock_user_struct(target_st, target_addr, 1);
4870    } else
4871#endif
4872    {
4873#if defined(TARGET_HAS_STRUCT_STAT64)
4874        struct target_stat64 *target_st;
4875#else
4876        struct target_stat *target_st;
4877#endif
4878
4879        if (!lock_user_struct(VERIFY_WRITE, target_st, target_addr, 0))
4880            return -TARGET_EFAULT;
4881        memset(target_st, 0, sizeof(*target_st));
4882        __put_user(host_st->st_dev, &target_st->st_dev);
4883        __put_user(host_st->st_ino, &target_st->st_ino);
4884#ifdef TARGET_STAT64_HAS_BROKEN_ST_INO
4885        __put_user(host_st->st_ino, &target_st->__st_ino);
4886#endif
4887        __put_user(host_st->st_mode, &target_st->st_mode);
4888        __put_user(host_st->st_nlink, &target_st->st_nlink);
4889        __put_user(host_st->st_uid, &target_st->st_uid);
4890        __put_user(host_st->st_gid, &target_st->st_gid);
4891        __put_user(host_st->st_rdev, &target_st->st_rdev);
4892        /* XXX: better use of kernel struct */
4893        __put_user(host_st->st_size, &target_st->st_size);
4894        __put_user(host_st->st_blksize, &target_st->st_blksize);
4895        __put_user(host_st->st_blocks, &target_st->st_blocks);
4896        __put_user(host_st->st_atime, &target_st->target_st_atime);
4897        __put_user(host_st->st_mtime, &target_st->target_st_mtime);
4898        __put_user(host_st->st_ctime, &target_st->target_st_ctime);
4899        unlock_user_struct(target_st, target_addr, 1);
4900    }
4901
4902    return 0;
4903}
4904#endif
4905
4906/* ??? Using host futex calls even when target atomic operations
4907   are not really atomic probably breaks things.  However implementing
4908   futexes locally would make futexes shared between multiple processes
4909   tricky.  However they're probably useless because guest atomic
4910   operations won't work either.  */
4911static int do_futex(target_ulong uaddr, int op, int val, target_ulong timeout,
4912                    target_ulong uaddr2, int val3)
4913{
4914    struct timespec ts, *pts;
4915    int base_op;
4916
4917    /* ??? We assume FUTEX_* constants are the same on both host
4918       and target.  */
4919#ifdef FUTEX_CMD_MASK
4920    base_op = op & FUTEX_CMD_MASK;
4921#else
4922    base_op = op;
4923#endif
4924    switch (base_op) {
4925    case FUTEX_WAIT:
4926    case FUTEX_WAIT_BITSET:
4927        if (timeout) {
4928            pts = &ts;
4929            target_to_host_timespec(pts, timeout);
4930        } else {
4931            pts = NULL;
4932        }
4933        return get_errno(sys_futex(g2h(uaddr), op, tswap32(val),
4934                         pts, NULL, val3));
4935    case FUTEX_WAKE:
4936        return get_errno(sys_futex(g2h(uaddr), op, val, NULL, NULL, 0));
4937    case FUTEX_FD:
4938        return get_errno(sys_futex(g2h(uaddr), op, val, NULL, NULL, 0));
4939    case FUTEX_REQUEUE:
4940    case FUTEX_CMP_REQUEUE:
4941    case FUTEX_WAKE_OP:
4942        /* For FUTEX_REQUEUE, FUTEX_CMP_REQUEUE, and FUTEX_WAKE_OP, the
4943           TIMEOUT parameter is interpreted as a uint32_t by the kernel.
4944           But the prototype takes a `struct timespec *'; insert casts
4945           to satisfy the compiler.  We do not need to tswap TIMEOUT
4946           since it's not compared to guest memory.  */
4947        pts = (struct timespec *)(uintptr_t) timeout;
4948        return get_errno(sys_futex(g2h(uaddr), op, val, pts,
4949                                   g2h(uaddr2),
4950                                   (base_op == FUTEX_CMP_REQUEUE
4951                                    ? tswap32(val3)
4952                                    : val3)));
4953    default:
4954        return -TARGET_ENOSYS;
4955    }
4956}
4957
4958/* Map host to target signal numbers for the wait family of syscalls.
4959   Assume all other status bits are the same.  */
4960int host_to_target_waitstatus(int status)
4961{
4962    if (WIFSIGNALED(status)) {
4963        return host_to_target_signal(WTERMSIG(status)) | (status & ~0x7f);
4964    }
4965    if (WIFSTOPPED(status)) {
4966        return (host_to_target_signal(WSTOPSIG(status)) << 8)
4967               | (status & 0xff);
4968    }
4969    return status;
4970}
4971
4972static int relstr_to_int(const char *s)
4973{
4974    /* Convert a uname release string like "2.6.18" to an integer
4975     * of the form 0x020612. (Beware that 0x020612 is *not* 2.6.12.)
4976     */
4977    int i, n, tmp;
4978
4979    tmp = 0;
4980    for (i = 0; i < 3; i++) {
4981        n = 0;
4982        while (*s >= '0' && *s <= '9') {
4983            n *= 10;
4984            n += *s - '0';
4985            s++;
4986        }
4987        tmp = (tmp << 8) + n;
4988        if (*s == '.') {
4989            s++;
4990        }
4991    }
4992    return tmp;
4993}
4994
4995int get_osversion(void)
4996{
4997    static int osversion;
4998    struct new_utsname buf;
4999    const char *s;
5000
5001    if (osversion)
5002        return osversion;
5003    if (qemu_uname_release && *qemu_uname_release) {
5004        s = qemu_uname_release;
5005    } else {
5006        if (sys_uname(&buf))
5007            return 0;
5008        s = buf.release;
5009    }
5010    osversion = relstr_to_int(s);
5011    return osversion;
5012}
5013
5014void init_qemu_uname_release(void)
5015{
5016    /* Initialize qemu_uname_release for later use.
5017     * If the host kernel is too old and the user hasn't asked for
5018     * a specific fake version number, we might want to fake a minimum
5019     * target kernel version.
5020     */
5021#ifdef UNAME_MINIMUM_RELEASE
5022    struct new_utsname buf;
5023
5024    if (qemu_uname_release && *qemu_uname_release) {
5025        return;
5026    }
5027
5028    if (sys_uname(&buf)) {
5029        return;
5030    }
5031
5032    if (relstr_to_int(buf.release) < relstr_to_int(UNAME_MINIMUM_RELEASE)) {
5033        qemu_uname_release = UNAME_MINIMUM_RELEASE;
5034    }
5035#endif
5036}
5037
5038static int open_self_maps(void *cpu_env, int fd)
5039{
5040#if defined(TARGET_ARM) || defined(TARGET_M68K) || defined(TARGET_UNICORE32)
5041    TaskState *ts = ((CPUArchState *)cpu_env)->opaque;
5042#endif
5043    FILE *fp;
5044    char *line = NULL;
5045    size_t len = 0;
5046    ssize_t read;
5047
5048    fp = fopen("/proc/self/maps", "r");
5049    if (fp == NULL) {
5050        return -EACCES;
5051    }
5052
5053    while ((read = getline(&line, &len, fp)) != -1) {
5054        int fields, dev_maj, dev_min, inode;
5055        uint64_t min, max, offset;
5056        char flag_r, flag_w, flag_x, flag_p;
5057        char path[512] = "";
5058        fields = sscanf(line, "%"PRIx64"-%"PRIx64" %c%c%c%c %"PRIx64" %x:%x %d"
5059                        " %512s", &min, &max, &flag_r, &flag_w, &flag_x,
5060                        &flag_p, &offset, &dev_maj, &dev_min, &inode, path);
5061
5062        if ((fields < 10) || (fields > 11)) {
5063            continue;
5064        }
5065        if (!strncmp(path, "[stack]", 7)) {
5066            continue;
5067        }
5068        if (h2g_valid(min) && h2g_valid(max)) {
5069            dprintf(fd, TARGET_ABI_FMT_lx "-" TARGET_ABI_FMT_lx
5070                    " %c%c%c%c %08" PRIx64 " %02x:%02x %d %s%s\n",
5071                    h2g(min), h2g(max), flag_r, flag_w,
5072                    flag_x, flag_p, offset, dev_maj, dev_min, inode,
5073                    path[0] ? "         " : "", path);
5074        }
5075    }
5076
5077    free(line);
5078    fclose(fp);
5079
5080#if defined(TARGET_ARM) || defined(TARGET_M68K) || defined(TARGET_UNICORE32)
5081    dprintf(fd, "%08llx-%08llx rw-p %08llx 00:00 0          [stack]\n",
5082                (unsigned long long)ts->info->stack_limit,
5083                (unsigned long long)(ts->info->start_stack +
5084                                     (TARGET_PAGE_SIZE - 1)) & TARGET_PAGE_MASK,
5085                (unsigned long long)0);
5086#endif
5087
5088    return 0;
5089}
5090
5091static int open_self_stat(void *cpu_env, int fd)
5092{
5093    TaskState *ts = ((CPUArchState *)cpu_env)->opaque;
5094    abi_ulong start_stack = ts->info->start_stack;
5095    int i;
5096
5097    for (i = 0; i < 44; i++) {
5098      char buf[128];
5099      int len;
5100      uint64_t val = 0;
5101
5102      if (i == 0) {
5103        /* pid */
5104        val = getpid();
5105        snprintf(buf, sizeof(buf), "%"PRId64 " ", val);
5106      } else if (i == 1) {
5107        /* app name */
5108        snprintf(buf, sizeof(buf), "(%s) ", ts->bprm->argv[0]);
5109      } else if (i == 27) {
5110        /* stack bottom */
5111        val = start_stack;
5112        snprintf(buf, sizeof(buf), "%"PRId64 " ", val);
5113      } else {
5114        /* for the rest, there is MasterCard */
5115        snprintf(buf, sizeof(buf), "0%c", i == 43 ? '\n' : ' ');
5116      }
5117
5118      len = strlen(buf);
5119      if (write(fd, buf, len) != len) {
5120          return -1;
5121      }
5122    }
5123
5124    return 0;
5125}
5126
5127static int open_self_auxv(void *cpu_env, int fd)
5128{
5129    TaskState *ts = ((CPUArchState *)cpu_env)->opaque;
5130    abi_ulong auxv = ts->info->saved_auxv;
5131    abi_ulong len = ts->info->auxv_len;
5132    char *ptr;
5133
5134    /*
5135     * Auxiliary vector is stored in target process stack.
5136     * read in whole auxv vector and copy it to file
5137     */
5138    ptr = lock_user(VERIFY_READ, auxv, len, 0);
5139    if (ptr != NULL) {
5140        while (len > 0) {
5141            ssize_t r;
5142            r = write(fd, ptr, len);
5143            if (r <= 0) {
5144                break;
5145            }
5146            len -= r;
5147            ptr += r;
5148        }
5149        lseek(fd, 0, SEEK_SET);
5150        unlock_user(ptr, auxv, len);
5151    }
5152
5153    return 0;
5154}
5155
5156static int is_proc_myself(const char *filename, const char *entry)
5157{
5158    if (!strncmp(filename, "/proc/", strlen("/proc/"))) {
5159        filename += strlen("/proc/");
5160        if (!strncmp(filename, "self/", strlen("self/"))) {
5161            filename += strlen("self/");
5162        } else if (*filename >= '1' && *filename <= '9') {
5163            char myself[80];
5164            snprintf(myself, sizeof(myself), "%d/", getpid());
5165            if (!strncmp(filename, myself, strlen(myself))) {
5166                filename += strlen(myself);
5167            } else {
5168                return 0;
5169            }
5170        } else {
5171            return 0;
5172        }
5173        if (!strcmp(filename, entry)) {
5174            return 1;
5175        }
5176    }
5177    return 0;
5178}
5179
5180#if defined(HOST_WORDS_BIGENDIAN) != defined(TARGET_WORDS_BIGENDIAN)
5181static int is_proc(const char *filename, const char *entry)
5182{
5183    return strcmp(filename, entry) == 0;
5184}
5185
5186static int open_net_route(void *cpu_env, int fd)
5187{
5188    FILE *fp;
5189    char *line = NULL;
5190    size_t len = 0;
5191    ssize_t read;
5192
5193    fp = fopen("/proc/net/route", "r");
5194    if (fp == NULL) {
5195        return -EACCES;
5196    }
5197
5198    /* read header */
5199
5200    read = getline(&line, &len, fp);
5201    dprintf(fd, "%s", line);
5202
5203    /* read routes */
5204
5205    while ((read = getline(&line, &len, fp)) != -1) {
5206        char iface[16];
5207        uint32_t dest, gw, mask;
5208        unsigned int flags, refcnt, use, metric, mtu, window, irtt;
5209        sscanf(line, "%s\t%08x\t%08x\t%04x\t%d\t%d\t%d\t%08x\t%d\t%u\t%u\n",
5210                     iface, &dest, &gw, &flags, &refcnt, &use, &metric,
5211                     &mask, &mtu, &window, &irtt);
5212        dprintf(fd, "%s\t%08x\t%08x\t%04x\t%d\t%d\t%d\t%08x\t%d\t%u\t%u\n",
5213                iface, tswap32(dest), tswap32(gw), flags, refcnt, use,
5214                metric, tswap32(mask), mtu, window, irtt);
5215    }
5216
5217    free(line);
5218    fclose(fp);
5219
5220    return 0;
5221}
5222#endif
5223
5224static int do_open(void *cpu_env, const char *pathname, int flags, mode_t mode)
5225{
5226    struct fake_open {
5227        const char *filename;
5228        int (*fill)(void *cpu_env, int fd);
5229        int (*cmp)(const char *s1, const char *s2);
5230    };
5231    const struct fake_open *fake_open;
5232    static const struct fake_open fakes[] = {
5233        { "maps", open_self_maps, is_proc_myself },
5234        { "stat", open_self_stat, is_proc_myself },
5235        { "auxv", open_self_auxv, is_proc_myself },
5236#if defined(HOST_WORDS_BIGENDIAN) != defined(TARGET_WORDS_BIGENDIAN)
5237        { "/proc/net/route", open_net_route, is_proc },
5238#endif
5239        { NULL, NULL, NULL }
5240    };
5241
5242    for (fake_open = fakes; fake_open->filename; fake_open++) {
5243        if (fake_open->cmp(pathname, fake_open->filename)) {
5244            break;
5245        }
5246    }
5247
5248    if (fake_open->filename) {
5249        const char *tmpdir;
5250        char filename[PATH_MAX];
5251        int fd, r;
5252
5253        /* create temporary file to map stat to */
5254        tmpdir = getenv("TMPDIR");
5255        if (!tmpdir)
5256            tmpdir = "/tmp";
5257        snprintf(filename, sizeof(filename), "%s/qemu-open.XXXXXX", tmpdir);
5258        fd = mkstemp(filename);
5259        if (fd < 0) {
5260            return fd;
5261        }
5262        unlink(filename);
5263
5264        if ((r = fake_open->fill(cpu_env, fd))) {
5265            close(fd);
5266            return r;
5267        }
5268        lseek(fd, 0, SEEK_SET);
5269
5270        return fd;
5271    }
5272
5273    return get_errno(open(path(pathname), flags, mode));
5274}
5275
5276/* do_syscall() should always have a single exit point at the end so
5277   that actions, such as logging of syscall results, can be performed.
5278   All errnos that do_syscall() returns must be -TARGET_<errcode>. */
5279abi_long do_syscall(void *cpu_env, int num, abi_long arg1,
5280                    abi_long arg2, abi_long arg3, abi_long arg4,
5281                    abi_long arg5, abi_long arg6, abi_long arg7,
5282                    abi_long arg8)
5283{
5284    CPUState *cpu = ENV_GET_CPU(cpu_env);
5285    abi_long ret;
5286    struct stat st;
5287    struct statfs stfs;
5288    void *p;
5289
5290#ifdef DEBUG
5291    gemu_log("syscall %d", num);
5292#endif
5293    if(do_strace)
5294        print_syscall(num, arg1, arg2, arg3, arg4, arg5, arg6);
5295
5296    switch(num) {
5297    case TARGET_NR_exit:
5298        /* In old applications this may be used to implement _exit(2).
5299           However in threaded applictions it is used for thread termination,
5300           and _exit_group is used for application termination.
5301           Do thread termination if we have more then one thread.  */
5302        /* FIXME: This probably breaks if a signal arrives.  We should probably
5303           be disabling signals.  */
5304        if (CPU_NEXT(first_cpu)) {
5305            TaskState *ts;
5306
5307            cpu_list_lock();
5308            /* Remove the CPU from the list.  */
5309            QTAILQ_REMOVE(&cpus, cpu, node);
5310            cpu_list_unlock();
5311            ts = ((CPUArchState *)cpu_env)->opaque;
5312            if (ts->child_tidptr) {
5313                put_user_u32(0, ts->child_tidptr);
5314                sys_futex(g2h(ts->child_tidptr), FUTEX_WAKE, INT_MAX,
5315                          NULL, NULL, 0);
5316            }
5317            thread_cpu = NULL;
5318            object_unref(OBJECT(ENV_GET_CPU(cpu_env)));
5319            g_free(ts);
5320            pthread_exit(NULL);
5321        }
5322#ifdef TARGET_GPROF
5323        _mcleanup();
5324#endif
5325        gdb_exit(cpu_env, arg1);
5326        _exit(arg1);
5327        ret = 0; /* avoid warning */
5328        break;
5329    case TARGET_NR_read:
5330        if (arg3 == 0)
5331            ret = 0;
5332        else {
5333            if (!(p = lock_user(VERIFY_WRITE, arg2, arg3, 0)))
5334                goto efault;
5335            ret = get_errno(read(arg1, p, arg3));
5336            unlock_user(p, arg2, ret);
5337        }
5338        break;
5339    case TARGET_NR_write:
5340        if (!(p = lock_user(VERIFY_READ, arg2, arg3, 1)))
5341            goto efault;
5342        ret = get_errno(write(arg1, p, arg3));
5343        unlock_user(p, arg2, 0);
5344        break;
5345    case TARGET_NR_open:
5346        if (!(p = lock_user_string(arg1)))
5347            goto efault;
5348        ret = get_errno(do_open(cpu_env, p,
5349                                target_to_host_bitmask(arg2, fcntl_flags_tbl),
5350                                arg3));
5351        unlock_user(p, arg1, 0);
5352        break;
5353#if defined(TARGET_NR_openat) && defined(__NR_openat)
5354    case TARGET_NR_openat:
5355        if (!(p = lock_user_string(arg2)))
5356            goto efault;
5357        ret = get_errno(sys_openat(arg1,
5358                                   path(p),
5359                                   target_to_host_bitmask(arg3, fcntl_flags_tbl),
5360                                   arg4));
5361        unlock_user(p, arg2, 0);
5362        break;
5363#endif
5364    case TARGET_NR_close:
5365        ret = get_errno(close(arg1));
5366        break;
5367    case TARGET_NR_brk:
5368        ret = do_brk(arg1);
5369        break;
5370    case TARGET_NR_fork:
5371        ret = get_errno(do_fork(cpu_env, SIGCHLD, 0, 0, 0, 0));
5372        break;
5373#ifdef TARGET_NR_waitpid
5374    case TARGET_NR_waitpid:
5375        {
5376            int status;
5377            ret = get_errno(waitpid(arg1, &status, arg3));
5378            if (!is_error(ret) && arg2 && ret
5379                && put_user_s32(host_to_target_waitstatus(status), arg2))
5380                goto efault;
5381        }
5382        break;
5383#endif
5384#ifdef TARGET_NR_waitid
5385    case TARGET_NR_waitid:
5386        {
5387            siginfo_t info;
5388            info.si_pid = 0;
5389            ret = get_errno(waitid(arg1, arg2, &info, arg4));
5390            if (!is_error(ret) && arg3 && info.si_pid != 0) {
5391                if (!(p = lock_user(VERIFY_WRITE, arg3, sizeof(target_siginfo_t), 0)))
5392                    goto efault;
5393                host_to_target_siginfo(p, &info);
5394                unlock_user(p, arg3, sizeof(target_siginfo_t));
5395            }
5396        }
5397        break;
5398#endif
5399#ifdef TARGET_NR_creat /* not on alpha */
5400    case TARGET_NR_creat:
5401        if (!(p = lock_user_string(arg1)))
5402            goto efault;
5403        ret = get_errno(creat(p, arg2));
5404        unlock_user(p, arg1, 0);
5405        break;
5406#endif
5407    case TARGET_NR_link:
5408        {
5409            void * p2;
5410            p = lock_user_string(arg1);
5411            p2 = lock_user_string(arg2);
5412            if (!p || !p2)
5413                ret = -TARGET_EFAULT;
5414            else
5415                ret = get_errno(link(p, p2));
5416            unlock_user(p2, arg2, 0);
5417            unlock_user(p, arg1, 0);
5418        }
5419        break;
5420#if defined(TARGET_NR_linkat)
5421    case TARGET_NR_linkat:
5422        {
5423            void * p2 = NULL;
5424            if (!arg2 || !arg4)
5425                goto efault;
5426            p  = lock_user_string(arg2);
5427            p2 = lock_user_string(arg4);
5428            if (!p || !p2)
5429                ret = -TARGET_EFAULT;
5430            else
5431                ret = get_errno(linkat(arg1, p, arg3, p2, arg5));
5432            unlock_user(p, arg2, 0);
5433            unlock_user(p2, arg4, 0);
5434        }
5435        break;
5436#endif
5437    case TARGET_NR_unlink:
5438        if (!(p = lock_user_string(arg1)))
5439            goto efault;
5440        ret = get_errno(unlink(p));
5441        unlock_user(p, arg1, 0);
5442        break;
5443#if defined(TARGET_NR_unlinkat)
5444    case TARGET_NR_unlinkat:
5445        if (!(p = lock_user_string(arg2)))
5446            goto efault;
5447        ret = get_errno(unlinkat(arg1, p, arg3));
5448        unlock_user(p, arg2, 0);
5449        break;
5450#endif
5451    case TARGET_NR_execve:
5452        {
5453            char **argp, **envp;
5454            int argc, envc;
5455            abi_ulong gp;
5456            abi_ulong guest_argp;
5457            abi_ulong guest_envp;
5458            abi_ulong addr;
5459            char **q;
5460            int total_size = 0;
5461
5462            argc = 0;
5463            guest_argp = arg2;
5464            for (gp = guest_argp; gp; gp += sizeof(abi_ulong)) {
5465                if (get_user_ual(addr, gp))
5466                    goto efault;
5467                if (!addr)
5468                    break;
5469                argc++;
5470            }
5471            envc = 0;
5472            guest_envp = arg3;
5473            for (gp = guest_envp; gp; gp += sizeof(abi_ulong)) {
5474                if (get_user_ual(addr, gp))
5475                    goto efault;
5476                if (!addr)
5477                    break;
5478                envc++;
5479            }
5480
5481            argp = alloca((argc + 1) * sizeof(void *));
5482            envp = alloca((envc + 1) * sizeof(void *));
5483
5484            for (gp = guest_argp, q = argp; gp;
5485                  gp += sizeof(abi_ulong), q++) {
5486                if (get_user_ual(addr, gp))
5487                    goto execve_efault;
5488                if (!addr)
5489                    break;
5490                if (!(*q = lock_user_string(addr)))
5491                    goto execve_efault;
5492                total_size += strlen(*q) + 1;
5493            }
5494            *q = NULL;
5495
5496            for (gp = guest_envp, q = envp; gp;
5497                  gp += sizeof(abi_ulong), q++) {
5498                if (get_user_ual(addr, gp))
5499                    goto execve_efault;
5500                if (!addr)
5501                    break;
5502                if (!(*q = lock_user_string(addr)))
5503                    goto execve_efault;
5504                total_size += strlen(*q) + 1;
5505            }
5506            *q = NULL;
5507
5508            /* This case will not be caught by the host's execve() if its
5509               page size is bigger than the target's. */
5510            if (total_size > MAX_ARG_PAGES * TARGET_PAGE_SIZE) {
5511                ret = -TARGET_E2BIG;
5512                goto execve_end;
5513            }
5514            if (!(p = lock_user_string(arg1)))
5515                goto execve_efault;
5516            ret = get_errno(execve(p, argp, envp));
5517            unlock_user(p, arg1, 0);
5518
5519            goto execve_end;
5520
5521        execve_efault:
5522            ret = -TARGET_EFAULT;
5523
5524        execve_end:
5525            for (gp = guest_argp, q = argp; *q;
5526                  gp += sizeof(abi_ulong), q++) {
5527                if (get_user_ual(addr, gp)
5528                    || !addr)
5529                    break;
5530                unlock_user(*q, addr, 0);
5531            }
5532            for (gp = guest_envp, q = envp; *q;
5533                  gp += sizeof(abi_ulong), q++) {
5534                if (get_user_ual(addr, gp)
5535                    || !addr)
5536                    break;
5537                unlock_user(*q, addr, 0);
5538            }
5539        }
5540        break;
5541    case TARGET_NR_chdir:
5542        if (!(p = lock_user_string(arg1)))
5543            goto efault;
5544        ret = get_errno(chdir(p));
5545        unlock_user(p, arg1, 0);
5546        break;
5547#ifdef TARGET_NR_time
5548    case TARGET_NR_time:
5549        {
5550            time_t host_time;
5551            ret = get_errno(time(&host_time));
5552            if (!is_error(ret)
5553                && arg1
5554                && put_user_sal(host_time, arg1))
5555                goto efault;
5556        }
5557        break;
5558#endif
5559    case TARGET_NR_mknod:
5560        if (!(p = lock_user_string(arg1)))
5561            goto efault;
5562        ret = get_errno(mknod(p, arg2, arg3));
5563        unlock_user(p, arg1, 0);
5564        break;
5565#if defined(TARGET_NR_mknodat)
5566    case TARGET_NR_mknodat:
5567        if (!(p = lock_user_string(arg2)))
5568            goto efault;
5569        ret = get_errno(mknodat(arg1, p, arg3, arg4));
5570        unlock_user(p, arg2, 0);
5571        break;
5572#endif
5573    case TARGET_NR_chmod:
5574        if (!(p = lock_user_string(arg1)))
5575            goto efault;
5576        ret = get_errno(chmod(p, arg2));
5577        unlock_user(p, arg1, 0);
5578        break;
5579#ifdef TARGET_NR_break
5580    case TARGET_NR_break:
5581        goto unimplemented;
5582#endif
5583#ifdef TARGET_NR_oldstat
5584    case TARGET_NR_oldstat:
5585        goto unimplemented;
5586#endif
5587    case TARGET_NR_lseek:
5588        ret = get_errno(lseek(arg1, arg2, arg3));
5589        break;
5590#if defined(TARGET_NR_getxpid) && defined(TARGET_ALPHA)
5591    /* Alpha specific */
5592    case TARGET_NR_getxpid:
5593        ((CPUAlphaState *)cpu_env)->ir[IR_A4] = getppid();
5594        ret = get_errno(getpid());
5595        break;
5596#endif
5597#ifdef TARGET_NR_getpid
5598    case TARGET_NR_getpid:
5599        ret = get_errno(getpid());
5600        break;
5601#endif
5602    case TARGET_NR_mount:
5603                {
5604                        /* need to look at the data field */
5605                        void *p2, *p3;
5606                        p = lock_user_string(arg1);
5607                        p2 = lock_user_string(arg2);
5608                        p3 = lock_user_string(arg3);
5609                        if (!p || !p2 || !p3)
5610                            ret = -TARGET_EFAULT;
5611                        else {
5612                            /* FIXME - arg5 should be locked, but it isn't clear how to
5613                             * do that since it's not guaranteed to be a NULL-terminated
5614                             * string.
5615                             */
5616                            if ( ! arg5 )
5617                                ret = get_errno(mount(p, p2, p3, (unsigned long)arg4, NULL));
5618                            else
5619                                ret = get_errno(mount(p, p2, p3, (unsigned long)arg4, g2h(arg5)));
5620                        }
5621                        unlock_user(p, arg1, 0);
5622                        unlock_user(p2, arg2, 0);
5623                        unlock_user(p3, arg3, 0);
5624                        break;
5625                }
5626#ifdef TARGET_NR_umount
5627    case TARGET_NR_umount:
5628        if (!(p = lock_user_string(arg1)))
5629            goto efault;
5630        ret = get_errno(umount(p));
5631        unlock_user(p, arg1, 0);
5632        break;
5633#endif
5634#ifdef TARGET_NR_stime /* not on alpha */
5635    case TARGET_NR_stime:
5636        {
5637            time_t host_time;
5638            if (get_user_sal(host_time, arg1))
5639                goto efault;
5640            ret = get_errno(stime(&host_time));
5641        }
5642        break;
5643#endif
5644    case TARGET_NR_ptrace:
5645        goto unimplemented;
5646#ifdef TARGET_NR_alarm /* not on alpha */
5647    case TARGET_NR_alarm:
5648        ret = alarm(arg1);
5649        break;
5650#endif
5651#ifdef TARGET_NR_oldfstat
5652    case TARGET_NR_oldfstat:
5653        goto unimplemented;
5654#endif
5655#ifdef TARGET_NR_pause /* not on alpha */
5656    case TARGET_NR_pause:
5657        ret = get_errno(pause());
5658        break;
5659#endif
5660#ifdef TARGET_NR_utime
5661    case TARGET_NR_utime:
5662        {
5663            struct utimbuf tbuf, *host_tbuf;
5664            struct target_utimbuf *target_tbuf;
5665            if (arg2) {
5666                if (!lock_user_struct(VERIFY_READ, target_tbuf, arg2, 1))
5667                    goto efault;
5668                tbuf.actime = tswapal(target_tbuf->actime);
5669                tbuf.modtime = tswapal(target_tbuf->modtime);
5670                unlock_user_struct(target_tbuf, arg2, 0);
5671                host_tbuf = &tbuf;
5672            } else {
5673                host_tbuf = NULL;
5674            }
5675            if (!(p = lock_user_string(arg1)))
5676                goto efault;
5677            ret = get_errno(utime(p, host_tbuf));
5678            unlock_user(p, arg1, 0);
5679        }
5680        break;
5681#endif
5682    case TARGET_NR_utimes:
5683        {
5684            struct timeval *tvp, tv[2];
5685            if (arg2) {
5686                if (copy_from_user_timeval(&tv[0], arg2)
5687                    || copy_from_user_timeval(&tv[1],
5688                                              arg2 + sizeof(struct target_timeval)))
5689                    goto efault;
5690                tvp = tv;
5691            } else {
5692                tvp = NULL;
5693            }
5694            if (!(p = lock_user_string(arg1)))
5695                goto efault;
5696            ret = get_errno(utimes(p, tvp));
5697            unlock_user(p, arg1, 0);
5698        }
5699        break;
5700#if defined(TARGET_NR_futimesat)
5701    case TARGET_NR_futimesat:
5702        {
5703            struct timeval *tvp, tv[2];
5704            if (arg3) {
5705                if (copy_from_user_timeval(&tv[0], arg3)
5706                    || copy_from_user_timeval(&tv[1],
5707                                              arg3 + sizeof(struct target_timeval)))
5708                    goto efault;
5709                tvp = tv;
5710            } else {
5711                tvp = NULL;
5712            }
5713            if (!(p = lock_user_string(arg2)))
5714                goto efault;
5715            ret = get_errno(futimesat(arg1, path(p), tvp));
5716            unlock_user(p, arg2, 0);
5717        }
5718        break;
5719#endif
5720#ifdef TARGET_NR_stty
5721    case TARGET_NR_stty:
5722        goto unimplemented;
5723#endif
5724#ifdef TARGET_NR_gtty
5725    case TARGET_NR_gtty:
5726        goto unimplemented;
5727#endif
5728    case TARGET_NR_access:
5729        if (!(p = lock_user_string(arg1)))
5730            goto efault;
5731        ret = get_errno(access(path(p), arg2));
5732        unlock_user(p, arg1, 0);
5733        break;
5734#if defined(TARGET_NR_faccessat) && defined(__NR_faccessat)
5735    case TARGET_NR_faccessat:
5736        if (!(p = lock_user_string(arg2)))
5737            goto efault;
5738        ret = get_errno(faccessat(arg1, p, arg3, 0));
5739        unlock_user(p, arg2, 0);
5740        break;
5741#endif
5742#ifdef TARGET_NR_nice /* not on alpha */
5743    case TARGET_NR_nice:
5744        ret = get_errno(nice(arg1));
5745        break;
5746#endif
5747#ifdef TARGET_NR_ftime
5748    case TARGET_NR_ftime:
5749        goto unimplemented;
5750#endif
5751    case TARGET_NR_sync:
5752        sync();
5753        ret = 0;
5754        break;
5755    case TARGET_NR_kill:
5756        ret = get_errno(kill(arg1, target_to_host_signal(arg2)));
5757        break;
5758    case TARGET_NR_rename:
5759        {
5760            void *p2;
5761            p = lock_user_string(arg1);
5762            p2 = lock_user_string(arg2);
5763            if (!p || !p2)
5764                ret = -TARGET_EFAULT;
5765            else
5766                ret = get_errno(rename(p, p2));
5767            unlock_user(p2, arg2, 0);
5768            unlock_user(p, arg1, 0);
5769        }
5770        break;
5771#if defined(TARGET_NR_renameat)
5772    case TARGET_NR_renameat:
5773        {
5774            void *p2;
5775            p  = lock_user_string(arg2);
5776            p2 = lock_user_string(arg4);
5777            if (!p || !p2)
5778                ret = -TARGET_EFAULT;
5779            else
5780                ret = get_errno(renameat(arg1, p, arg3, p2));
5781            unlock_user(p2, arg4, 0);
5782            unlock_user(p, arg2, 0);
5783        }
5784        break;
5785#endif
5786    case TARGET_NR_mkdir:
5787        if (!(p = lock_user_string(arg1)))
5788            goto efault;
5789        ret = get_errno(mkdir(p, arg2));
5790        unlock_user(p, arg1, 0);
5791        break;
5792#if defined(TARGET_NR_mkdirat)
5793    case TARGET_NR_mkdirat:
5794        if (!(p = lock_user_string(arg2)))
5795            goto efault;
5796        ret = get_errno(mkdirat(arg1, p, arg3));
5797        unlock_user(p, arg2, 0);
5798        break;
5799#endif
5800    case TARGET_NR_rmdir:
5801        if (!(p = lock_user_string(arg1)))
5802            goto efault;
5803        ret = get_errno(rmdir(p));
5804        unlock_user(p, arg1, 0);
5805        break;
5806    case TARGET_NR_dup:
5807        ret = get_errno(dup(arg1));
5808        break;
5809    case TARGET_NR_pipe:
5810        ret = do_pipe(cpu_env, arg1, 0, 0);
5811        break;
5812#ifdef TARGET_NR_pipe2
5813    case TARGET_NR_pipe2:
5814        ret = do_pipe(cpu_env, arg1,
5815                      target_to_host_bitmask(arg2, fcntl_flags_tbl), 1);
5816        break;
5817#endif
5818    case TARGET_NR_times:
5819        {
5820            struct target_tms *tmsp;
5821            struct tms tms;
5822            ret = get_errno(times(&tms));
5823            if (arg1) {
5824                tmsp = lock_user(VERIFY_WRITE, arg1, sizeof(struct target_tms), 0);
5825                if (!tmsp)
5826                    goto efault;
5827                tmsp->tms_utime = tswapal(host_to_target_clock_t(tms.tms_utime));
5828                tmsp->tms_stime = tswapal(host_to_target_clock_t(tms.tms_stime));
5829                tmsp->tms_cutime = tswapal(host_to_target_clock_t(tms.tms_cutime));
5830                tmsp->tms_cstime = tswapal(host_to_target_clock_t(tms.tms_cstime));
5831            }
5832            if (!is_error(ret))
5833                ret = host_to_target_clock_t(ret);
5834        }
5835        break;
5836#ifdef TARGET_NR_prof
5837    case TARGET_NR_prof:
5838        goto unimplemented;
5839#endif
5840#ifdef TARGET_NR_signal
5841    case TARGET_NR_signal:
5842        goto unimplemented;
5843#endif
5844    case TARGET_NR_acct:
5845        if (arg1 == 0) {
5846            ret = get_errno(acct(NULL));
5847        } else {
5848            if (!(p = lock_user_string(arg1)))
5849                goto efault;
5850            ret = get_errno(acct(path(p)));
5851            unlock_user(p, arg1, 0);
5852        }
5853        break;
5854#ifdef TARGET_NR_umount2
5855    case TARGET_NR_umount2:
5856        if (!(p = lock_user_string(arg1)))
5857            goto efault;
5858        ret = get_errno(umount2(p, arg2));
5859        unlock_user(p, arg1, 0);
5860        break;
5861#endif
5862#ifdef TARGET_NR_lock
5863    case TARGET_NR_lock:
5864        goto unimplemented;
5865#endif
5866    case TARGET_NR_ioctl:
5867        ret = do_ioctl(arg1, arg2, arg3);
5868        break;
5869    case TARGET_NR_fcntl:
5870        ret = do_fcntl(arg1, arg2, arg3);
5871        break;
5872#ifdef TARGET_NR_mpx
5873    case TARGET_NR_mpx:
5874        goto unimplemented;
5875#endif
5876    case TARGET_NR_setpgid:
5877        ret = get_errno(setpgid(arg1, arg2));
5878        break;
5879#ifdef TARGET_NR_ulimit
5880    case TARGET_NR_ulimit:
5881        goto unimplemented;
5882#endif
5883#ifdef TARGET_NR_oldolduname
5884    case TARGET_NR_oldolduname:
5885        goto unimplemented;
5886#endif
5887    case TARGET_NR_umask:
5888        ret = get_errno(umask(arg1));
5889        break;
5890    case TARGET_NR_chroot:
5891        if (!(p = lock_user_string(arg1)))
5892            goto efault;
5893        ret = get_errno(chroot(p));
5894        unlock_user(p, arg1, 0);
5895        break;
5896    case TARGET_NR_ustat:
5897        goto unimplemented;
5898    case TARGET_NR_dup2:
5899        ret = get_errno(dup2(arg1, arg2));
5900        break;
5901#if defined(CONFIG_DUP3) && defined(TARGET_NR_dup3)
5902    case TARGET_NR_dup3:
5903        ret = get_errno(dup3(arg1, arg2, arg3));
5904        break;
5905#endif
5906#ifdef TARGET_NR_getppid /* not on alpha */
5907    case TARGET_NR_getppid:
5908        ret = get_errno(getppid());
5909        break;
5910#endif
5911    case TARGET_NR_getpgrp:
5912        ret = get_errno(getpgrp());
5913        break;
5914    case TARGET_NR_setsid:
5915        ret = get_errno(setsid());
5916        break;
5917#ifdef TARGET_NR_sigaction
5918    case TARGET_NR_sigaction:
5919        {
5920#if defined(TARGET_ALPHA)
5921            struct target_sigaction act, oact, *pact = 0;
5922            struct target_old_sigaction *old_act;
5923            if (arg2) {
5924                if (!lock_user_struct(VERIFY_READ, old_act, arg2, 1))
5925                    goto efault;
5926                act._sa_handler = old_act->_sa_handler;
5927                target_siginitset(&act.sa_mask, old_act->sa_mask);
5928                act.sa_flags = old_act->sa_flags;
5929                act.sa_restorer = 0;
5930                unlock_user_struct(old_act, arg2, 0);
5931                pact = &act;
5932            }
5933            ret = get_errno(do_sigaction(arg1, pact, &oact));
5934            if (!is_error(ret) && arg3) {
5935                if (!lock_user_struct(VERIFY_WRITE, old_act, arg3, 0))
5936                    goto efault;
5937                old_act->_sa_handler = oact._sa_handler;
5938                old_act->sa_mask = oact.sa_mask.sig[0];
5939                old_act->sa_flags = oact.sa_flags;
5940                unlock_user_struct(old_act, arg3, 1);
5941            }
5942#elif defined(TARGET_MIPS)
5943            struct target_sigaction act, oact, *pact, *old_act;
5944
5945            if (arg2) {
5946                if (!lock_user_struct(VERIFY_READ, old_act, arg2, 1))
5947                    goto efault;
5948                act._sa_handler = old_act->_sa_handler;
5949                target_siginitset(&act.sa_mask, old_act->sa_mask.sig[0]);
5950                act.sa_flags = old_act->sa_flags;
5951                unlock_user_struct(old_act, arg2, 0);
5952                pact = &act;
5953            } else {
5954                pact = NULL;
5955            }
5956
5957            ret = get_errno(do_sigaction(arg1, pact, &oact));
5958
5959            if (!is_error(ret) && arg3) {
5960                if (!lock_user_struct(VERIFY_WRITE, old_act, arg3, 0))
5961                    goto efault;
5962                old_act->_sa_handler = oact._sa_handler;
5963                old_act->sa_flags = oact.sa_flags;
5964                old_act->sa_mask.sig[0] = oact.sa_mask.sig[0];
5965                old_act->sa_mask.sig[1] = 0;
5966                old_act->sa_mask.sig[2] = 0;
5967                old_act->sa_mask.sig[3] = 0;
5968                unlock_user_struct(old_act, arg3, 1);
5969            }
5970#else
5971            struct target_old_sigaction *old_act;
5972            struct target_sigaction act, oact, *pact;
5973            if (arg2) {
5974                if (!lock_user_struct(VERIFY_READ, old_act, arg2, 1))
5975                    goto efault;
5976                act._sa_handler = old_act->_sa_handler;
5977                target_siginitset(&act.sa_mask, old_act->sa_mask);
5978                act.sa_flags = old_act->sa_flags;
5979                act.sa_restorer = old_act->sa_restorer;
5980                unlock_user_struct(old_act, arg2, 0);
5981                pact = &act;
5982            } else {
5983                pact = NULL;
5984            }
5985            ret = get_errno(do_sigaction(arg1, pact, &oact));
5986            if (!is_error(ret) && arg3) {
5987                if (!lock_user_struct(VERIFY_WRITE, old_act, arg3, 0))
5988                    goto efault;
5989                old_act->_sa_handler = oact._sa_handler;
5990                old_act->sa_mask = oact.sa_mask.sig[0];
5991                old_act->sa_flags = oact.sa_flags;
5992                old_act->sa_restorer = oact.sa_restorer;
5993                unlock_user_struct(old_act, arg3, 1);
5994            }
5995#endif
5996        }
5997        break;
5998#endif
5999    case TARGET_NR_rt_sigaction:
6000        {
6001#if defined(TARGET_ALPHA)
6002            struct target_sigaction act, oact, *pact = 0;
6003            struct target_rt_sigaction *rt_act;
6004            /* ??? arg4 == sizeof(sigset_t).  */
6005            if (arg2) {
6006                if (!lock_user_struct(VERIFY_READ, rt_act, arg2, 1))
6007                    goto efault;
6008                act._sa_handler = rt_act->_sa_handler;
6009                act.sa_mask = rt_act->sa_mask;
6010                act.sa_flags = rt_act->sa_flags;
6011                act.sa_restorer = arg5;
6012                unlock_user_struct(rt_act, arg2, 0);
6013                pact = &act;
6014            }
6015            ret = get_errno(do_sigaction(arg1, pact, &oact));
6016            if (!is_error(ret) && arg3) {
6017                if (!lock_user_struct(VERIFY_WRITE, rt_act, arg3, 0))
6018                    goto efault;
6019                rt_act->_sa_handler = oact._sa_handler;
6020                rt_act->sa_mask = oact.sa_mask;
6021                rt_act->sa_flags = oact.sa_flags;
6022                unlock_user_struct(rt_act, arg3, 1);
6023            }
6024#else
6025            struct target_sigaction *act;
6026            struct target_sigaction *oact;
6027
6028            if (arg2) {
6029                if (!lock_user_struct(VERIFY_READ, act, arg2, 1))
6030                    goto efault;
6031            } else
6032                act = NULL;
6033            if (arg3) {
6034                if (!lock_user_struct(VERIFY_WRITE, oact, arg3, 0)) {
6035                    ret = -TARGET_EFAULT;
6036                    goto rt_sigaction_fail;
6037                }
6038            } else
6039                oact = NULL;
6040            ret = get_errno(do_sigaction(arg1, act, oact));
6041        rt_sigaction_fail:
6042            if (act)
6043                unlock_user_struct(act, arg2, 0);
6044            if (oact)
6045                unlock_user_struct(oact, arg3, 1);
6046#endif
6047        }
6048        break;
6049#ifdef TARGET_NR_sgetmask /* not on alpha */
6050    case TARGET_NR_sgetmask:
6051        {
6052            sigset_t cur_set;
6053            abi_ulong target_set;
6054            sigprocmask(0, NULL, &cur_set);
6055            host_to_target_old_sigset(&target_set, &cur_set);
6056            ret = target_set;
6057        }
6058        break;
6059#endif
6060#ifdef TARGET_NR_ssetmask /* not on alpha */
6061    case TARGET_NR_ssetmask:
6062        {
6063            sigset_t set, oset, cur_set;
6064            abi_ulong target_set = arg1;
6065            sigprocmask(0, NULL, &cur_set);
6066            target_to_host_old_sigset(&set, &target_set);
6067            sigorset(&set, &set, &cur_set);
6068            sigprocmask(SIG_SETMASK, &set, &oset);
6069            host_to_target_old_sigset(&target_set, &oset);
6070            ret = target_set;
6071        }
6072        break;
6073#endif
6074#ifdef TARGET_NR_sigprocmask
6075    case TARGET_NR_sigprocmask:
6076        {
6077#if defined(TARGET_ALPHA)
6078            sigset_t set, oldset;
6079            abi_ulong mask;
6080            int how;
6081
6082            switch (arg1) {
6083            case TARGET_SIG_BLOCK:
6084                how = SIG_BLOCK;
6085                break;
6086            case TARGET_SIG_UNBLOCK:
6087                how = SIG_UNBLOCK;
6088                break;
6089            case TARGET_SIG_SETMASK:
6090                how = SIG_SETMASK;
6091                break;
6092            default:
6093                ret = -TARGET_EINVAL;
6094                goto fail;
6095            }
6096            mask = arg2;
6097            target_to_host_old_sigset(&set, &mask);
6098
6099            ret = get_errno(sigprocmask(how, &set, &oldset));
6100            if (!is_error(ret)) {
6101                host_to_target_old_sigset(&mask, &oldset);
6102                ret = mask;
6103                ((CPUAlphaState *)cpu_env)->ir[IR_V0] = 0; /* force no error */
6104            }
6105#else
6106            sigset_t set, oldset, *set_ptr;
6107            int how;
6108
6109            if (arg2) {
6110                switch (arg1) {
6111                case TARGET_SIG_BLOCK:
6112                    how = SIG_BLOCK;
6113                    break;
6114                case TARGET_SIG_UNBLOCK:
6115                    how = SIG_UNBLOCK;
6116                    break;
6117                case TARGET_SIG_SETMASK:
6118                    how = SIG_SETMASK;
6119                    break;
6120                default:
6121                    ret = -TARGET_EINVAL;
6122                    goto fail;
6123                }
6124                if (!(p = lock_user(VERIFY_READ, arg2, sizeof(target_sigset_t), 1)))
6125                    goto efault;
6126                target_to_host_old_sigset(&set, p);
6127                unlock_user(p, arg2, 0);
6128                set_ptr = &set;
6129            } else {
6130                how = 0;
6131                set_ptr = NULL;
6132            }
6133            ret = get_errno(sigprocmask(how, set_ptr, &oldset));
6134            if (!is_error(ret) && arg3) {
6135                if (!(p = lock_user(VERIFY_WRITE, arg3, sizeof(target_sigset_t), 0)))
6136                    goto efault;
6137                host_to_target_old_sigset(p, &oldset);
6138                unlock_user(p, arg3, sizeof(target_sigset_t));
6139            }
6140#endif
6141        }
6142        break;
6143#endif
6144    case TARGET_NR_rt_sigprocmask:
6145        {
6146            int how = arg1;
6147            sigset_t set, oldset, *set_ptr;
6148
6149            if (arg2) {
6150                switch(how) {
6151                case TARGET_SIG_BLOCK:
6152                    how = SIG_BLOCK;
6153                    break;
6154                case TARGET_SIG_UNBLOCK:
6155                    how = SIG_UNBLOCK;
6156                    break;
6157                case TARGET_SIG_SETMASK:
6158                    how = SIG_SETMASK;
6159                    break;
6160                default:
6161                    ret = -TARGET_EINVAL;
6162                    goto fail;
6163                }
6164                if (!(p = lock_user(VERIFY_READ, arg2, sizeof(target_sigset_t), 1)))
6165                    goto efault;
6166                target_to_host_sigset(&set, p);
6167                unlock_user(p, arg2, 0);
6168                set_ptr = &set;
6169            } else {
6170                how = 0;
6171                set_ptr = NULL;
6172            }
6173            ret = get_errno(sigprocmask(how, set_ptr, &oldset));
6174            if (!is_error(ret) && arg3) {
6175                if (!(p = lock_user(VERIFY_WRITE, arg3, sizeof(target_sigset_t), 0)))
6176                    goto efault;
6177                host_to_target_sigset(p, &oldset);
6178                unlock_user(p, arg3, sizeof(target_sigset_t));
6179            }
6180        }
6181        break;
6182#ifdef TARGET_NR_sigpending
6183    case TARGET_NR_sigpending:
6184        {
6185            sigset_t set;
6186            ret = get_errno(sigpending(&set));
6187            if (!is_error(ret)) {
6188                if (!(p = lock_user(VERIFY_WRITE, arg1, sizeof(target_sigset_t), 0)))
6189                    goto efault;
6190                host_to_target_old_sigset(p, &set);
6191                unlock_user(p, arg1, sizeof(target_sigset_t));
6192            }
6193        }
6194        break;
6195#endif
6196    case TARGET_NR_rt_sigpending:
6197        {
6198            sigset_t set;
6199            ret = get_errno(sigpending(&set));
6200            if (!is_error(ret)) {
6201                if (!(p = lock_user(VERIFY_WRITE, arg1, sizeof(target_sigset_t), 0)))
6202                    goto efault;
6203                host_to_target_sigset(p, &set);
6204                unlock_user(p, arg1, sizeof(target_sigset_t));
6205            }
6206        }
6207        break;
6208#ifdef TARGET_NR_sigsuspend
6209    case TARGET_NR_sigsuspend:
6210        {
6211            sigset_t set;
6212#if defined(TARGET_ALPHA)
6213            abi_ulong mask = arg1;
6214            target_to_host_old_sigset(&set, &mask);
6215#else
6216            if (!(p = lock_user(VERIFY_READ, arg1, sizeof(target_sigset_t), 1)))
6217                goto efault;
6218            target_to_host_old_sigset(&set, p);
6219            unlock_user(p, arg1, 0);
6220#endif
6221            ret = get_errno(sigsuspend(&set));
6222        }
6223        break;
6224#endif
6225    case TARGET_NR_rt_sigsuspend:
6226        {
6227            sigset_t set;
6228            if (!(p = lock_user(VERIFY_READ, arg1, sizeof(target_sigset_t), 1)))
6229                goto efault;
6230            target_to_host_sigset(&set, p);
6231            unlock_user(p, arg1, 0);
6232            ret = get_errno(sigsuspend(&set));
6233        }
6234        break;
6235    case TARGET_NR_rt_sigtimedwait:
6236        {
6237            sigset_t set;
6238            struct timespec uts, *puts;
6239            siginfo_t uinfo;
6240
6241            if (!(p = lock_user(VERIFY_READ, arg1, sizeof(target_sigset_t), 1)))
6242                goto efault;
6243            target_to_host_sigset(&set, p);
6244            unlock_user(p, arg1, 0);
6245            if (arg3) {
6246                puts = &uts;
6247                target_to_host_timespec(puts, arg3);
6248            } else {
6249                puts = NULL;
6250            }
6251            ret = get_errno(sigtimedwait(&set, &uinfo, puts));
6252            if (!is_error(ret) && arg2) {
6253                if (!(p = lock_user(VERIFY_WRITE, arg2, sizeof(target_siginfo_t), 0)))
6254                    goto efault;
6255                host_to_target_siginfo(p, &uinfo);
6256                unlock_user(p, arg2, sizeof(target_siginfo_t));
6257            }
6258        }
6259        break;
6260    case TARGET_NR_rt_sigqueueinfo:
6261        {
6262            siginfo_t uinfo;
6263            if (!(p = lock_user(VERIFY_READ, arg3, sizeof(target_sigset_t), 1)))
6264                goto efault;
6265            target_to_host_siginfo(&uinfo, p);
6266            unlock_user(p, arg1, 0);
6267            ret = get_errno(sys_rt_sigqueueinfo(arg1, arg2, &uinfo));
6268        }
6269        break;
6270#ifdef TARGET_NR_sigreturn
6271    case TARGET_NR_sigreturn:
6272        /* NOTE: ret is eax, so not transcoding must be done */
6273        ret = do_sigreturn(cpu_env);
6274        break;
6275#endif
6276    case TARGET_NR_rt_sigreturn:
6277        /* NOTE: ret is eax, so not transcoding must be done */
6278        ret = do_rt_sigreturn(cpu_env);
6279        break;
6280    case TARGET_NR_sethostname:
6281        if (!(p = lock_user_string(arg1)))
6282            goto efault;
6283        ret = get_errno(sethostname(p, arg2));
6284        unlock_user(p, arg1, 0);
6285        break;
6286    case TARGET_NR_setrlimit:
6287        {
6288            int resource = target_to_host_resource(arg1);
6289            struct target_rlimit *target_rlim;
6290            struct rlimit rlim;
6291            if (!lock_user_struct(VERIFY_READ, target_rlim, arg2, 1))
6292                goto efault;
6293            rlim.rlim_cur = target_to_host_rlim(target_rlim->rlim_cur);
6294            rlim.rlim_max = target_to_host_rlim(target_rlim->rlim_max);
6295            unlock_user_struct(target_rlim, arg2, 0);
6296            ret = get_errno(setrlimit(resource, &rlim));
6297        }
6298        break;
6299    case TARGET_NR_getrlimit:
6300        {
6301            int resource = target_to_host_resource(arg1);
6302            struct target_rlimit *target_rlim;
6303            struct rlimit rlim;
6304
6305            ret = get_errno(getrlimit(resource, &rlim));
6306            if (!is_error(ret)) {
6307                if (!lock_user_struct(VERIFY_WRITE, target_rlim, arg2, 0))
6308                    goto efault;
6309                target_rlim->rlim_cur = host_to_target_rlim(rlim.rlim_cur);
6310                target_rlim->rlim_max = host_to_target_rlim(rlim.rlim_max);
6311                unlock_user_struct(target_rlim, arg2, 1);
6312            }
6313        }
6314        break;
6315    case TARGET_NR_getrusage:
6316        {
6317            struct rusage rusage;
6318            ret = get_errno(getrusage(arg1, &rusage));
6319            if (!is_error(ret)) {
6320                host_to_target_rusage(arg2, &rusage);
6321            }
6322        }
6323        break;
6324    case TARGET_NR_gettimeofday:
6325        {
6326            struct timeval tv;
6327            ret = get_errno(gettimeofday(&tv, NULL));
6328            if (!is_error(ret)) {
6329                if (copy_to_user_timeval(arg1, &tv))
6330                    goto efault;
6331            }
6332        }
6333        break;
6334    case TARGET_NR_settimeofday:
6335        {
6336            struct timeval tv;
6337            if (copy_from_user_timeval(&tv, arg1))
6338                goto efault;
6339            ret = get_errno(settimeofday(&tv, NULL));
6340        }
6341        break;
6342#if defined(TARGET_NR_select)
6343    case TARGET_NR_select:
6344#if defined(TARGET_S390X) || defined(TARGET_ALPHA)
6345        ret = do_select(arg1, arg2, arg3, arg4, arg5);
6346#else
6347        {
6348            struct target_sel_arg_struct *sel;
6349            abi_ulong inp, outp, exp, tvp;
6350            long nsel;
6351
6352            if (!lock_user_struct(VERIFY_READ, sel, arg1, 1))
6353                goto efault;
6354            nsel = tswapal(sel->n);
6355            inp = tswapal(sel->inp);
6356            outp = tswapal(sel->outp);
6357            exp = tswapal(sel->exp);
6358            tvp = tswapal(sel->tvp);
6359            unlock_user_struct(sel, arg1, 0);
6360            ret = do_select(nsel, inp, outp, exp, tvp);
6361        }
6362#endif
6363        break;
6364#endif
6365#ifdef TARGET_NR_pselect6
6366    case TARGET_NR_pselect6:
6367        {
6368            abi_long rfd_addr, wfd_addr, efd_addr, n, ts_addr;
6369            fd_set rfds, wfds, efds;
6370            fd_set *rfds_ptr, *wfds_ptr, *efds_ptr;
6371            struct timespec ts, *ts_ptr;
6372
6373            /*
6374             * The 6th arg is actually two args smashed together,
6375             * so we cannot use the C library.
6376             */
6377            sigset_t set;
6378            struct {
6379                sigset_t *set;
6380                size_t size;
6381            } sig, *sig_ptr;
6382
6383            abi_ulong arg_sigset, arg_sigsize, *arg7;
6384            target_sigset_t *target_sigset;
6385
6386            n = arg1;
6387            rfd_addr = arg2;
6388            wfd_addr = arg3;
6389            efd_addr = arg4;
6390            ts_addr = arg5;
6391
6392            ret = copy_from_user_fdset_ptr(&rfds, &rfds_ptr, rfd_addr, n);
6393            if (ret) {
6394                goto fail;
6395            }
6396            ret = copy_from_user_fdset_ptr(&wfds, &wfds_ptr, wfd_addr, n);
6397            if (ret) {
6398                goto fail;
6399            }
6400            ret = copy_from_user_fdset_ptr(&efds, &efds_ptr, efd_addr, n);
6401            if (ret) {
6402                goto fail;
6403            }
6404
6405            /*
6406             * This takes a timespec, and not a timeval, so we cannot
6407             * use the do_select() helper ...
6408             */
6409            if (ts_addr) {
6410                if (target_to_host_timespec(&ts, ts_addr)) {
6411                    goto efault;
6412                }
6413                ts_ptr = &ts;
6414            } else {
6415                ts_ptr = NULL;
6416            }
6417
6418            /* Extract the two packed args for the sigset */
6419            if (arg6) {
6420                sig_ptr = &sig;
6421                sig.size = _NSIG / 8;
6422
6423                arg7 = lock_user(VERIFY_READ, arg6, sizeof(*arg7) * 2, 1);
6424                if (!arg7) {
6425                    goto efault;
6426                }
6427                arg_sigset = tswapal(arg7[0]);
6428                arg_sigsize = tswapal(arg7[1]);
6429                unlock_user(arg7, arg6, 0);
6430
6431                if (arg_sigset) {
6432                    sig.set = &set;
6433                    if (arg_sigsize != sizeof(*target_sigset)) {
6434                        /* Like the kernel, we enforce correct size sigsets */
6435                        ret = -TARGET_EINVAL;
6436                        goto fail;
6437                    }
6438                    target_sigset = lock_user(VERIFY_READ, arg_sigset,
6439                                              sizeof(*target_sigset), 1);
6440                    if (!target_sigset) {
6441                        goto efault;
6442                    }
6443                    target_to_host_sigset(&set, target_sigset);
6444                    unlock_user(target_sigset, arg_sigset, 0);
6445                } else {
6446                    sig.set = NULL;
6447                }
6448            } else {
6449                sig_ptr = NULL;
6450            }
6451
6452            ret = get_errno(sys_pselect6(n, rfds_ptr, wfds_ptr, efds_ptr,
6453                                         ts_ptr, sig_ptr));
6454
6455            if (!is_error(ret)) {
6456                if (rfd_addr && copy_to_user_fdset(rfd_addr, &rfds, n))
6457                    goto efault;
6458                if (wfd_addr && copy_to_user_fdset(wfd_addr, &wfds, n))
6459                    goto efault;
6460                if (efd_addr && copy_to_user_fdset(efd_addr, &efds, n))
6461                    goto efault;
6462
6463                if (ts_addr && host_to_target_timespec(ts_addr, &ts))
6464                    goto efault;
6465            }
6466        }
6467        break;
6468#endif
6469    case TARGET_NR_symlink:
6470        {
6471            void *p2;
6472            p = lock_user_string(arg1);
6473            p2 = lock_user_string(arg2);
6474            if (!p || !p2)
6475                ret = -TARGET_EFAULT;
6476            else
6477                ret = get_errno(symlink(p, p2));
6478            unlock_user(p2, arg2, 0);
6479            unlock_user(p, arg1, 0);
6480        }
6481        break;
6482#if defined(TARGET_NR_symlinkat)
6483    case TARGET_NR_symlinkat:
6484        {
6485            void *p2;
6486            p  = lock_user_string(arg1);
6487            p2 = lock_user_string(arg3);
6488            if (!p || !p2)
6489                ret = -TARGET_EFAULT;
6490            else
6491                ret = get_errno(symlinkat(p, arg2, p2));
6492            unlock_user(p2, arg3, 0);
6493            unlock_user(p, arg1, 0);
6494        }
6495        break;
6496#endif
6497#ifdef TARGET_NR_oldlstat
6498    case TARGET_NR_oldlstat:
6499        goto unimplemented;
6500#endif
6501    case TARGET_NR_readlink:
6502        {
6503            void *p2;
6504            p = lock_user_string(arg1);
6505            p2 = lock_user(VERIFY_WRITE, arg2, arg3, 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, arg3, "%s", real);
6513            } else {
6514                ret = get_errno(readlink(path(p), p2, arg3));
6515            }
6516            unlock_user(p2, arg2, ret);
6517            unlock_user(p, arg1, 0);
6518        }
6519        break;
6520#if defined(TARGET_NR_readlinkat)
6521    case TARGET_NR_readlinkat:
6522        {
6523            void *p2;
6524            p  = lock_user_string(arg2);
6525            p2 = lock_user(VERIFY_WRITE, arg3, arg4, 0);
6526            if (!p || !p2) {
6527                ret = -TARGET_EFAULT;
6528            } else if (is_proc_myself((const char *)p, "exe")) {
6529                char real[PATH_MAX], *temp;
6530                temp = realpath(exec_path, real);
6531                ret = temp == NULL ? get_errno(-1) : strlen(real) ;
6532                snprintf((char *)p2, arg4, "%s", real);
6533            } else {
6534                ret = get_errno(readlinkat(arg1, path(p), p2, arg4));
6535            }
6536            unlock_user(p2, arg3, ret);
6537            unlock_user(p, arg2, 0);
6538        }
6539        break;
6540#endif
6541#ifdef TARGET_NR_uselib
6542    case TARGET_NR_uselib:
6543        goto unimplemented;
6544#endif
6545#ifdef TARGET_NR_swapon
6546    case TARGET_NR_swapon:
6547        if (!(p = lock_user_string(arg1)))
6548            goto efault;
6549        ret = get_errno(swapon(p, arg2));
6550        unlock_user(p, arg1, 0);
6551        break;
6552#endif
6553    case TARGET_NR_reboot:
6554        if (arg3 == LINUX_REBOOT_CMD_RESTART2) {
6555           /* arg4 must be ignored in all other cases */
6556           p = lock_user_string(arg4);
6557           if (!p) {
6558              goto efault;
6559           }
6560           ret = get_errno(reboot(arg1, arg2, arg3, p));
6561           unlock_user(p, arg4, 0);
6562        } else {
6563           ret = get_errno(reboot(arg1, arg2, arg3, NULL));
6564        }
6565        break;
6566#ifdef TARGET_NR_readdir
6567    case TARGET_NR_readdir:
6568        goto unimplemented;
6569#endif
6570#ifdef TARGET_NR_mmap
6571    case TARGET_NR_mmap:
6572#if (defined(TARGET_I386) && defined(TARGET_ABI32)) || \
6573    (defined(TARGET_ARM) && defined(TARGET_ABI32)) || \
6574    defined(TARGET_M68K) || defined(TARGET_CRIS) || defined(TARGET_MICROBLAZE) \
6575    || defined(TARGET_S390X)
6576        {
6577            abi_ulong *v;
6578            abi_ulong v1, v2, v3, v4, v5, v6;
6579            if (!(v = lock_user(VERIFY_READ, arg1, 6 * sizeof(abi_ulong), 1)))
6580                goto efault;
6581            v1 = tswapal(v[0]);
6582            v2 = tswapal(v[1]);
6583            v3 = tswapal(v[2]);
6584            v4 = tswapal(v[3]);
6585            v5 = tswapal(v[4]);
6586            v6 = tswapal(v[5]);
6587            unlock_user(v, arg1, 0);
6588            ret = get_errno(target_mmap(v1, v2, v3,
6589                                        target_to_host_bitmask(v4, mmap_flags_tbl),
6590                                        v5, v6));
6591        }
6592#else
6593        ret = get_errno(target_mmap(arg1, arg2, arg3,
6594                                    target_to_host_bitmask(arg4, mmap_flags_tbl),
6595                                    arg5,
6596                                    arg6));
6597#endif
6598        break;
6599#endif
6600#ifdef TARGET_NR_mmap2
6601    case TARGET_NR_mmap2:
6602#ifndef MMAP_SHIFT
6603#define MMAP_SHIFT 12
6604#endif
6605        ret = get_errno(target_mmap(arg1, arg2, arg3,
6606                                    target_to_host_bitmask(arg4, mmap_flags_tbl),
6607                                    arg5,
6608                                    arg6 << MMAP_SHIFT));
6609        break;
6610#endif
6611    case TARGET_NR_munmap:
6612        ret = get_errno(target_munmap(arg1, arg2));
6613        break;
6614    case TARGET_NR_mprotect:
6615        {
6616            TaskState *ts = ((CPUArchState *)cpu_env)->opaque;
6617            /* Special hack to detect libc making the stack executable.  */
6618            if ((arg3 & PROT_GROWSDOWN)
6619                && arg1 >= ts->info->stack_limit
6620                && arg1 <= ts->info->start_stack) {
6621                arg3 &= ~PROT_GROWSDOWN;
6622                arg2 = arg2 + arg1 - ts->info->stack_limit;
6623                arg1 = ts->info->stack_limit;
6624            }
6625        }
6626        ret = get_errno(target_mprotect(arg1, arg2, arg3));
6627        break;
6628#ifdef TARGET_NR_mremap
6629    case TARGET_NR_mremap:
6630        ret = get_errno(target_mremap(arg1, arg2, arg3, arg4, arg5));
6631        break;
6632#endif
6633        /* ??? msync/mlock/munlock are broken for softmmu.  */
6634#ifdef TARGET_NR_msync
6635    case TARGET_NR_msync:
6636        ret = get_errno(msync(g2h(arg1), arg2, arg3));
6637        break;
6638#endif
6639#ifdef TARGET_NR_mlock
6640    case TARGET_NR_mlock:
6641        ret = get_errno(mlock(g2h(arg1), arg2));
6642        break;
6643#endif
6644#ifdef TARGET_NR_munlock
6645    case TARGET_NR_munlock:
6646        ret = get_errno(munlock(g2h(arg1), arg2));
6647        break;
6648#endif
6649#ifdef TARGET_NR_mlockall
6650    case TARGET_NR_mlockall:
6651        ret = get_errno(mlockall(arg1));
6652        break;
6653#endif
6654#ifdef TARGET_NR_munlockall
6655    case TARGET_NR_munlockall:
6656        ret = get_errno(munlockall());
6657        break;
6658#endif
6659    case TARGET_NR_truncate:
6660        if (!(p = lock_user_string(arg1)))
6661            goto efault;
6662        ret = get_errno(truncate(p, arg2));
6663        unlock_user(p, arg1, 0);
6664        break;
6665    case TARGET_NR_ftruncate:
6666        ret = get_errno(ftruncate(arg1, arg2));
6667        break;
6668    case TARGET_NR_fchmod:
6669        ret = get_errno(fchmod(arg1, arg2));
6670        break;
6671#if defined(TARGET_NR_fchmodat)
6672    case TARGET_NR_fchmodat:
6673        if (!(p = lock_user_string(arg2)))
6674            goto efault;
6675        ret = get_errno(fchmodat(arg1, p, arg3, 0));
6676        unlock_user(p, arg2, 0);
6677        break;
6678#endif
6679    case TARGET_NR_getpriority:
6680        /* Note that negative values are valid for getpriority, so we must
6681           differentiate based on errno settings.  */
6682        errno = 0;
6683        ret = getpriority(arg1, arg2);
6684        if (ret == -1 && errno != 0) {
6685            ret = -host_to_target_errno(errno);
6686            break;
6687        }
6688#ifdef TARGET_ALPHA
6689        /* Return value is the unbiased priority.  Signal no error.  */
6690        ((CPUAlphaState *)cpu_env)->ir[IR_V0] = 0;
6691#else
6692        /* Return value is a biased priority to avoid negative numbers.  */
6693        ret = 20 - ret;
6694#endif
6695        break;
6696    case TARGET_NR_setpriority:
6697        ret = get_errno(setpriority(arg1, arg2, arg3));
6698        break;
6699#ifdef TARGET_NR_profil
6700    case TARGET_NR_profil:
6701        goto unimplemented;
6702#endif
6703    case TARGET_NR_statfs:
6704        if (!(p = lock_user_string(arg1)))
6705            goto efault;
6706        ret = get_errno(statfs(path(p), &stfs));
6707        unlock_user(p, arg1, 0);
6708    convert_statfs:
6709        if (!is_error(ret)) {
6710            struct target_statfs *target_stfs;
6711
6712            if (!lock_user_struct(VERIFY_WRITE, target_stfs, arg2, 0))
6713                goto efault;
6714            __put_user(stfs.f_type, &target_stfs->f_type);
6715            __put_user(stfs.f_bsize, &target_stfs->f_bsize);
6716            __put_user(stfs.f_blocks, &target_stfs->f_blocks);
6717            __put_user(stfs.f_bfree, &target_stfs->f_bfree);
6718            __put_user(stfs.f_bavail, &target_stfs->f_bavail);
6719            __put_user(stfs.f_files, &target_stfs->f_files);
6720            __put_user(stfs.f_ffree, &target_stfs->f_ffree);
6721            __put_user(stfs.f_fsid.__val[0], &target_stfs->f_fsid.val[0]);
6722            __put_user(stfs.f_fsid.__val[1], &target_stfs->f_fsid.val[1]);
6723            __put_user(stfs.f_namelen, &target_stfs->f_namelen);
6724            __put_user(stfs.f_frsize, &target_stfs->f_frsize);
6725            memset(target_stfs->f_spare, 0, sizeof(target_stfs->f_spare));
6726            unlock_user_struct(target_stfs, arg2, 1);
6727        }
6728        break;
6729    case TARGET_NR_fstatfs:
6730        ret = get_errno(fstatfs(arg1, &stfs));
6731        goto convert_statfs;
6732#ifdef TARGET_NR_statfs64
6733    case TARGET_NR_statfs64:
6734        if (!(p = lock_user_string(arg1)))
6735            goto efault;
6736        ret = get_errno(statfs(path(p), &stfs));
6737        unlock_user(p, arg1, 0);
6738    convert_statfs64:
6739        if (!is_error(ret)) {
6740            struct target_statfs64 *target_stfs;
6741
6742            if (!lock_user_struct(VERIFY_WRITE, target_stfs, arg3, 0))
6743                goto efault;
6744            __put_user(stfs.f_type, &target_stfs->f_type);
6745            __put_user(stfs.f_bsize, &target_stfs->f_bsize);
6746            __put_user(stfs.f_blocks, &target_stfs->f_blocks);
6747            __put_user(stfs.f_bfree, &target_stfs->f_bfree);
6748            __put_user(stfs.f_bavail, &target_stfs->f_bavail);
6749            __put_user(stfs.f_files, &target_stfs->f_files);
6750            __put_user(stfs.f_ffree, &target_stfs->f_ffree);
6751            __put_user(stfs.f_fsid.__val[0], &target_stfs->f_fsid.val[0]);
6752            __put_user(stfs.f_fsid.__val[1], &target_stfs->f_fsid.val[1]);
6753            __put_user(stfs.f_namelen, &target_stfs->f_namelen);
6754            __put_user(stfs.f_frsize, &target_stfs->f_frsize);
6755            memset(target_stfs->f_spare, 0, sizeof(target_stfs->f_spare));
6756            unlock_user_struct(target_stfs, arg3, 1);
6757        }
6758        break;
6759    case TARGET_NR_fstatfs64:
6760        ret = get_errno(fstatfs(arg1, &stfs));
6761        goto convert_statfs64;
6762#endif
6763#ifdef TARGET_NR_ioperm
6764    case TARGET_NR_ioperm:
6765        goto unimplemented;
6766#endif
6767#ifdef TARGET_NR_socketcall
6768    case TARGET_NR_socketcall:
6769        ret = do_socketcall(arg1, arg2);
6770        break;
6771#endif
6772#ifdef TARGET_NR_accept
6773    case TARGET_NR_accept:
6774        ret = do_accept4(arg1, arg2, arg3, 0);
6775        break;
6776#endif
6777#ifdef TARGET_NR_accept4
6778    case TARGET_NR_accept4:
6779#ifdef CONFIG_ACCEPT4
6780        ret = do_accept4(arg1, arg2, arg3, arg4);
6781#else
6782        goto unimplemented;
6783#endif
6784        break;
6785#endif
6786#ifdef TARGET_NR_bind
6787    case TARGET_NR_bind:
6788        ret = do_bind(arg1, arg2, arg3);
6789        break;
6790#endif
6791#ifdef TARGET_NR_connect
6792    case TARGET_NR_connect:
6793        ret = do_connect(arg1, arg2, arg3);
6794        break;
6795#endif
6796#ifdef TARGET_NR_getpeername
6797    case TARGET_NR_getpeername:
6798        ret = do_getpeername(arg1, arg2, arg3);
6799        break;
6800#endif
6801#ifdef TARGET_NR_getsockname
6802    case TARGET_NR_getsockname:
6803        ret = do_getsockname(arg1, arg2, arg3);
6804        break;
6805#endif
6806#ifdef TARGET_NR_getsockopt
6807    case TARGET_NR_getsockopt:
6808        ret = do_getsockopt(arg1, arg2, arg3, arg4, arg5);
6809        break;
6810#endif
6811#ifdef TARGET_NR_listen
6812    case TARGET_NR_listen:
6813        ret = get_errno(listen(arg1, arg2));
6814        break;
6815#endif
6816#ifdef TARGET_NR_recv
6817    case TARGET_NR_recv:
6818        ret = do_recvfrom(arg1, arg2, arg3, arg4, 0, 0);
6819        break;
6820#endif
6821#ifdef TARGET_NR_recvfrom
6822    case TARGET_NR_recvfrom:
6823        ret = do_recvfrom(arg1, arg2, arg3, arg4, arg5, arg6);
6824        break;
6825#endif
6826#ifdef TARGET_NR_recvmsg
6827    case TARGET_NR_recvmsg:
6828        ret = do_sendrecvmsg(arg1, arg2, arg3, 0);
6829        break;
6830#endif
6831#ifdef TARGET_NR_send
6832    case TARGET_NR_send:
6833        ret = do_sendto(arg1, arg2, arg3, arg4, 0, 0);
6834        break;
6835#endif
6836#ifdef TARGET_NR_sendmsg
6837    case TARGET_NR_sendmsg:
6838        ret = do_sendrecvmsg(arg1, arg2, arg3, 1);
6839        break;
6840#endif
6841#ifdef TARGET_NR_sendto
6842    case TARGET_NR_sendto:
6843        ret = do_sendto(arg1, arg2, arg3, arg4, arg5, arg6);
6844        break;
6845#endif
6846#ifdef TARGET_NR_shutdown
6847    case TARGET_NR_shutdown:
6848        ret = get_errno(shutdown(arg1, arg2));
6849        break;
6850#endif
6851#ifdef TARGET_NR_socket
6852    case TARGET_NR_socket:
6853        ret = do_socket(arg1, arg2, arg3);
6854        break;
6855#endif
6856#ifdef TARGET_NR_socketpair
6857    case TARGET_NR_socketpair:
6858        ret = do_socketpair(arg1, arg2, arg3, arg4);
6859        break;
6860#endif
6861#ifdef TARGET_NR_setsockopt
6862    case TARGET_NR_setsockopt:
6863        ret = do_setsockopt(arg1, arg2, arg3, arg4, (socklen_t) arg5);
6864        break;
6865#endif
6866
6867    case TARGET_NR_syslog:
6868        if (!(p = lock_user_string(arg2)))
6869            goto efault;
6870        ret = get_errno(sys_syslog((int)arg1, p, (int)arg3));
6871        unlock_user(p, arg2, 0);
6872        break;
6873
6874    case TARGET_NR_setitimer:
6875        {
6876            struct itimerval value, ovalue, *pvalue;
6877
6878            if (arg2) {
6879                pvalue = &value;
6880                if (copy_from_user_timeval(&pvalue->it_interval, arg2)
6881                    || copy_from_user_timeval(&pvalue->it_value,
6882                                              arg2 + sizeof(struct target_timeval)))
6883                    goto efault;
6884            } else {
6885                pvalue = NULL;
6886            }
6887            ret = get_errno(setitimer(arg1, pvalue, &ovalue));
6888            if (!is_error(ret) && arg3) {
6889                if (copy_to_user_timeval(arg3,
6890                                         &ovalue.it_interval)
6891                    || copy_to_user_timeval(arg3 + sizeof(struct target_timeval),
6892                                            &ovalue.it_value))
6893                    goto efault;
6894            }
6895        }
6896        break;
6897    case TARGET_NR_getitimer:
6898        {
6899            struct itimerval value;
6900
6901            ret = get_errno(getitimer(arg1, &value));
6902            if (!is_error(ret) && arg2) {
6903                if (copy_to_user_timeval(arg2,
6904                                         &value.it_interval)
6905                    || copy_to_user_timeval(arg2 + sizeof(struct target_timeval),
6906                                            &value.it_value))
6907                    goto efault;
6908            }
6909        }
6910        break;
6911    case TARGET_NR_stat:
6912        if (!(p = lock_user_string(arg1)))
6913            goto efault;
6914        ret = get_errno(stat(path(p), &st));
6915        unlock_user(p, arg1, 0);
6916        goto do_stat;
6917    case TARGET_NR_lstat:
6918        if (!(p = lock_user_string(arg1)))
6919            goto efault;
6920        ret = get_errno(lstat(path(p), &st));
6921        unlock_user(p, arg1, 0);
6922        goto do_stat;
6923    case TARGET_NR_fstat:
6924        {
6925            ret = get_errno(fstat(arg1, &st));
6926        do_stat:
6927            if (!is_error(ret)) {
6928                struct target_stat *target_st;
6929
6930                if (!lock_user_struct(VERIFY_WRITE, target_st, arg2, 0))
6931                    goto efault;
6932                memset(target_st, 0, sizeof(*target_st));
6933                __put_user(st.st_dev, &target_st->st_dev);
6934                __put_user(st.st_ino, &target_st->st_ino);
6935                __put_user(st.st_mode, &target_st->st_mode);
6936                __put_user(st.st_uid, &target_st->st_uid);
6937                __put_user(st.st_gid, &target_st->st_gid);
6938                __put_user(st.st_nlink, &target_st->st_nlink);
6939                __put_user(st.st_rdev, &target_st->st_rdev);
6940                __put_user(st.st_size, &target_st->st_size);
6941                __put_user(st.st_blksize, &target_st->st_blksize);
6942                __put_user(st.st_blocks, &target_st->st_blocks);
6943                __put_user(st.st_atime, &target_st->target_st_atime);
6944                __put_user(st.st_mtime, &target_st->target_st_mtime);
6945                __put_user(st.st_ctime, &target_st->target_st_ctime);
6946                unlock_user_struct(target_st, arg2, 1);
6947            }
6948        }
6949        break;
6950#ifdef TARGET_NR_olduname
6951    case TARGET_NR_olduname:
6952        goto unimplemented;
6953#endif
6954#ifdef TARGET_NR_iopl
6955    case TARGET_NR_iopl:
6956        goto unimplemented;
6957#endif
6958    case TARGET_NR_vhangup:
6959        ret = get_errno(vhangup());
6960        break;
6961#ifdef TARGET_NR_idle
6962    case TARGET_NR_idle:
6963        goto unimplemented;
6964#endif
6965#ifdef TARGET_NR_syscall
6966    case TARGET_NR_syscall:
6967        ret = do_syscall(cpu_env, arg1 & 0xffff, arg2, arg3, arg4, arg5,
6968                         arg6, arg7, arg8, 0);
6969        break;
6970#endif
6971    case TARGET_NR_wait4:
6972        {
6973            int status;
6974            abi_long status_ptr = arg2;
6975            struct rusage rusage, *rusage_ptr;
6976            abi_ulong target_rusage = arg4;
6977            if (target_rusage)
6978                rusage_ptr = &rusage;
6979            else
6980                rusage_ptr = NULL;
6981            ret = get_errno(wait4(arg1, &status, arg3, rusage_ptr));
6982            if (!is_error(ret)) {
6983                if (status_ptr && ret) {
6984                    status = host_to_target_waitstatus(status);
6985                    if (put_user_s32(status, status_ptr))
6986                        goto efault;
6987                }
6988                if (target_rusage)
6989                    host_to_target_rusage(target_rusage, &rusage);
6990            }
6991        }
6992        break;
6993#ifdef TARGET_NR_swapoff
6994    case TARGET_NR_swapoff:
6995        if (!(p = lock_user_string(arg1)))
6996            goto efault;
6997        ret = get_errno(swapoff(p));
6998        unlock_user(p, arg1, 0);
6999        break;
7000#endif
7001    case TARGET_NR_sysinfo:
7002        {
7003            struct target_sysinfo *target_value;
7004            struct sysinfo value;
7005            ret = get_errno(sysinfo(&value));
7006            if (!is_error(ret) && arg1)
7007            {
7008                if (!lock_user_struct(VERIFY_WRITE, target_value, arg1, 0))
7009                    goto efault;
7010                __put_user(value.uptime, &target_value->uptime);
7011                __put_user(value.loads[0], &target_value->loads[0]);
7012                __put_user(value.loads[1], &target_value->loads[1]);
7013                __put_user(value.loads[2], &target_value->loads[2]);
7014                __put_user(value.totalram, &target_value->totalram);
7015                __put_user(value.freeram, &target_value->freeram);
7016                __put_user(value.sharedram, &target_value->sharedram);
7017                __put_user(value.bufferram, &target_value->bufferram);
7018                __put_user(value.totalswap, &target_value->totalswap);
7019                __put_user(value.freeswap, &target_value->freeswap);
7020                __put_user(value.procs, &target_value->procs);
7021                __put_user(value.totalhigh, &target_value->totalhigh);
7022                __put_user(value.freehigh, &target_value->freehigh);
7023                __put_user(value.mem_unit, &target_value->mem_unit);
7024                unlock_user_struct(target_value, arg1, 1);
7025            }
7026        }
7027        break;
7028#ifdef TARGET_NR_ipc
7029    case TARGET_NR_ipc:
7030        ret = do_ipc(arg1, arg2, arg3, arg4, arg5, arg6);
7031        break;
7032#endif
7033#ifdef TARGET_NR_semget
7034    case TARGET_NR_semget:
7035        ret = get_errno(semget(arg1, arg2, arg3));
7036        break;
7037#endif
7038#ifdef TARGET_NR_semop
7039    case TARGET_NR_semop:
7040        ret = do_semop(arg1, arg2, arg3);
7041        break;
7042#endif
7043#ifdef TARGET_NR_semctl
7044    case TARGET_NR_semctl:
7045        ret = do_semctl(arg1, arg2, arg3, (union target_semun)(abi_ulong)arg4);
7046        break;
7047#endif
7048#ifdef TARGET_NR_msgctl
7049    case TARGET_NR_msgctl:
7050        ret = do_msgctl(arg1, arg2, arg3);
7051        break;
7052#endif
7053#ifdef TARGET_NR_msgget
7054    case TARGET_NR_msgget:
7055        ret = get_errno(msgget(arg1, arg2));
7056        break;
7057#endif
7058#ifdef TARGET_NR_msgrcv
7059    case TARGET_NR_msgrcv:
7060        ret = do_msgrcv(arg1, arg2, arg3, arg4, arg5);
7061        break;
7062#endif
7063#ifdef TARGET_NR_msgsnd
7064    case TARGET_NR_msgsnd:
7065        ret = do_msgsnd(arg1, arg2, arg3, arg4);
7066        break;
7067#endif
7068#ifdef TARGET_NR_shmget
7069    case TARGET_NR_shmget:
7070        ret = get_errno(shmget(arg1, arg2, arg3));
7071        break;
7072#endif
7073#ifdef TARGET_NR_shmctl
7074    case TARGET_NR_shmctl:
7075        ret = do_shmctl(arg1, arg2, arg3);
7076        break;
7077#endif
7078#ifdef TARGET_NR_shmat
7079    case TARGET_NR_shmat:
7080        ret = do_shmat(arg1, arg2, arg3);
7081        break;
7082#endif
7083#ifdef TARGET_NR_shmdt
7084    case TARGET_NR_shmdt:
7085        ret = do_shmdt(arg1);
7086        break;
7087#endif
7088    case TARGET_NR_fsync:
7089        ret = get_errno(fsync(arg1));
7090        break;
7091    case TARGET_NR_clone:
7092        /* Linux manages to have three different orderings for its
7093         * arguments to clone(); the BACKWARDS and BACKWARDS2 defines
7094         * match the kernel's CONFIG_CLONE_* settings.
7095         * Microblaze is further special in that it uses a sixth
7096         * implicit argument to clone for the TLS pointer.
7097         */
7098#if defined(TARGET_MICROBLAZE)
7099        ret = get_errno(do_fork(cpu_env, arg1, arg2, arg4, arg6, arg5));
7100#elif defined(TARGET_CLONE_BACKWARDS)
7101        ret = get_errno(do_fork(cpu_env, arg1, arg2, arg3, arg4, arg5));
7102#elif defined(TARGET_CLONE_BACKWARDS2)
7103        ret = get_errno(do_fork(cpu_env, arg2, arg1, arg3, arg5, arg4));
7104#else
7105        ret = get_errno(do_fork(cpu_env, arg1, arg2, arg3, arg5, arg4));
7106#endif
7107        break;
7108#ifdef __NR_exit_group
7109        /* new thread calls */
7110    case TARGET_NR_exit_group:
7111#ifdef TARGET_GPROF
7112        _mcleanup();
7113#endif
7114        gdb_exit(cpu_env, arg1);
7115        ret = get_errno(exit_group(arg1));
7116        break;
7117#endif
7118    case TARGET_NR_setdomainname:
7119        if (!(p = lock_user_string(arg1)))
7120            goto efault;
7121        ret = get_errno(setdomainname(p, arg2));
7122        unlock_user(p, arg1, 0);
7123        break;
7124    case TARGET_NR_uname:
7125        /* no need to transcode because we use the linux syscall */
7126        {
7127            struct new_utsname * buf;
7128
7129            if (!lock_user_struct(VERIFY_WRITE, buf, arg1, 0))
7130                goto efault;
7131            ret = get_errno(sys_uname(buf));
7132            if (!is_error(ret)) {
7133                /* Overrite the native machine name with whatever is being
7134                   emulated. */
7135                strcpy (buf->machine, cpu_to_uname_machine(cpu_env));
7136                /* Allow the user to override the reported release.  */
7137                if (qemu_uname_release && *qemu_uname_release)
7138                  strcpy (buf->release, qemu_uname_release);
7139            }
7140            unlock_user_struct(buf, arg1, 1);
7141        }
7142        break;
7143#ifdef TARGET_I386
7144    case TARGET_NR_modify_ldt:
7145        ret = do_modify_ldt(cpu_env, arg1, arg2, arg3);
7146        break;
7147#if !defined(TARGET_X86_64)
7148    case TARGET_NR_vm86old:
7149        goto unimplemented;
7150    case TARGET_NR_vm86:
7151        ret = do_vm86(cpu_env, arg1, arg2);
7152        break;
7153#endif
7154#endif
7155    case TARGET_NR_adjtimex:
7156        goto unimplemented;
7157#ifdef TARGET_NR_create_module
7158    case TARGET_NR_create_module:
7159#endif
7160    case TARGET_NR_init_module:
7161    case TARGET_NR_delete_module:
7162#ifdef TARGET_NR_get_kernel_syms
7163    case TARGET_NR_get_kernel_syms:
7164#endif
7165        goto unimplemented;
7166    case TARGET_NR_quotactl:
7167        goto unimplemented;
7168    case TARGET_NR_getpgid:
7169        ret = get_errno(getpgid(arg1));
7170        break;
7171    case TARGET_NR_fchdir:
7172        ret = get_errno(fchdir(arg1));
7173        break;
7174#ifdef TARGET_NR_bdflush /* not on x86_64 */
7175    case TARGET_NR_bdflush:
7176        goto unimplemented;
7177#endif
7178#ifdef TARGET_NR_sysfs
7179    case TARGET_NR_sysfs:
7180        goto unimplemented;
7181#endif
7182    case TARGET_NR_personality:
7183        ret = get_errno(personality(arg1));
7184        break;
7185#ifdef TARGET_NR_afs_syscall
7186    case TARGET_NR_afs_syscall:
7187        goto unimplemented;
7188#endif
7189#ifdef TARGET_NR__llseek /* Not on alpha */
7190    case TARGET_NR__llseek:
7191        {
7192            int64_t res;
7193#if !defined(__NR_llseek)
7194            res = lseek(arg1, ((uint64_t)arg2 << 32) | arg3, arg5);
7195            if (res == -1) {
7196                ret = get_errno(res);
7197            } else {
7198                ret = 0;
7199            }
7200#else
7201            ret = get_errno(_llseek(arg1, arg2, arg3, &res, arg5));
7202#endif
7203            if ((ret == 0) && put_user_s64(res, arg4)) {
7204                goto efault;
7205            }
7206        }
7207        break;
7208#endif
7209    case TARGET_NR_getdents:
7210#ifdef __NR_getdents
7211#if TARGET_ABI_BITS == 32 && HOST_LONG_BITS == 64
7212        {
7213            struct target_dirent *target_dirp;
7214            struct linux_dirent *dirp;
7215            abi_long count = arg3;
7216
7217            dirp = malloc(count);
7218            if (!dirp) {
7219                ret = -TARGET_ENOMEM;
7220                goto fail;
7221            }
7222
7223            ret = get_errno(sys_getdents(arg1, dirp, count));
7224            if (!is_error(ret)) {
7225                struct linux_dirent *de;
7226                struct target_dirent *tde;
7227                int len = ret;
7228                int reclen, treclen;
7229                int count1, tnamelen;
7230
7231                count1 = 0;
7232                de = dirp;
7233                if (!(target_dirp = lock_user(VERIFY_WRITE, arg2, count, 0)))
7234                    goto efault;
7235                tde = target_dirp;
7236                while (len > 0) {
7237                    reclen = de->d_reclen;
7238                    tnamelen = reclen - offsetof(struct linux_dirent, d_name);
7239                    assert(tnamelen >= 0);
7240                    treclen = tnamelen + offsetof(struct target_dirent, d_name);
7241                    assert(count1 + treclen <= count);
7242                    tde->d_reclen = tswap16(treclen);
7243                    tde->d_ino = tswapal(de->d_ino);
7244                    tde->d_off = tswapal(de->d_off);
7245                    memcpy(tde->d_name, de->d_name, tnamelen);
7246                    de = (struct linux_dirent *)((char *)de + reclen);
7247                    len -= reclen;
7248                    tde = (struct target_dirent *)((char *)tde + treclen);
7249                    count1 += treclen;
7250                }
7251                ret = count1;
7252                unlock_user(target_dirp, arg2, ret);
7253            }
7254            free(dirp);
7255        }
7256#else
7257        {
7258            struct linux_dirent *dirp;
7259            abi_long count = arg3;
7260
7261            if (!(dirp = lock_user(VERIFY_WRITE, arg2, count, 0)))
7262                goto efault;
7263            ret = get_errno(sys_getdents(arg1, dirp, count));
7264            if (!is_error(ret)) {
7265                struct linux_dirent *de;
7266                int len = ret;
7267                int reclen;
7268                de = dirp;
7269                while (len > 0) {
7270                    reclen = de->d_reclen;
7271                    if (reclen > len)
7272                        break;
7273                    de->d_reclen = tswap16(reclen);
7274                    tswapls(&de->d_ino);
7275                    tswapls(&de->d_off);
7276                    de = (struct linux_dirent *)((char *)de + reclen);
7277                    len -= reclen;
7278                }
7279            }
7280            unlock_user(dirp, arg2, ret);
7281        }
7282#endif
7283#else
7284        /* Implement getdents in terms of getdents64 */
7285        {
7286            struct linux_dirent64 *dirp;
7287            abi_long count = arg3;
7288
7289            dirp = lock_user(VERIFY_WRITE, arg2, count, 0);
7290            if (!dirp) {
7291                goto efault;
7292            }
7293            ret = get_errno(sys_getdents64(arg1, dirp, count));
7294            if (!is_error(ret)) {
7295                /* Convert the dirent64 structs to target dirent.  We do this
7296                 * in-place, since we can guarantee that a target_dirent is no
7297                 * larger than a dirent64; however this means we have to be
7298                 * careful to read everything before writing in the new format.
7299                 */
7300                struct linux_dirent64 *de;
7301                struct target_dirent *tde;
7302                int len = ret;
7303                int tlen = 0;
7304
7305                de = dirp;
7306                tde = (struct target_dirent *)dirp;
7307                while (len > 0) {
7308                    int namelen, treclen;
7309                    int reclen = de->d_reclen;
7310                    uint64_t ino = de->d_ino;
7311                    int64_t off = de->d_off;
7312                    uint8_t type = de->d_type;
7313
7314                    namelen = strlen(de->d_name);
7315                    treclen = offsetof(struct target_dirent, d_name)
7316                        + namelen + 2;
7317                    treclen = QEMU_ALIGN_UP(treclen, sizeof(abi_long));
7318
7319                    memmove(tde->d_name, de->d_name, namelen + 1);
7320                    tde->d_ino = tswapal(ino);
7321                    tde->d_off = tswapal(off);
7322                    tde->d_reclen = tswap16(treclen);
7323                    /* The target_dirent type is in what was formerly a padding
7324                     * byte at the end of the structure:
7325                     */
7326                    *(((char *)tde) + treclen - 1) = type;
7327
7328                    de = (struct linux_dirent64 *)((char *)de + reclen);
7329                    tde = (struct target_dirent *)((char *)tde + treclen);
7330                    len -= reclen;
7331                    tlen += treclen;
7332                }
7333                ret = tlen;
7334            }
7335            unlock_user(dirp, arg2, ret);
7336        }
7337#endif
7338        break;
7339#if defined(TARGET_NR_getdents64) && defined(__NR_getdents64)
7340    case TARGET_NR_getdents64:
7341        {
7342            struct linux_dirent64 *dirp;
7343            abi_long count = arg3;
7344            if (!(dirp = lock_user(VERIFY_WRITE, arg2, count, 0)))
7345                goto efault;
7346            ret = get_errno(sys_getdents64(arg1, dirp, count));
7347            if (!is_error(ret)) {
7348                struct linux_dirent64 *de;
7349                int len = ret;
7350                int reclen;
7351                de = dirp;
7352                while (len > 0) {
7353                    reclen = de->d_reclen;
7354                    if (reclen > len)
7355                        break;
7356                    de->d_reclen = tswap16(reclen);
7357                    tswap64s((uint64_t *)&de->d_ino);
7358                    tswap64s((uint64_t *)&de->d_off);
7359                    de = (struct linux_dirent64 *)((char *)de + reclen);
7360                    len -= reclen;
7361                }
7362            }
7363            unlock_user(dirp, arg2, ret);
7364        }
7365        break;
7366#endif /* TARGET_NR_getdents64 */
7367#if defined(TARGET_NR__newselect)
7368    case TARGET_NR__newselect:
7369        ret = do_select(arg1, arg2, arg3, arg4, arg5);
7370        break;
7371#endif
7372#if defined(TARGET_NR_poll) || defined(TARGET_NR_ppoll)
7373# ifdef TARGET_NR_poll
7374    case TARGET_NR_poll:
7375# endif
7376# ifdef TARGET_NR_ppoll
7377    case TARGET_NR_ppoll:
7378# endif
7379        {
7380            struct target_pollfd *target_pfd;
7381            unsigned int nfds = arg2;
7382            int timeout = arg3;
7383            struct pollfd *pfd;
7384            unsigned int i;
7385
7386            target_pfd = lock_user(VERIFY_WRITE, arg1, sizeof(struct target_pollfd) * nfds, 1);
7387            if (!target_pfd)
7388                goto efault;
7389
7390            pfd = alloca(sizeof(struct pollfd) * nfds);
7391            for(i = 0; i < nfds; i++) {
7392                pfd[i].fd = tswap32(target_pfd[i].fd);
7393                pfd[i].events = tswap16(target_pfd[i].events);
7394            }
7395
7396# ifdef TARGET_NR_ppoll
7397            if (num == TARGET_NR_ppoll) {
7398                struct timespec _timeout_ts, *timeout_ts = &_timeout_ts;
7399                target_sigset_t *target_set;
7400                sigset_t _set, *set = &_set;
7401
7402                if (arg3) {
7403                    if (target_to_host_timespec(timeout_ts, arg3)) {
7404                        unlock_user(target_pfd, arg1, 0);
7405                        goto efault;
7406                    }
7407                } else {
7408                    timeout_ts = NULL;
7409                }
7410
7411                if (arg4) {
7412                    target_set = lock_user(VERIFY_READ, arg4, sizeof(target_sigset_t), 1);
7413                    if (!target_set) {
7414                        unlock_user(target_pfd, arg1, 0);
7415                        goto efault;
7416                    }
7417                    target_to_host_sigset(set, target_set);
7418                } else {
7419                    set = NULL;
7420                }
7421
7422                ret = get_errno(sys_ppoll(pfd, nfds, timeout_ts, set, _NSIG/8));
7423
7424                if (!is_error(ret) && arg3) {
7425                    host_to_target_timespec(arg3, timeout_ts);
7426                }
7427                if (arg4) {
7428                    unlock_user(target_set, arg4, 0);
7429                }
7430            } else
7431# endif
7432                ret = get_errno(poll(pfd, nfds, timeout));
7433
7434            if (!is_error(ret)) {
7435                for(i = 0; i < nfds; i++) {
7436                    target_pfd[i].revents = tswap16(pfd[i].revents);
7437                }
7438            }
7439            unlock_user(target_pfd, arg1, sizeof(struct target_pollfd) * nfds);
7440        }
7441        break;
7442#endif
7443    case TARGET_NR_flock:
7444        /* NOTE: the flock constant seems to be the same for every
7445           Linux platform */
7446        ret = get_errno(flock(arg1, arg2));
7447        break;
7448    case TARGET_NR_readv:
7449        {
7450            struct iovec *vec = lock_iovec(VERIFY_WRITE, arg2, arg3, 0);
7451            if (vec != NULL) {
7452                ret = get_errno(readv(arg1, vec, arg3));
7453                unlock_iovec(vec, arg2, arg3, 1);
7454            } else {
7455                ret = -host_to_target_errno(errno);
7456            }
7457        }
7458        break;
7459    case TARGET_NR_writev:
7460        {
7461            struct iovec *vec = lock_iovec(VERIFY_READ, arg2, arg3, 1);
7462            if (vec != NULL) {
7463                ret = get_errno(writev(arg1, vec, arg3));
7464                unlock_iovec(vec, arg2, arg3, 0);
7465            } else {
7466                ret = -host_to_target_errno(errno);
7467            }
7468        }
7469        break;
7470    case TARGET_NR_getsid:
7471        ret = get_errno(getsid(arg1));
7472        break;
7473#if defined(TARGET_NR_fdatasync) /* Not on alpha (osf_datasync ?) */
7474    case TARGET_NR_fdatasync:
7475        ret = get_errno(fdatasync(arg1));
7476        break;
7477#endif
7478    case TARGET_NR__sysctl:
7479        /* We don't implement this, but ENOTDIR is always a safe
7480           return value. */
7481        ret = -TARGET_ENOTDIR;
7482        break;
7483    case TARGET_NR_sched_getaffinity:
7484        {
7485            unsigned int mask_size;
7486            unsigned long *mask;
7487
7488            /*
7489             * sched_getaffinity needs multiples of ulong, so need to take
7490             * care of mismatches between target ulong and host ulong sizes.
7491             */
7492            if (arg2 & (sizeof(abi_ulong) - 1)) {
7493                ret = -TARGET_EINVAL;
7494                break;
7495            }
7496            mask_size = (arg2 + (sizeof(*mask) - 1)) & ~(sizeof(*mask) - 1);
7497
7498            mask = alloca(mask_size);
7499            ret = get_errno(sys_sched_getaffinity(arg1, mask_size, mask));
7500
7501            if (!is_error(ret)) {
7502                if (copy_to_user(arg3, mask, ret)) {
7503                    goto efault;
7504                }
7505            }
7506        }
7507        break;
7508    case TARGET_NR_sched_setaffinity:
7509        {
7510            unsigned int mask_size;
7511            unsigned long *mask;
7512
7513            /*
7514             * sched_setaffinity needs multiples of ulong, so need to take
7515             * care of mismatches between target ulong and host ulong sizes.
7516             */
7517            if (arg2 & (sizeof(abi_ulong) - 1)) {
7518                ret = -TARGET_EINVAL;
7519                break;
7520            }
7521            mask_size = (arg2 + (sizeof(*mask) - 1)) & ~(sizeof(*mask) - 1);
7522
7523            mask = alloca(mask_size);
7524            if (!lock_user_struct(VERIFY_READ, p, arg3, 1)) {
7525                goto efault;
7526            }
7527            memcpy(mask, p, arg2);
7528            unlock_user_struct(p, arg2, 0);
7529
7530            ret = get_errno(sys_sched_setaffinity(arg1, mask_size, mask));
7531        }
7532        break;
7533    case TARGET_NR_sched_setparam:
7534        {
7535            struct sched_param *target_schp;
7536            struct sched_param schp;
7537
7538            if (!lock_user_struct(VERIFY_READ, target_schp, arg2, 1))
7539                goto efault;
7540            schp.sched_priority = tswap32(target_schp->sched_priority);
7541            unlock_user_struct(target_schp, arg2, 0);
7542            ret = get_errno(sched_setparam(arg1, &schp));
7543        }
7544        break;
7545    case TARGET_NR_sched_getparam:
7546        {
7547            struct sched_param *target_schp;
7548            struct sched_param schp;
7549            ret = get_errno(sched_getparam(arg1, &schp));
7550            if (!is_error(ret)) {
7551                if (!lock_user_struct(VERIFY_WRITE, target_schp, arg2, 0))
7552                    goto efault;
7553                target_schp->sched_priority = tswap32(schp.sched_priority);
7554                unlock_user_struct(target_schp, arg2, 1);
7555            }
7556        }
7557        break;
7558    case TARGET_NR_sched_setscheduler:
7559        {
7560            struct sched_param *target_schp;
7561            struct sched_param schp;
7562            if (!lock_user_struct(VERIFY_READ, target_schp, arg3, 1))
7563                goto efault;
7564            schp.sched_priority = tswap32(target_schp->sched_priority);
7565            unlock_user_struct(target_schp, arg3, 0);
7566            ret = get_errno(sched_setscheduler(arg1, arg2, &schp));
7567        }
7568        break;
7569    case TARGET_NR_sched_getscheduler:
7570        ret = get_errno(sched_getscheduler(arg1));
7571        break;
7572    case TARGET_NR_sched_yield:
7573        ret = get_errno(sched_yield());
7574        break;
7575    case TARGET_NR_sched_get_priority_max:
7576        ret = get_errno(sched_get_priority_max(arg1));
7577        break;
7578    case TARGET_NR_sched_get_priority_min:
7579        ret = get_errno(sched_get_priority_min(arg1));
7580        break;
7581    case TARGET_NR_sched_rr_get_interval:
7582        {
7583            struct timespec ts;
7584            ret = get_errno(sched_rr_get_interval(arg1, &ts));
7585            if (!is_error(ret)) {
7586                host_to_target_timespec(arg2, &ts);
7587            }
7588        }
7589        break;
7590    case TARGET_NR_nanosleep:
7591        {
7592            struct timespec req, rem;
7593            target_to_host_timespec(&req, arg1);
7594            ret = get_errno(nanosleep(&req, &rem));
7595            if (is_error(ret) && arg2) {
7596                host_to_target_timespec(arg2, &rem);
7597            }
7598        }
7599        break;
7600#ifdef TARGET_NR_query_module
7601    case TARGET_NR_query_module:
7602        goto unimplemented;
7603#endif
7604#ifdef TARGET_NR_nfsservctl
7605    case TARGET_NR_nfsservctl:
7606        goto unimplemented;
7607#endif
7608    case TARGET_NR_prctl:
7609        switch (arg1) {
7610        case PR_GET_PDEATHSIG:
7611        {
7612            int deathsig;
7613            ret = get_errno(prctl(arg1, &deathsig, arg3, arg4, arg5));
7614            if (!is_error(ret) && arg2
7615                && put_user_ual(deathsig, arg2)) {
7616                goto efault;
7617            }
7618            break;
7619        }
7620#ifdef PR_GET_NAME
7621        case PR_GET_NAME:
7622        {
7623            void *name = lock_user(VERIFY_WRITE, arg2, 16, 1);
7624            if (!name) {
7625                goto efault;
7626            }
7627            ret = get_errno(prctl(arg1, (unsigned long)name,
7628                                  arg3, arg4, arg5));
7629            unlock_user(name, arg2, 16);
7630            break;
7631        }
7632        case PR_SET_NAME:
7633        {
7634            void *name = lock_user(VERIFY_READ, arg2, 16, 1);
7635            if (!name) {
7636                goto efault;
7637            }
7638            ret = get_errno(prctl(arg1, (unsigned long)name,
7639                                  arg3, arg4, arg5));
7640            unlock_user(name, arg2, 0);
7641            break;
7642        }
7643#endif
7644        default:
7645            /* Most prctl options have no pointer arguments */
7646            ret = get_errno(prctl(arg1, arg2, arg3, arg4, arg5));
7647            break;
7648        }
7649        break;
7650#ifdef TARGET_NR_arch_prctl
7651    case TARGET_NR_arch_prctl:
7652#if defined(TARGET_I386) && !defined(TARGET_ABI32)
7653        ret = do_arch_prctl(cpu_env, arg1, arg2);
7654        break;
7655#else
7656        goto unimplemented;
7657#endif
7658#endif
7659#ifdef TARGET_NR_pread64
7660    case TARGET_NR_pread64:
7661        if (regpairs_aligned(cpu_env)) {
7662            arg4 = arg5;
7663            arg5 = arg6;
7664        }
7665        if (!(p = lock_user(VERIFY_WRITE, arg2, arg3, 0)))
7666            goto efault;
7667        ret = get_errno(pread64(arg1, p, arg3, target_offset64(arg4, arg5)));
7668        unlock_user(p, arg2, ret);
7669        break;
7670    case TARGET_NR_pwrite64:
7671        if (regpairs_aligned(cpu_env)) {
7672            arg4 = arg5;
7673            arg5 = arg6;
7674        }
7675        if (!(p = lock_user(VERIFY_READ, arg2, arg3, 1)))
7676            goto efault;
7677        ret = get_errno(pwrite64(arg1, p, arg3, target_offset64(arg4, arg5)));
7678        unlock_user(p, arg2, 0);
7679        break;
7680#endif
7681    case TARGET_NR_getcwd:
7682        if (!(p = lock_user(VERIFY_WRITE, arg1, arg2, 0)))
7683            goto efault;
7684        ret = get_errno(sys_getcwd1(p, arg2));
7685        unlock_user(p, arg1, ret);
7686        break;
7687    case TARGET_NR_capget:
7688        goto unimplemented;
7689    case TARGET_NR_capset:
7690        goto unimplemented;
7691    case TARGET_NR_sigaltstack:
7692#if defined(TARGET_I386) || defined(TARGET_ARM) || defined(TARGET_MIPS) || \
7693    defined(TARGET_SPARC) || defined(TARGET_PPC) || defined(TARGET_ALPHA) || \
7694    defined(TARGET_M68K) || defined(TARGET_S390X) || defined(TARGET_OPENRISC)
7695        ret = do_sigaltstack(arg1, arg2, get_sp_from_cpustate((CPUArchState *)cpu_env));
7696        break;
7697#else
7698        goto unimplemented;
7699#endif
7700
7701#ifdef CONFIG_SENDFILE
7702    case TARGET_NR_sendfile:
7703    {
7704        off_t *offp = NULL;
7705        off_t off;
7706        if (arg3) {
7707            ret = get_user_sal(off, arg3);
7708            if (is_error(ret)) {
7709                break;
7710            }
7711            offp = &off;
7712        }
7713        ret = get_errno(sendfile(arg1, arg2, offp, arg4));
7714        if (!is_error(ret) && arg3) {
7715            abi_long ret2 = put_user_sal(off, arg3);
7716            if (is_error(ret2)) {
7717                ret = ret2;
7718            }
7719        }
7720        break;
7721    }
7722#ifdef TARGET_NR_sendfile64
7723    case TARGET_NR_sendfile64:
7724    {
7725        off_t *offp = NULL;
7726        off_t off;
7727        if (arg3) {
7728            ret = get_user_s64(off, arg3);
7729            if (is_error(ret)) {
7730                break;
7731            }
7732            offp = &off;
7733        }
7734        ret = get_errno(sendfile(arg1, arg2, offp, arg4));
7735        if (!is_error(ret) && arg3) {
7736            abi_long ret2 = put_user_s64(off, arg3);
7737            if (is_error(ret2)) {
7738                ret = ret2;
7739            }
7740        }
7741        break;
7742    }
7743#endif
7744#else
7745    case TARGET_NR_sendfile:
7746#ifdef TARGET_NR_sendfile64
7747    case TARGET_NR_sendfile64:
7748#endif
7749        goto unimplemented;
7750#endif
7751
7752#ifdef TARGET_NR_getpmsg
7753    case TARGET_NR_getpmsg:
7754        goto unimplemented;
7755#endif
7756#ifdef TARGET_NR_putpmsg
7757    case TARGET_NR_putpmsg:
7758        goto unimplemented;
7759#endif
7760#ifdef TARGET_NR_vfork
7761    case TARGET_NR_vfork:
7762        ret = get_errno(do_fork(cpu_env, CLONE_VFORK | CLONE_VM | SIGCHLD,
7763                        0, 0, 0, 0));
7764        break;
7765#endif
7766#ifdef TARGET_NR_ugetrlimit
7767    case TARGET_NR_ugetrlimit:
7768    {
7769        struct rlimit rlim;
7770        int resource = target_to_host_resource(arg1);
7771        ret = get_errno(getrlimit(resource, &rlim));
7772        if (!is_error(ret)) {
7773            struct target_rlimit *target_rlim;
7774            if (!lock_user_struct(VERIFY_WRITE, target_rlim, arg2, 0))
7775                goto efault;
7776            target_rlim->rlim_cur = host_to_target_rlim(rlim.rlim_cur);
7777            target_rlim->rlim_max = host_to_target_rlim(rlim.rlim_max);
7778            unlock_user_struct(target_rlim, arg2, 1);
7779        }
7780        break;
7781    }
7782#endif
7783#ifdef TARGET_NR_truncate64
7784    case TARGET_NR_truncate64:
7785        if (!(p = lock_user_string(arg1)))
7786            goto efault;
7787        ret = target_truncate64(cpu_env, p, arg2, arg3, arg4);
7788        unlock_user(p, arg1, 0);
7789        break;
7790#endif
7791#ifdef TARGET_NR_ftruncate64
7792    case TARGET_NR_ftruncate64:
7793        ret = target_ftruncate64(cpu_env, arg1, arg2, arg3, arg4);
7794        break;
7795#endif
7796#ifdef TARGET_NR_stat64
7797    case TARGET_NR_stat64:
7798        if (!(p = lock_user_string(arg1)))
7799            goto efault;
7800        ret = get_errno(stat(path(p), &st));
7801        unlock_user(p, arg1, 0);
7802        if (!is_error(ret))
7803            ret = host_to_target_stat64(cpu_env, arg2, &st);
7804        break;
7805#endif
7806#ifdef TARGET_NR_lstat64
7807    case TARGET_NR_lstat64:
7808        if (!(p = lock_user_string(arg1)))
7809            goto efault;
7810        ret = get_errno(lstat(path(p), &st));
7811        unlock_user(p, arg1, 0);
7812        if (!is_error(ret))
7813            ret = host_to_target_stat64(cpu_env, arg2, &st);
7814        break;
7815#endif
7816#ifdef TARGET_NR_fstat64
7817    case TARGET_NR_fstat64:
7818        ret = get_errno(fstat(arg1, &st));
7819        if (!is_error(ret))
7820            ret = host_to_target_stat64(cpu_env, arg2, &st);
7821        break;
7822#endif
7823#if (defined(TARGET_NR_fstatat64) || defined(TARGET_NR_newfstatat))
7824#ifdef TARGET_NR_fstatat64
7825    case TARGET_NR_fstatat64:
7826#endif
7827#ifdef TARGET_NR_newfstatat
7828    case TARGET_NR_newfstatat:
7829#endif
7830        if (!(p = lock_user_string(arg2)))
7831            goto efault;
7832        ret = get_errno(fstatat(arg1, path(p), &st, arg4));
7833        if (!is_error(ret))
7834            ret = host_to_target_stat64(cpu_env, arg3, &st);
7835        break;
7836#endif
7837    case TARGET_NR_lchown:
7838        if (!(p = lock_user_string(arg1)))
7839            goto efault;
7840        ret = get_errno(lchown(p, low2highuid(arg2), low2highgid(arg3)));
7841        unlock_user(p, arg1, 0);
7842        break;
7843#ifdef TARGET_NR_getuid
7844    case TARGET_NR_getuid:
7845        ret = get_errno(high2lowuid(getuid()));
7846        break;
7847#endif
7848#ifdef TARGET_NR_getgid
7849    case TARGET_NR_getgid:
7850        ret = get_errno(high2lowgid(getgid()));
7851        break;
7852#endif
7853#ifdef TARGET_NR_geteuid
7854    case TARGET_NR_geteuid:
7855        ret = get_errno(high2lowuid(geteuid()));
7856        break;
7857#endif
7858#ifdef TARGET_NR_getegid
7859    case TARGET_NR_getegid:
7860        ret = get_errno(high2lowgid(getegid()));
7861        break;
7862#endif
7863    case TARGET_NR_setreuid:
7864        ret = get_errno(setreuid(low2highuid(arg1), low2highuid(arg2)));
7865        break;
7866    case TARGET_NR_setregid:
7867        ret = get_errno(setregid(low2highgid(arg1), low2highgid(arg2)));
7868        break;
7869    case TARGET_NR_getgroups:
7870        {
7871            int gidsetsize = arg1;
7872            target_id *target_grouplist;
7873            gid_t *grouplist;
7874            int i;
7875
7876            grouplist = alloca(gidsetsize * sizeof(gid_t));
7877            ret = get_errno(getgroups(gidsetsize, grouplist));
7878            if (gidsetsize == 0)
7879                break;
7880            if (!is_error(ret)) {
7881                target_grouplist = lock_user(VERIFY_WRITE, arg2, gidsetsize * sizeof(target_id), 0);
7882                if (!target_grouplist)
7883                    goto efault;
7884                for(i = 0;i < ret; i++)
7885                    target_grouplist[i] = tswapid(high2lowgid(grouplist[i]));
7886                unlock_user(target_grouplist, arg2, gidsetsize * sizeof(target_id));
7887            }
7888        }
7889        break;
7890    case TARGET_NR_setgroups:
7891        {
7892            int gidsetsize = arg1;
7893            target_id *target_grouplist;
7894            gid_t *grouplist = NULL;
7895            int i;
7896            if (gidsetsize) {
7897                grouplist = alloca(gidsetsize * sizeof(gid_t));
7898                target_grouplist = lock_user(VERIFY_READ, arg2, gidsetsize * sizeof(target_id), 1);
7899                if (!target_grouplist) {
7900                    ret = -TARGET_EFAULT;
7901                    goto fail;
7902                }
7903                for (i = 0; i < gidsetsize; i++) {
7904                    grouplist[i] = low2highgid(tswapid(target_grouplist[i]));
7905                }
7906                unlock_user(target_grouplist, arg2, 0);
7907            }
7908            ret = get_errno(setgroups(gidsetsize, grouplist));
7909        }
7910        break;
7911    case TARGET_NR_fchown:
7912        ret = get_errno(fchown(arg1, low2highuid(arg2), low2highgid(arg3)));
7913        break;
7914#if defined(TARGET_NR_fchownat)
7915    case TARGET_NR_fchownat:
7916        if (!(p = lock_user_string(arg2))) 
7917            goto efault;
7918        ret = get_errno(fchownat(arg1, p, low2highuid(arg3),
7919                                 low2highgid(arg4), arg5));
7920        unlock_user(p, arg2, 0);
7921        break;
7922#endif
7923#ifdef TARGET_NR_setresuid
7924    case TARGET_NR_setresuid:
7925        ret = get_errno(setresuid(low2highuid(arg1),
7926                                  low2highuid(arg2),
7927                                  low2highuid(arg3)));
7928        break;
7929#endif
7930#ifdef TARGET_NR_getresuid
7931    case TARGET_NR_getresuid:
7932        {
7933            uid_t ruid, euid, suid;
7934            ret = get_errno(getresuid(&ruid, &euid, &suid));
7935            if (!is_error(ret)) {
7936                if (put_user_u16(high2lowuid(ruid), arg1)
7937                    || put_user_u16(high2lowuid(euid), arg2)
7938                    || put_user_u16(high2lowuid(suid), arg3))
7939                    goto efault;
7940            }
7941        }
7942        break;
7943#endif
7944#ifdef TARGET_NR_getresgid
7945    case TARGET_NR_setresgid:
7946        ret = get_errno(setresgid(low2highgid(arg1),
7947                                  low2highgid(arg2),
7948                                  low2highgid(arg3)));
7949        break;
7950#endif
7951#ifdef TARGET_NR_getresgid
7952    case TARGET_NR_getresgid:
7953        {
7954            gid_t rgid, egid, sgid;
7955            ret = get_errno(getresgid(&rgid, &egid, &sgid));
7956            if (!is_error(ret)) {
7957                if (put_user_u16(high2lowgid(rgid), arg1)
7958                    || put_user_u16(high2lowgid(egid), arg2)
7959                    || put_user_u16(high2lowgid(sgid), arg3))
7960                    goto efault;
7961            }
7962        }
7963        break;
7964#endif
7965    case TARGET_NR_chown:
7966        if (!(p = lock_user_string(arg1)))
7967            goto efault;
7968        ret = get_errno(chown(p, low2highuid(arg2), low2highgid(arg3)));
7969        unlock_user(p, arg1, 0);
7970        break;
7971    case TARGET_NR_setuid:
7972        ret = get_errno(setuid(low2highuid(arg1)));
7973        break;
7974    case TARGET_NR_setgid:
7975        ret = get_errno(setgid(low2highgid(arg1)));
7976        break;
7977    case TARGET_NR_setfsuid:
7978        ret = get_errno(setfsuid(arg1));
7979        break;
7980    case TARGET_NR_setfsgid:
7981        ret = get_errno(setfsgid(arg1));
7982        break;
7983
7984#ifdef TARGET_NR_lchown32
7985    case TARGET_NR_lchown32:
7986        if (!(p = lock_user_string(arg1)))
7987            goto efault;
7988        ret = get_errno(lchown(p, arg2, arg3));
7989        unlock_user(p, arg1, 0);
7990        break;
7991#endif
7992#ifdef TARGET_NR_getuid32
7993    case TARGET_NR_getuid32:
7994        ret = get_errno(getuid());
7995        break;
7996#endif
7997
7998#if defined(TARGET_NR_getxuid) && defined(TARGET_ALPHA)
7999   /* Alpha specific */
8000    case TARGET_NR_getxuid:
8001         {
8002            uid_t euid;
8003            euid=geteuid();
8004            ((CPUAlphaState *)cpu_env)->ir[IR_A4]=euid;
8005         }
8006        ret = get_errno(getuid());
8007        break;
8008#endif
8009#if defined(TARGET_NR_getxgid) && defined(TARGET_ALPHA)
8010   /* Alpha specific */
8011    case TARGET_NR_getxgid:
8012         {
8013            uid_t egid;
8014            egid=getegid();
8015            ((CPUAlphaState *)cpu_env)->ir[IR_A4]=egid;
8016         }
8017        ret = get_errno(getgid());
8018        break;
8019#endif
8020#if defined(TARGET_NR_osf_getsysinfo) && defined(TARGET_ALPHA)
8021    /* Alpha specific */
8022    case TARGET_NR_osf_getsysinfo:
8023        ret = -TARGET_EOPNOTSUPP;
8024        switch (arg1) {
8025          case TARGET_GSI_IEEE_FP_CONTROL:
8026            {
8027                uint64_t swcr, fpcr = cpu_alpha_load_fpcr (cpu_env);
8028
8029                /* Copied from linux ieee_fpcr_to_swcr.  */
8030                swcr = (fpcr >> 35) & SWCR_STATUS_MASK;
8031                swcr |= (fpcr >> 36) & SWCR_MAP_DMZ;
8032                swcr |= (~fpcr >> 48) & (SWCR_TRAP_ENABLE_INV
8033                                        | SWCR_TRAP_ENABLE_DZE
8034                                        | SWCR_TRAP_ENABLE_OVF);
8035                swcr |= (~fpcr >> 57) & (SWCR_TRAP_ENABLE_UNF
8036                                        | SWCR_TRAP_ENABLE_INE);
8037                swcr |= (fpcr >> 47) & SWCR_MAP_UMZ;
8038                swcr |= (~fpcr >> 41) & SWCR_TRAP_ENABLE_DNO;
8039
8040                if (put_user_u64 (swcr, arg2))
8041                        goto efault;
8042                ret = 0;
8043            }
8044            break;
8045
8046          /* case GSI_IEEE_STATE_AT_SIGNAL:
8047             -- Not implemented in linux kernel.
8048             case GSI_UACPROC:
8049             -- Retrieves current unaligned access state; not much used.
8050             case GSI_PROC_TYPE:
8051             -- Retrieves implver information; surely not used.
8052             case GSI_GET_HWRPB:
8053             -- Grabs a copy of the HWRPB; surely not used.
8054          */
8055        }
8056        break;
8057#endif
8058#if defined(TARGET_NR_osf_setsysinfo) && defined(TARGET_ALPHA)
8059    /* Alpha specific */
8060    case TARGET_NR_osf_setsysinfo:
8061        ret = -TARGET_EOPNOTSUPP;
8062        switch (arg1) {
8063          case TARGET_SSI_IEEE_FP_CONTROL:
8064            {
8065                uint64_t swcr, fpcr, orig_fpcr;
8066
8067                if (get_user_u64 (swcr, arg2)) {
8068                    goto efault;
8069                }
8070                orig_fpcr = cpu_alpha_load_fpcr(cpu_env);
8071                fpcr = orig_fpcr & FPCR_DYN_MASK;
8072
8073                /* Copied from linux ieee_swcr_to_fpcr.  */
8074                fpcr |= (swcr & SWCR_STATUS_MASK) << 35;
8075                fpcr |= (swcr & SWCR_MAP_DMZ) << 36;
8076                fpcr |= (~swcr & (SWCR_TRAP_ENABLE_INV
8077                                  | SWCR_TRAP_ENABLE_DZE
8078                                  | SWCR_TRAP_ENABLE_OVF)) << 48;
8079                fpcr |= (~swcr & (SWCR_TRAP_ENABLE_UNF
8080                                  | SWCR_TRAP_ENABLE_INE)) << 57;
8081                fpcr |= (swcr & SWCR_MAP_UMZ ? FPCR_UNDZ | FPCR_UNFD : 0);
8082                fpcr |= (~swcr & SWCR_TRAP_ENABLE_DNO) << 41;
8083
8084                cpu_alpha_store_fpcr(cpu_env, fpcr);
8085                ret = 0;
8086            }
8087            break;
8088
8089          case TARGET_SSI_IEEE_RAISE_EXCEPTION:
8090            {
8091                uint64_t exc, fpcr, orig_fpcr;
8092                int si_code;
8093
8094                if (get_user_u64(exc, arg2)) {
8095                    goto efault;
8096                }
8097
8098                orig_fpcr = cpu_alpha_load_fpcr(cpu_env);
8099
8100                /* We only add to the exception status here.  */
8101                fpcr = orig_fpcr | ((exc & SWCR_STATUS_MASK) << 35);
8102
8103                cpu_alpha_store_fpcr(cpu_env, fpcr);
8104                ret = 0;
8105
8106                /* Old exceptions are not signaled.  */
8107                fpcr &= ~(orig_fpcr & FPCR_STATUS_MASK);
8108
8109                /* If any exceptions set by this call,
8110                   and are unmasked, send a signal.  */
8111                si_code = 0;
8112                if ((fpcr & (FPCR_INE | FPCR_INED)) == FPCR_INE) {
8113                    si_code = TARGET_FPE_FLTRES;
8114                }
8115                if ((fpcr & (FPCR_UNF | FPCR_UNFD)) == FPCR_UNF) {
8116                    si_code = TARGET_FPE_FLTUND;
8117                }
8118                if ((fpcr & (FPCR_OVF | FPCR_OVFD)) == FPCR_OVF) {
8119                    si_code = TARGET_FPE_FLTOVF;
8120                }
8121                if ((fpcr & (FPCR_DZE | FPCR_DZED)) == FPCR_DZE) {
8122                    si_code = TARGET_FPE_FLTDIV;
8123                }
8124                if ((fpcr & (FPCR_INV | FPCR_INVD)) == FPCR_INV) {
8125                    si_code = TARGET_FPE_FLTINV;
8126                }
8127                if (si_code != 0) {
8128                    target_siginfo_t info;
8129                    info.si_signo = SIGFPE;
8130                    info.si_errno = 0;
8131                    info.si_code = si_code;
8132                    info._sifields._sigfault._addr
8133                        = ((CPUArchState *)cpu_env)->pc;
8134                    queue_signal((CPUArchState *)cpu_env, info.si_signo, &info);
8135                }
8136            }
8137            break;
8138
8139          /* case SSI_NVPAIRS:
8140             -- Used with SSIN_UACPROC to enable unaligned accesses.
8141             case SSI_IEEE_STATE_AT_SIGNAL:
8142             case SSI_IEEE_IGNORE_STATE_AT_SIGNAL:
8143             -- Not implemented in linux kernel
8144          */
8145        }
8146        break;
8147#endif
8148#ifdef TARGET_NR_osf_sigprocmask
8149    /* Alpha specific.  */
8150    case TARGET_NR_osf_sigprocmask:
8151        {
8152            abi_ulong mask;
8153            int how;
8154            sigset_t set, oldset;
8155
8156            switch(arg1) {
8157            case TARGET_SIG_BLOCK:
8158                how = SIG_BLOCK;
8159                break;
8160            case TARGET_SIG_UNBLOCK:
8161                how = SIG_UNBLOCK;
8162                break;
8163            case TARGET_SIG_SETMASK:
8164                how = SIG_SETMASK;
8165                break;
8166            default:
8167                ret = -TARGET_EINVAL;
8168                goto fail;
8169            }
8170            mask = arg2;
8171            target_to_host_old_sigset(&set, &mask);
8172            sigprocmask(how, &set, &oldset);
8173            host_to_target_old_sigset(&mask, &oldset);
8174            ret = mask;
8175        }
8176        break;
8177#endif
8178
8179#ifdef TARGET_NR_getgid32
8180    case TARGET_NR_getgid32:
8181        ret = get_errno(getgid());
8182        break;
8183#endif
8184#ifdef TARGET_NR_geteuid32
8185    case TARGET_NR_geteuid32:
8186        ret = get_errno(geteuid());
8187        break;
8188#endif
8189#ifdef TARGET_NR_getegid32
8190    case TARGET_NR_getegid32:
8191        ret = get_errno(getegid());
8192        break;
8193#endif
8194#ifdef TARGET_NR_setreuid32
8195    case TARGET_NR_setreuid32:
8196        ret = get_errno(setreuid(arg1, arg2));
8197        break;
8198#endif
8199#ifdef TARGET_NR_setregid32
8200    case TARGET_NR_setregid32:
8201        ret = get_errno(setregid(arg1, arg2));
8202        break;
8203#endif
8204#ifdef TARGET_NR_getgroups32
8205    case TARGET_NR_getgroups32:
8206        {
8207            int gidsetsize = arg1;
8208            uint32_t *target_grouplist;
8209            gid_t *grouplist;
8210            int i;
8211
8212            grouplist = alloca(gidsetsize * sizeof(gid_t));
8213            ret = get_errno(getgroups(gidsetsize, grouplist));
8214            if (gidsetsize == 0)
8215                break;
8216            if (!is_error(ret)) {
8217                target_grouplist = lock_user(VERIFY_WRITE, arg2, gidsetsize * 4, 0);
8218                if (!target_grouplist) {
8219                    ret = -TARGET_EFAULT;
8220                    goto fail;
8221                }
8222                for(i = 0;i < ret; i++)
8223                    target_grouplist[i] = tswap32(grouplist[i]);
8224                unlock_user(target_grouplist, arg2, gidsetsize * 4);
8225            }
8226        }
8227        break;
8228#endif
8229#ifdef TARGET_NR_setgroups32
8230    case TARGET_NR_setgroups32:
8231        {
8232            int gidsetsize = arg1;
8233            uint32_t *target_grouplist;
8234            gid_t *grouplist;
8235            int i;
8236
8237            grouplist = alloca(gidsetsize * sizeof(gid_t));
8238            target_grouplist = lock_user(VERIFY_READ, arg2, gidsetsize * 4, 1);
8239            if (!target_grouplist) {
8240                ret = -TARGET_EFAULT;
8241                goto fail;
8242            }
8243            for(i = 0;i < gidsetsize; i++)
8244                grouplist[i] = tswap32(target_grouplist[i]);
8245            unlock_user(target_grouplist, arg2, 0);
8246            ret = get_errno(setgroups(gidsetsize, grouplist));
8247        }
8248        break;
8249#endif
8250#ifdef TARGET_NR_fchown32
8251    case TARGET_NR_fchown32:
8252        ret = get_errno(fchown(arg1, arg2, arg3));
8253        break;
8254#endif
8255#ifdef TARGET_NR_setresuid32
8256    case TARGET_NR_setresuid32:
8257        ret = get_errno(setresuid(arg1, arg2, arg3));
8258        break;
8259#endif
8260#ifdef TARGET_NR_getresuid32
8261    case TARGET_NR_getresuid32:
8262        {
8263            uid_t ruid, euid, suid;
8264            ret = get_errno(getresuid(&ruid, &euid, &suid));
8265            if (!is_error(ret)) {
8266                if (put_user_u32(ruid, arg1)
8267                    || put_user_u32(euid, arg2)
8268                    || put_user_u32(suid, arg3))
8269                    goto efault;
8270            }
8271        }
8272        break;
8273#endif
8274#ifdef TARGET_NR_setresgid32
8275    case TARGET_NR_setresgid32:
8276        ret = get_errno(setresgid(arg1, arg2, arg3));
8277        break;
8278#endif
8279#ifdef TARGET_NR_getresgid32
8280    case TARGET_NR_getresgid32:
8281        {
8282            gid_t rgid, egid, sgid;
8283            ret = get_errno(getresgid(&rgid, &egid, &sgid));
8284            if (!is_error(ret)) {
8285                if (put_user_u32(rgid, arg1)
8286                    || put_user_u32(egid, arg2)
8287                    || put_user_u32(sgid, arg3))
8288                    goto efault;
8289            }
8290        }
8291        break;
8292#endif
8293#ifdef TARGET_NR_chown32
8294    case TARGET_NR_chown32:
8295        if (!(p = lock_user_string(arg1)))
8296            goto efault;
8297        ret = get_errno(chown(p, arg2, arg3));
8298        unlock_user(p, arg1, 0);
8299        break;
8300#endif
8301#ifdef TARGET_NR_setuid32
8302    case TARGET_NR_setuid32:
8303        ret = get_errno(setuid(arg1));
8304        break;
8305#endif
8306#ifdef TARGET_NR_setgid32
8307    case TARGET_NR_setgid32:
8308        ret = get_errno(setgid(arg1));
8309        break;
8310#endif
8311#ifdef TARGET_NR_setfsuid32
8312    case TARGET_NR_setfsuid32:
8313        ret = get_errno(setfsuid(arg1));
8314        break;
8315#endif
8316#ifdef TARGET_NR_setfsgid32
8317    case TARGET_NR_setfsgid32:
8318        ret = get_errno(setfsgid(arg1));
8319        break;
8320#endif
8321
8322    case TARGET_NR_pivot_root:
8323        goto unimplemented;
8324#ifdef TARGET_NR_mincore
8325    case TARGET_NR_mincore:
8326        {
8327            void *a;
8328            ret = -TARGET_EFAULT;
8329            if (!(a = lock_user(VERIFY_READ, arg1,arg2, 0)))
8330                goto efault;
8331            if (!(p = lock_user_string(arg3)))
8332                goto mincore_fail;
8333            ret = get_errno(mincore(a, arg2, p));
8334            unlock_user(p, arg3, ret);
8335            mincore_fail:
8336            unlock_user(a, arg1, 0);
8337        }
8338        break;
8339#endif
8340#ifdef TARGET_NR_arm_fadvise64_64
8341    case TARGET_NR_arm_fadvise64_64:
8342        {
8343                /*
8344                 * arm_fadvise64_64 looks like fadvise64_64 but
8345                 * with different argument order
8346                 */
8347                abi_long temp;
8348                temp = arg3;
8349                arg3 = arg4;
8350                arg4 = temp;
8351        }
8352#endif
8353#if defined(TARGET_NR_fadvise64_64) || defined(TARGET_NR_arm_fadvise64_64) || defined(TARGET_NR_fadvise64)
8354#ifdef TARGET_NR_fadvise64_64
8355    case TARGET_NR_fadvise64_64:
8356#endif
8357#ifdef TARGET_NR_fadvise64
8358    case TARGET_NR_fadvise64:
8359#endif
8360#ifdef TARGET_S390X
8361        switch (arg4) {
8362        case 4: arg4 = POSIX_FADV_NOREUSE + 1; break; /* make sure it's an invalid value */
8363        case 5: arg4 = POSIX_FADV_NOREUSE + 2; break; /* ditto */
8364        case 6: arg4 = POSIX_FADV_DONTNEED; break;
8365        case 7: arg4 = POSIX_FADV_NOREUSE; break;
8366        default: break;
8367        }
8368#endif
8369        ret = -posix_fadvise(arg1, arg2, arg3, arg4);
8370        break;
8371#endif
8372#ifdef TARGET_NR_madvise
8373    case TARGET_NR_madvise:
8374        /* A straight passthrough may not be safe because qemu sometimes
8375           turns private file-backed mappings into anonymous mappings.
8376           This will break MADV_DONTNEED.
8377           This is a hint, so ignoring and returning success is ok.  */
8378        ret = get_errno(0);
8379        break;
8380#endif
8381#if TARGET_ABI_BITS == 32
8382    case TARGET_NR_fcntl64:
8383    {
8384        int cmd;
8385        struct flock64 fl;
8386        struct target_flock64 *target_fl;
8387#ifdef TARGET_ARM
8388        struct target_eabi_flock64 *target_efl;
8389#endif
8390
8391        cmd = target_to_host_fcntl_cmd(arg2);
8392        if (cmd == -TARGET_EINVAL) {
8393            ret = cmd;
8394            break;
8395        }
8396
8397        switch(arg2) {
8398        case TARGET_F_GETLK64:
8399#ifdef TARGET_ARM
8400            if (((CPUARMState *)cpu_env)->eabi) {
8401                if (!lock_user_struct(VERIFY_READ, target_efl, arg3, 1)) 
8402                    goto efault;
8403                fl.l_type = tswap16(target_efl->l_type);
8404                fl.l_whence = tswap16(target_efl->l_whence);
8405                fl.l_start = tswap64(target_efl->l_start);
8406                fl.l_len = tswap64(target_efl->l_len);
8407                fl.l_pid = tswap32(target_efl->l_pid);
8408                unlock_user_struct(target_efl, arg3, 0);
8409            } else
8410#endif
8411            {
8412                if (!lock_user_struct(VERIFY_READ, target_fl, arg3, 1)) 
8413                    goto efault;
8414                fl.l_type = tswap16(target_fl->l_type);
8415                fl.l_whence = tswap16(target_fl->l_whence);
8416                fl.l_start = tswap64(target_fl->l_start);
8417                fl.l_len = tswap64(target_fl->l_len);
8418                fl.l_pid = tswap32(target_fl->l_pid);
8419                unlock_user_struct(target_fl, arg3, 0);
8420            }
8421            ret = get_errno(fcntl(arg1, cmd, &fl));
8422            if (ret == 0) {
8423#ifdef TARGET_ARM
8424                if (((CPUARMState *)cpu_env)->eabi) {
8425                    if (!lock_user_struct(VERIFY_WRITE, target_efl, arg3, 0)) 
8426                        goto efault;
8427                    target_efl->l_type = tswap16(fl.l_type);
8428                    target_efl->l_whence = tswap16(fl.l_whence);
8429                    target_efl->l_start = tswap64(fl.l_start);
8430                    target_efl->l_len = tswap64(fl.l_len);
8431                    target_efl->l_pid = tswap32(fl.l_pid);
8432                    unlock_user_struct(target_efl, arg3, 1);
8433                } else
8434#endif
8435                {
8436                    if (!lock_user_struct(VERIFY_WRITE, target_fl, arg3, 0)) 
8437                        goto efault;
8438                    target_fl->l_type = tswap16(fl.l_type);
8439                    target_fl->l_whence = tswap16(fl.l_whence);
8440                    target_fl->l_start = tswap64(fl.l_start);
8441                    target_fl->l_len = tswap64(fl.l_len);
8442                    target_fl->l_pid = tswap32(fl.l_pid);
8443                    unlock_user_struct(target_fl, arg3, 1);
8444                }
8445            }
8446            break;
8447
8448        case TARGET_F_SETLK64:
8449        case TARGET_F_SETLKW64:
8450#ifdef TARGET_ARM
8451            if (((CPUARMState *)cpu_env)->eabi) {
8452                if (!lock_user_struct(VERIFY_READ, target_efl, arg3, 1)) 
8453                    goto efault;
8454                fl.l_type = tswap16(target_efl->l_type);
8455                fl.l_whence = tswap16(target_efl->l_whence);
8456                fl.l_start = tswap64(target_efl->l_start);
8457                fl.l_len = tswap64(target_efl->l_len);
8458                fl.l_pid = tswap32(target_efl->l_pid);
8459                unlock_user_struct(target_efl, arg3, 0);
8460            } else
8461#endif
8462            {
8463                if (!lock_user_struct(VERIFY_READ, target_fl, arg3, 1)) 
8464                    goto efault;
8465                fl.l_type = tswap16(target_fl->l_type);
8466                fl.l_whence = tswap16(target_fl->l_whence);
8467                fl.l_start = tswap64(target_fl->l_start);
8468                fl.l_len = tswap64(target_fl->l_len);
8469                fl.l_pid = tswap32(target_fl->l_pid);
8470                unlock_user_struct(target_fl, arg3, 0);
8471            }
8472            ret = get_errno(fcntl(arg1, cmd, &fl));
8473            break;
8474        default:
8475            ret = do_fcntl(arg1, arg2, arg3);
8476            break;
8477        }
8478        break;
8479    }
8480#endif
8481#ifdef TARGET_NR_cacheflush
8482    case TARGET_NR_cacheflush:
8483        /* self-modifying code is handled automatically, so nothing needed */
8484        ret = 0;
8485        break;
8486#endif
8487#ifdef TARGET_NR_security
8488    case TARGET_NR_security:
8489        goto unimplemented;
8490#endif
8491#ifdef TARGET_NR_getpagesize
8492    case TARGET_NR_getpagesize:
8493        ret = TARGET_PAGE_SIZE;
8494        break;
8495#endif
8496    case TARGET_NR_gettid:
8497        ret = get_errno(gettid());
8498        break;
8499#ifdef TARGET_NR_readahead
8500    case TARGET_NR_readahead:
8501#if TARGET_ABI_BITS == 32
8502        if (regpairs_aligned(cpu_env)) {
8503            arg2 = arg3;
8504            arg3 = arg4;
8505            arg4 = arg5;
8506        }
8507        ret = get_errno(readahead(arg1, ((off64_t)arg3 << 32) | arg2, arg4));
8508#else
8509        ret = get_errno(readahead(arg1, arg2, arg3));
8510#endif
8511        break;
8512#endif
8513#ifdef CONFIG_ATTR
8514#ifdef TARGET_NR_setxattr
8515    case TARGET_NR_listxattr:
8516    case TARGET_NR_llistxattr:
8517    {
8518        void *p, *b = 0;
8519        if (arg2) {
8520            b = lock_user(VERIFY_WRITE, arg2, arg3, 0);
8521            if (!b) {
8522                ret = -TARGET_EFAULT;
8523                break;
8524            }
8525        }
8526        p = lock_user_string(arg1);
8527        if (p) {
8528            if (num == TARGET_NR_listxattr) {
8529                ret = get_errno(listxattr(p, b, arg3));
8530            } else {
8531                ret = get_errno(llistxattr(p, b, arg3));
8532            }
8533        } else {
8534            ret = -TARGET_EFAULT;
8535        }
8536        unlock_user(p, arg1, 0);
8537        unlock_user(b, arg2, arg3);
8538        break;
8539    }
8540    case TARGET_NR_flistxattr:
8541    {
8542        void *b = 0;
8543        if (arg2) {
8544            b = lock_user(VERIFY_WRITE, arg2, arg3, 0);
8545            if (!b) {
8546                ret = -TARGET_EFAULT;
8547                break;
8548            }
8549        }
8550        ret = get_errno(flistxattr(arg1, b, arg3));
8551        unlock_user(b, arg2, arg3);
8552        break;
8553    }
8554    case TARGET_NR_setxattr:
8555    case TARGET_NR_lsetxattr:
8556        {
8557            void *p, *n, *v = 0;
8558            if (arg3) {
8559                v = lock_user(VERIFY_READ, arg3, arg4, 1);
8560                if (!v) {
8561                    ret = -TARGET_EFAULT;
8562                    break;
8563                }
8564            }
8565            p = lock_user_string(arg1);
8566            n = lock_user_string(arg2);
8567            if (p && n) {
8568                if (num == TARGET_NR_setxattr) {
8569                    ret = get_errno(setxattr(p, n, v, arg4, arg5));
8570                } else {
8571                    ret = get_errno(lsetxattr(p, n, v, arg4, arg5));
8572                }
8573            } else {
8574                ret = -TARGET_EFAULT;
8575            }
8576            unlock_user(p, arg1, 0);
8577            unlock_user(n, arg2, 0);
8578            unlock_user(v, arg3, 0);
8579        }
8580        break;
8581    case TARGET_NR_fsetxattr:
8582        {
8583            void *n, *v = 0;
8584            if (arg3) {
8585                v = lock_user(VERIFY_READ, arg3, arg4, 1);
8586                if (!v) {
8587                    ret = -TARGET_EFAULT;
8588                    break;
8589                }
8590            }
8591            n = lock_user_string(arg2);
8592            if (n) {
8593                ret = get_errno(fsetxattr(arg1, n, v, arg4, arg5));
8594            } else {
8595                ret = -TARGET_EFAULT;
8596            }
8597            unlock_user(n, arg2, 0);
8598            unlock_user(v, arg3, 0);
8599        }
8600        break;
8601    case TARGET_NR_getxattr:
8602    case TARGET_NR_lgetxattr:
8603        {
8604            void *p, *n, *v = 0;
8605            if (arg3) {
8606                v = lock_user(VERIFY_WRITE, arg3, arg4, 0);
8607                if (!v) {
8608                    ret = -TARGET_EFAULT;
8609                    break;
8610                }
8611            }
8612            p = lock_user_string(arg1);
8613            n = lock_user_string(arg2);
8614            if (p && n) {
8615                if (num == TARGET_NR_getxattr) {
8616                    ret = get_errno(getxattr(p, n, v, arg4));
8617                } else {
8618                    ret = get_errno(lgetxattr(p, n, v, arg4));
8619                }
8620            } else {
8621                ret = -TARGET_EFAULT;
8622            }
8623            unlock_user(p, arg1, 0);
8624            unlock_user(n, arg2, 0);
8625            unlock_user(v, arg3, arg4);
8626        }
8627        break;
8628    case TARGET_NR_fgetxattr:
8629        {
8630            void *n, *v = 0;
8631            if (arg3) {
8632                v = lock_user(VERIFY_WRITE, arg3, arg4, 0);
8633                if (!v) {
8634                    ret = -TARGET_EFAULT;
8635                    break;
8636                }
8637            }
8638            n = lock_user_string(arg2);
8639            if (n) {
8640                ret = get_errno(fgetxattr(arg1, n, v, arg4));
8641            } else {
8642                ret = -TARGET_EFAULT;
8643            }
8644            unlock_user(n, arg2, 0);
8645            unlock_user(v, arg3, arg4);
8646        }
8647        break;
8648    case TARGET_NR_removexattr:
8649    case TARGET_NR_lremovexattr:
8650        {
8651            void *p, *n;
8652            p = lock_user_string(arg1);
8653            n = lock_user_string(arg2);
8654            if (p && n) {
8655                if (num == TARGET_NR_removexattr) {
8656                    ret = get_errno(removexattr(p, n));
8657                } else {
8658                    ret = get_errno(lremovexattr(p, n));
8659                }
8660            } else {
8661                ret = -TARGET_EFAULT;
8662            }
8663            unlock_user(p, arg1, 0);
8664            unlock_user(n, arg2, 0);
8665        }
8666        break;
8667    case TARGET_NR_fremovexattr:
8668        {
8669            void *n;
8670            n = lock_user_string(arg2);
8671            if (n) {
8672                ret = get_errno(fremovexattr(arg1, n));
8673            } else {
8674                ret = -TARGET_EFAULT;
8675            }
8676            unlock_user(n, arg2, 0);
8677        }
8678        break;
8679#endif
8680#endif /* CONFIG_ATTR */
8681#ifdef TARGET_NR_set_thread_area
8682    case TARGET_NR_set_thread_area:
8683#if defined(TARGET_MIPS)
8684      ((CPUMIPSState *) cpu_env)->tls_value = arg1;
8685      ret = 0;
8686      break;
8687#elif defined(TARGET_CRIS)
8688      if (arg1 & 0xff)
8689          ret = -TARGET_EINVAL;
8690      else {
8691          ((CPUCRISState *) cpu_env)->pregs[PR_PID] = arg1;
8692          ret = 0;
8693      }
8694      break;
8695#elif defined(TARGET_I386) && defined(TARGET_ABI32)
8696      ret = do_set_thread_area(cpu_env, arg1);
8697      break;
8698#elif defined(TARGET_M68K)
8699      {
8700          TaskState *ts = ((CPUArchState *)cpu_env)->opaque;
8701          ts->tp_value = arg1;
8702          ret = 0;
8703          break;
8704      }
8705#else
8706      goto unimplemented_nowarn;
8707#endif
8708#endif
8709#ifdef TARGET_NR_get_thread_area
8710    case TARGET_NR_get_thread_area:
8711#if defined(TARGET_I386) && defined(TARGET_ABI32)
8712        ret = do_get_thread_area(cpu_env, arg1);
8713        break;
8714#elif defined(TARGET_M68K)
8715        {
8716            TaskState *ts = ((CPUArchState *)cpu_env)->opaque;
8717            ret = ts->tp_value;
8718            break;
8719        }
8720#else
8721        goto unimplemented_nowarn;
8722#endif
8723#endif
8724#ifdef TARGET_NR_getdomainname
8725    case TARGET_NR_getdomainname:
8726        goto unimplemented_nowarn;
8727#endif
8728
8729#ifdef TARGET_NR_clock_gettime
8730    case TARGET_NR_clock_gettime:
8731    {
8732        struct timespec ts;
8733        ret = get_errno(clock_gettime(arg1, &ts));
8734        if (!is_error(ret)) {
8735            host_to_target_timespec(arg2, &ts);
8736        }
8737        break;
8738    }
8739#endif
8740#ifdef TARGET_NR_clock_getres
8741    case TARGET_NR_clock_getres:
8742    {
8743        struct timespec ts;
8744        ret = get_errno(clock_getres(arg1, &ts));
8745        if (!is_error(ret)) {
8746            host_to_target_timespec(arg2, &ts);
8747        }
8748        break;
8749    }
8750#endif
8751#ifdef TARGET_NR_clock_nanosleep
8752    case TARGET_NR_clock_nanosleep:
8753    {
8754        struct timespec ts;
8755        target_to_host_timespec(&ts, arg3);
8756        ret = get_errno(clock_nanosleep(arg1, arg2, &ts, arg4 ? &ts : NULL));
8757        if (arg4)
8758            host_to_target_timespec(arg4, &ts);
8759        break;
8760    }
8761#endif
8762
8763#if defined(TARGET_NR_set_tid_address) && defined(__NR_set_tid_address)
8764    case TARGET_NR_set_tid_address:
8765        ret = get_errno(set_tid_address((int *)g2h(arg1)));
8766        break;
8767#endif
8768
8769#if defined(TARGET_NR_tkill) && defined(__NR_tkill)
8770    case TARGET_NR_tkill:
8771        ret = get_errno(sys_tkill((int)arg1, target_to_host_signal(arg2)));
8772        break;
8773#endif
8774
8775#if defined(TARGET_NR_tgkill) && defined(__NR_tgkill)
8776    case TARGET_NR_tgkill:
8777        ret = get_errno(sys_tgkill((int)arg1, (int)arg2,
8778                        target_to_host_signal(arg3)));
8779        break;
8780#endif
8781
8782#ifdef TARGET_NR_set_robust_list
8783    case TARGET_NR_set_robust_list:
8784    case TARGET_NR_get_robust_list:
8785        /* The ABI for supporting robust futexes has userspace pass
8786         * the kernel a pointer to a linked list which is updated by
8787         * userspace after the syscall; the list is walked by the kernel
8788         * when the thread exits. Since the linked list in QEMU guest
8789         * memory isn't a valid linked list for the host and we have
8790         * no way to reliably intercept the thread-death event, we can't
8791         * support these. Silently return ENOSYS so that guest userspace
8792         * falls back to a non-robust futex implementation (which should
8793         * be OK except in the corner case of the guest crashing while
8794         * holding a mutex that is shared with another process via
8795         * shared memory).
8796         */
8797        goto unimplemented_nowarn;
8798#endif
8799
8800#if defined(TARGET_NR_utimensat)
8801    case TARGET_NR_utimensat:
8802        {
8803            struct timespec *tsp, ts[2];
8804            if (!arg3) {
8805                tsp = NULL;
8806            } else {
8807                target_to_host_timespec(ts, arg3);
8808                target_to_host_timespec(ts+1, arg3+sizeof(struct target_timespec));
8809                tsp = ts;
8810            }
8811            if (!arg2)
8812                ret = get_errno(sys_utimensat(arg1, NULL, tsp, arg4));
8813            else {
8814                if (!(p = lock_user_string(arg2))) {
8815                    ret = -TARGET_EFAULT;
8816                    goto fail;
8817                }
8818                ret = get_errno(sys_utimensat(arg1, path(p), tsp, arg4));
8819                unlock_user(p, arg2, 0);
8820            }
8821        }
8822        break;
8823#endif
8824    case TARGET_NR_futex:
8825        ret = do_futex(arg1, arg2, arg3, arg4, arg5, arg6);
8826        break;
8827#if defined(TARGET_NR_inotify_init) && defined(__NR_inotify_init)
8828    case TARGET_NR_inotify_init:
8829        ret = get_errno(sys_inotify_init());
8830        break;
8831#endif
8832#ifdef CONFIG_INOTIFY1
8833#if defined(TARGET_NR_inotify_init1) && defined(__NR_inotify_init1)
8834    case TARGET_NR_inotify_init1:
8835        ret = get_errno(sys_inotify_init1(arg1));
8836        break;
8837#endif
8838#endif
8839#if defined(TARGET_NR_inotify_add_watch) && defined(__NR_inotify_add_watch)
8840    case TARGET_NR_inotify_add_watch:
8841        p = lock_user_string(arg2);
8842        ret = get_errno(sys_inotify_add_watch(arg1, path(p), arg3));
8843        unlock_user(p, arg2, 0);
8844        break;
8845#endif
8846#if defined(TARGET_NR_inotify_rm_watch) && defined(__NR_inotify_rm_watch)
8847    case TARGET_NR_inotify_rm_watch:
8848        ret = get_errno(sys_inotify_rm_watch(arg1, arg2));
8849        break;
8850#endif
8851
8852#if defined(TARGET_NR_mq_open) && defined(__NR_mq_open)
8853    case TARGET_NR_mq_open:
8854        {
8855            struct mq_attr posix_mq_attr;
8856
8857            p = lock_user_string(arg1 - 1);
8858            if (arg4 != 0)
8859                copy_from_user_mq_attr (&posix_mq_attr, arg4);
8860            ret = get_errno(mq_open(p, arg2, arg3, &posix_mq_attr));
8861            unlock_user (p, arg1, 0);
8862        }
8863        break;
8864
8865    case TARGET_NR_mq_unlink:
8866        p = lock_user_string(arg1 - 1);
8867        ret = get_errno(mq_unlink(p));
8868        unlock_user (p, arg1, 0);
8869        break;
8870
8871    case TARGET_NR_mq_timedsend:
8872        {
8873            struct timespec ts;
8874
8875            p = lock_user (VERIFY_READ, arg2, arg3, 1);
8876            if (arg5 != 0) {
8877                target_to_host_timespec(&ts, arg5);
8878                ret = get_errno(mq_timedsend(arg1, p, arg3, arg4, &ts));
8879                host_to_target_timespec(arg5, &ts);
8880            }
8881            else
8882                ret = get_errno(mq_send(arg1, p, arg3, arg4));
8883            unlock_user (p, arg2, arg3);
8884        }
8885        break;
8886
8887    case TARGET_NR_mq_timedreceive:
8888        {
8889            struct timespec ts;
8890            unsigned int prio;
8891
8892            p = lock_user (VERIFY_READ, arg2, arg3, 1);
8893            if (arg5 != 0) {
8894                target_to_host_timespec(&ts, arg5);
8895                ret = get_errno(mq_timedreceive(arg1, p, arg3, &prio, &ts));
8896                host_to_target_timespec(arg5, &ts);
8897            }
8898            else
8899                ret = get_errno(mq_receive(arg1, p, arg3, &prio));
8900            unlock_user (p, arg2, arg3);
8901            if (arg4 != 0)
8902                put_user_u32(prio, arg4);
8903        }
8904        break;
8905
8906    /* Not implemented for now... */
8907/*     case TARGET_NR_mq_notify: */
8908/*         break; */
8909
8910    case TARGET_NR_mq_getsetattr:
8911        {
8912            struct mq_attr posix_mq_attr_in, posix_mq_attr_out;
8913            ret = 0;
8914            if (arg3 != 0) {
8915                ret = mq_getattr(arg1, &posix_mq_attr_out);
8916                copy_to_user_mq_attr(arg3, &posix_mq_attr_out);
8917            }
8918            if (arg2 != 0) {
8919                copy_from_user_mq_attr(&posix_mq_attr_in, arg2);
8920                ret |= mq_setattr(arg1, &posix_mq_attr_in, &posix_mq_attr_out);
8921            }
8922
8923        }
8924        break;
8925#endif
8926
8927#ifdef CONFIG_SPLICE
8928#ifdef TARGET_NR_tee
8929    case TARGET_NR_tee:
8930        {
8931            ret = get_errno(tee(arg1,arg2,arg3,arg4));
8932        }
8933        break;
8934#endif
8935#ifdef TARGET_NR_splice
8936    case TARGET_NR_splice:
8937        {
8938            loff_t loff_in, loff_out;
8939            loff_t *ploff_in = NULL, *ploff_out = NULL;
8940            if(arg2) {
8941                get_user_u64(loff_in, arg2);
8942                ploff_in = &loff_in;
8943            }
8944            if(arg4) {
8945                get_user_u64(loff_out, arg2);
8946                ploff_out = &loff_out;
8947            }
8948            ret = get_errno(splice(arg1, ploff_in, arg3, ploff_out, arg5, arg6));
8949        }
8950        break;
8951#endif
8952#ifdef TARGET_NR_vmsplice
8953        case TARGET_NR_vmsplice:
8954        {
8955            struct iovec *vec = lock_iovec(VERIFY_READ, arg2, arg3, 1);
8956            if (vec != NULL) {
8957                ret = get_errno(vmsplice(arg1, vec, arg3, arg4));
8958                unlock_iovec(vec, arg2, arg3, 0);
8959            } else {
8960                ret = -host_to_target_errno(errno);
8961            }
8962        }
8963        break;
8964#endif
8965#endif /* CONFIG_SPLICE */
8966#ifdef CONFIG_EVENTFD
8967#if defined(TARGET_NR_eventfd)
8968    case TARGET_NR_eventfd:
8969        ret = get_errno(eventfd(arg1, 0));
8970        break;
8971#endif
8972#if defined(TARGET_NR_eventfd2)
8973    case TARGET_NR_eventfd2:
8974    {
8975        int host_flags = arg2 & (~(TARGET_O_NONBLOCK | TARGET_O_CLOEXEC));
8976        if (arg2 & TARGET_O_NONBLOCK) {
8977            host_flags |= O_NONBLOCK;
8978        }
8979        if (arg2 & TARGET_O_CLOEXEC) {
8980            host_flags |= O_CLOEXEC;
8981        }
8982        ret = get_errno(eventfd(arg1, host_flags));
8983        break;
8984    }
8985#endif
8986#endif /* CONFIG_EVENTFD  */
8987#if defined(CONFIG_FALLOCATE) && defined(TARGET_NR_fallocate)
8988    case TARGET_NR_fallocate:
8989#if TARGET_ABI_BITS == 32
8990        ret = get_errno(fallocate(arg1, arg2, target_offset64(arg3, arg4),
8991                                  target_offset64(arg5, arg6)));
8992#else
8993        ret = get_errno(fallocate(arg1, arg2, arg3, arg4));
8994#endif
8995        break;
8996#endif
8997#if defined(CONFIG_SYNC_FILE_RANGE)
8998#if defined(TARGET_NR_sync_file_range)
8999    case TARGET_NR_sync_file_range:
9000#if TARGET_ABI_BITS == 32
9001#if defined(TARGET_MIPS)
9002        ret = get_errno(sync_file_range(arg1, target_offset64(arg3, arg4),
9003                                        target_offset64(arg5, arg6), arg7));
9004#else
9005        ret = get_errno(sync_file_range(arg1, target_offset64(arg2, arg3),
9006                                        target_offset64(arg4, arg5), arg6));
9007#endif /* !TARGET_MIPS */
9008#else
9009        ret = get_errno(sync_file_range(arg1, arg2, arg3, arg4));
9010#endif
9011        break;
9012#endif
9013#if defined(TARGET_NR_sync_file_range2)
9014    case TARGET_NR_sync_file_range2:
9015        /* This is like sync_file_range but the arguments are reordered */
9016#if TARGET_ABI_BITS == 32
9017        ret = get_errno(sync_file_range(arg1, target_offset64(arg3, arg4),
9018                                        target_offset64(arg5, arg6), arg2));
9019#else
9020        ret = get_errno(sync_file_range(arg1, arg3, arg4, arg2));
9021#endif
9022        break;
9023#endif
9024#endif
9025#if defined(CONFIG_EPOLL)
9026#if defined(TARGET_NR_epoll_create)
9027    case TARGET_NR_epoll_create:
9028        ret = get_errno(epoll_create(arg1));
9029        break;
9030#endif
9031#if defined(TARGET_NR_epoll_create1) && defined(CONFIG_EPOLL_CREATE1)
9032    case TARGET_NR_epoll_create1:
9033        ret = get_errno(epoll_create1(arg1));
9034        break;
9035#endif
9036#if defined(TARGET_NR_epoll_ctl)
9037    case TARGET_NR_epoll_ctl:
9038    {
9039        struct epoll_event ep;
9040        struct epoll_event *epp = 0;
9041        if (arg4) {
9042            struct target_epoll_event *target_ep;
9043            if (!lock_user_struct(VERIFY_READ, target_ep, arg4, 1)) {
9044                goto efault;
9045            }
9046            ep.events = tswap32(target_ep->events);
9047            /* The epoll_data_t union is just opaque data to the kernel,
9048             * so we transfer all 64 bits across and need not worry what
9049             * actual data type it is.
9050             */
9051            ep.data.u64 = tswap64(target_ep->data.u64);
9052            unlock_user_struct(target_ep, arg4, 0);
9053            epp = &ep;
9054        }
9055        ret = get_errno(epoll_ctl(arg1, arg2, arg3, epp));
9056        break;
9057    }
9058#endif
9059
9060#if defined(TARGET_NR_epoll_pwait) && defined(CONFIG_EPOLL_PWAIT)
9061#define IMPLEMENT_EPOLL_PWAIT
9062#endif
9063#if defined(TARGET_NR_epoll_wait) || defined(IMPLEMENT_EPOLL_PWAIT)
9064#if defined(TARGET_NR_epoll_wait)
9065    case TARGET_NR_epoll_wait:
9066#endif
9067#if defined(IMPLEMENT_EPOLL_PWAIT)
9068    case TARGET_NR_epoll_pwait:
9069#endif
9070    {
9071        struct target_epoll_event *target_ep;
9072        struct epoll_event *ep;
9073        int epfd = arg1;
9074        int maxevents = arg3;
9075        int timeout = arg4;
9076
9077        target_ep = lock_user(VERIFY_WRITE, arg2,
9078                              maxevents * sizeof(struct target_epoll_event), 1);
9079        if (!target_ep) {
9080            goto efault;
9081        }
9082
9083        ep = alloca(maxevents * sizeof(struct epoll_event));
9084
9085        switch (num) {
9086#if defined(IMPLEMENT_EPOLL_PWAIT)
9087        case TARGET_NR_epoll_pwait:
9088        {
9089            target_sigset_t *target_set;
9090            sigset_t _set, *set = &_set;
9091
9092            if (arg5) {
9093                target_set = lock_user(VERIFY_READ, arg5,
9094                                       sizeof(target_sigset_t), 1);
9095                if (!target_set) {
9096                    unlock_user(target_ep, arg2, 0);
9097                    goto efault;
9098                }
9099                target_to_host_sigset(set, target_set);
9100                unlock_user(target_set, arg5, 0);
9101            } else {
9102                set = NULL;
9103            }
9104
9105            ret = get_errno(epoll_pwait(epfd, ep, maxevents, timeout, set));
9106            break;
9107        }
9108#endif
9109#if defined(TARGET_NR_epoll_wait)
9110        case TARGET_NR_epoll_wait:
9111            ret = get_errno(epoll_wait(epfd, ep, maxevents, timeout));
9112            break;
9113#endif
9114        default:
9115            ret = -TARGET_ENOSYS;
9116        }
9117        if (!is_error(ret)) {
9118            int i;
9119            for (i = 0; i < ret; i++) {
9120                target_ep[i].events = tswap32(ep[i].events);
9121                target_ep[i].data.u64 = tswap64(ep[i].data.u64);
9122            }
9123        }
9124        unlock_user(target_ep, arg2, ret * sizeof(struct target_epoll_event));
9125        break;
9126    }
9127#endif
9128#endif
9129#ifdef TARGET_NR_prlimit64
9130    case TARGET_NR_prlimit64:
9131    {
9132        /* args: pid, resource number, ptr to new rlimit, ptr to old rlimit */
9133        struct target_rlimit64 *target_rnew, *target_rold;
9134        struct host_rlimit64 rnew, rold, *rnewp = 0;
9135        if (arg3) {
9136            if (!lock_user_struct(VERIFY_READ, target_rnew, arg3, 1)) {
9137                goto efault;
9138            }
9139            rnew.rlim_cur = tswap64(target_rnew->rlim_cur);
9140            rnew.rlim_max = tswap64(target_rnew->rlim_max);
9141            unlock_user_struct(target_rnew, arg3, 0);
9142            rnewp = &rnew;
9143        }
9144
9145        ret = get_errno(sys_prlimit64(arg1, arg2, rnewp, arg4 ? &rold : 0));
9146        if (!is_error(ret) && arg4) {
9147            if (!lock_user_struct(VERIFY_WRITE, target_rold, arg4, 1)) {
9148                goto efault;
9149            }
9150            target_rold->rlim_cur = tswap64(rold.rlim_cur);
9151            target_rold->rlim_max = tswap64(rold.rlim_max);
9152            unlock_user_struct(target_rold, arg4, 1);
9153        }
9154        break;
9155    }
9156#endif
9157#ifdef TARGET_NR_gethostname
9158    case TARGET_NR_gethostname:
9159    {
9160        char *name = lock_user(VERIFY_WRITE, arg1, arg2, 0);
9161        if (name) {
9162            ret = get_errno(gethostname(name, arg2));
9163            unlock_user(name, arg1, arg2);
9164        } else {
9165            ret = -TARGET_EFAULT;
9166        }
9167        break;
9168    }
9169#endif
9170#ifdef TARGET_NR_atomic_cmpxchg_32
9171    case TARGET_NR_atomic_cmpxchg_32:
9172    {
9173        /* should use start_exclusive from main.c */
9174        abi_ulong mem_value;
9175        if (get_user_u32(mem_value, arg6)) {
9176            target_siginfo_t info;
9177            info.si_signo = SIGSEGV;
9178            info.si_errno = 0;
9179            info.si_code = TARGET_SEGV_MAPERR;
9180            info._sifields._sigfault._addr = arg6;
9181            queue_signal((CPUArchState *)cpu_env, info.si_signo, &info);
9182            ret = 0xdeadbeef;
9183
9184        }
9185        if (mem_value == arg2)
9186            put_user_u32(arg1, arg6);
9187        ret = mem_value;
9188        break;
9189    }
9190#endif
9191#ifdef TARGET_NR_atomic_barrier
9192    case TARGET_NR_atomic_barrier:
9193    {
9194        /* Like the kernel implementation and the qemu arm barrier, no-op this? */
9195        break;
9196    }
9197#endif
9198    default:
9199    unimplemented:
9200        gemu_log("qemu: Unsupported syscall: %d\n", num);
9201#if defined(TARGET_NR_setxattr) || defined(TARGET_NR_get_thread_area) || defined(TARGET_NR_getdomainname) || defined(TARGET_NR_set_robust_list)
9202    unimplemented_nowarn:
9203#endif
9204        ret = -TARGET_ENOSYS;
9205        break;
9206    }
9207fail:
9208#ifdef DEBUG
9209    gemu_log(" = " TARGET_ABI_FMT_ld "\n", ret);
9210#endif
9211    if(do_strace)
9212        print_syscall_ret(num, ret);
9213    return ret;
9214efault:
9215    ret = -TARGET_EFAULT;
9216    goto fail;
9217}
9218