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