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