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)