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