f986548c2dc62154a862ec90e33eaafa12d5e78b
[external/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 #ifdef TARGET_ARM
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 int get_osversion(void)
4867 {
4868     static int osversion;
4869     struct new_utsname buf;
4870     const char *s;
4871     int i, n, tmp;
4872     if (osversion)
4873         return osversion;
4874     if (qemu_uname_release && *qemu_uname_release) {
4875         s = qemu_uname_release;
4876     } else {
4877         if (sys_uname(&buf))
4878             return 0;
4879         s = buf.release;
4880     }
4881     tmp = 0;
4882     for (i = 0; i < 3; i++) {
4883         n = 0;
4884         while (*s >= '0' && *s <= '9') {
4885             n *= 10;
4886             n += *s - '0';
4887             s++;
4888         }
4889         tmp = (tmp << 8) + n;
4890         if (*s == '.')
4891             s++;
4892     }
4893     osversion = tmp;
4894     return osversion;
4895 }
4896
4897
4898 static int open_self_maps(void *cpu_env, int fd)
4899 {
4900 #if defined(TARGET_ARM) || defined(TARGET_M68K) || defined(TARGET_UNICORE32)
4901     TaskState *ts = ((CPUArchState *)cpu_env)->opaque;
4902 #endif
4903     FILE *fp;
4904     char *line = NULL;
4905     size_t len = 0;
4906     ssize_t read;
4907
4908     fp = fopen("/proc/self/maps", "r");
4909     if (fp == NULL) {
4910         return -EACCES;
4911     }
4912
4913     while ((read = getline(&line, &len, fp)) != -1) {
4914         int fields, dev_maj, dev_min, inode;
4915         uint64_t min, max, offset;
4916         char flag_r, flag_w, flag_x, flag_p;
4917         char path[512] = "";
4918         fields = sscanf(line, "%"PRIx64"-%"PRIx64" %c%c%c%c %"PRIx64" %x:%x %d"
4919                         " %512s", &min, &max, &flag_r, &flag_w, &flag_x,
4920                         &flag_p, &offset, &dev_maj, &dev_min, &inode, path);
4921
4922         if ((fields < 10) || (fields > 11)) {
4923             continue;
4924         }
4925         if (!strncmp(path, "[stack]", 7)) {
4926             continue;
4927         }
4928         if (h2g_valid(min) && h2g_valid(max)) {
4929             dprintf(fd, TARGET_ABI_FMT_lx "-" TARGET_ABI_FMT_lx
4930                     " %c%c%c%c %08" PRIx64 " %02x:%02x %d %s%s\n",
4931                     h2g(min), h2g(max), flag_r, flag_w,
4932                     flag_x, flag_p, offset, dev_maj, dev_min, inode,
4933                     path[0] ? "         " : "", path);
4934         }
4935     }
4936
4937     free(line);
4938     fclose(fp);
4939
4940 #if defined(TARGET_ARM) || defined(TARGET_M68K) || defined(TARGET_UNICORE32)
4941     dprintf(fd, "%08llx-%08llx rw-p %08llx 00:00 0          [stack]\n",
4942                 (unsigned long long)ts->info->stack_limit,
4943                 (unsigned long long)(ts->info->start_stack +
4944                                      (TARGET_PAGE_SIZE - 1)) & TARGET_PAGE_MASK,
4945                 (unsigned long long)0);
4946 #endif
4947
4948     return 0;
4949 }
4950
4951 static int open_self_stat(void *cpu_env, int fd)
4952 {
4953     TaskState *ts = ((CPUArchState *)cpu_env)->opaque;
4954     abi_ulong start_stack = ts->info->start_stack;
4955     int i;
4956
4957     for (i = 0; i < 44; i++) {
4958       char buf[128];
4959       int len;
4960       uint64_t val = 0;
4961
4962       if (i == 0) {
4963         /* pid */
4964         val = getpid();
4965         snprintf(buf, sizeof(buf), "%"PRId64 " ", val);
4966       } else if (i == 1) {
4967         /* app name */
4968         snprintf(buf, sizeof(buf), "(%s) ", ts->bprm->argv[0]);
4969       } else if (i == 27) {
4970         /* stack bottom */
4971         val = start_stack;
4972         snprintf(buf, sizeof(buf), "%"PRId64 " ", val);
4973       } else {
4974         /* for the rest, there is MasterCard */
4975         snprintf(buf, sizeof(buf), "0%c", i == 43 ? '\n' : ' ');
4976       }
4977
4978       len = strlen(buf);
4979       if (write(fd, buf, len) != len) {
4980           return -1;
4981       }
4982     }
4983
4984     return 0;
4985 }
4986
4987 static int open_self_auxv(void *cpu_env, int fd)
4988 {
4989     TaskState *ts = ((CPUArchState *)cpu_env)->opaque;
4990     abi_ulong auxv = ts->info->saved_auxv;
4991     abi_ulong len = ts->info->auxv_len;
4992     char *ptr;
4993
4994     /*
4995      * Auxiliary vector is stored in target process stack.
4996      * read in whole auxv vector and copy it to file
4997      */
4998     ptr = lock_user(VERIFY_READ, auxv, len, 0);
4999     if (ptr != NULL) {
5000         while (len > 0) {
5001             ssize_t r;
5002             r = write(fd, ptr, len);
5003             if (r <= 0) {
5004                 break;
5005             }
5006             len -= r;
5007             ptr += r;
5008         }
5009         lseek(fd, 0, SEEK_SET);
5010         unlock_user(ptr, auxv, len);
5011     }
5012
5013     return 0;
5014 }
5015
5016 static int is_proc_myself(const char *filename, const char *entry)
5017 {
5018     if (!strncmp(filename, "/proc/", strlen("/proc/"))) {
5019         filename += strlen("/proc/");
5020         if (!strncmp(filename, "self/", strlen("self/"))) {
5021             filename += strlen("self/");
5022         } else if (*filename >= '1' && *filename <= '9') {
5023             char myself[80];
5024             snprintf(myself, sizeof(myself), "%d/", getpid());
5025             if (!strncmp(filename, myself, strlen(myself))) {
5026                 filename += strlen(myself);
5027             } else {
5028                 return 0;
5029             }
5030         } else {
5031             return 0;
5032         }
5033         if (!strcmp(filename, entry)) {
5034             return 1;
5035         }
5036     }
5037     return 0;
5038 }
5039
5040 static int do_open(void *cpu_env, const char *pathname, int flags, mode_t mode)
5041 {
5042     struct fake_open {
5043         const char *filename;
5044         int (*fill)(void *cpu_env, int fd);
5045     };
5046     const struct fake_open *fake_open;
5047     static const struct fake_open fakes[] = {
5048         { "maps", open_self_maps },
5049         { "stat", open_self_stat },
5050         { "auxv", open_self_auxv },
5051         { NULL, NULL }
5052     };
5053
5054     for (fake_open = fakes; fake_open->filename; fake_open++) {
5055         if (is_proc_myself(pathname, fake_open->filename)) {
5056             break;
5057         }
5058     }
5059
5060     if (fake_open->filename) {
5061         const char *tmpdir;
5062         char filename[PATH_MAX];
5063         int fd, r;
5064
5065         /* create temporary file to map stat to */
5066         tmpdir = getenv("TMPDIR");
5067         if (!tmpdir)
5068             tmpdir = "/tmp";
5069         snprintf(filename, sizeof(filename), "%s/qemu-open.XXXXXX", tmpdir);
5070         fd = mkstemp(filename);
5071         if (fd < 0) {
5072             return fd;
5073         }
5074         unlink(filename);
5075
5076         if ((r = fake_open->fill(cpu_env, fd))) {
5077             close(fd);
5078             return r;
5079         }
5080         lseek(fd, 0, SEEK_SET);
5081
5082         return fd;
5083     }
5084
5085     return get_errno(open(path(pathname), flags, mode));
5086 }
5087
5088 /* do_syscall() should always have a single exit point at the end so
5089    that actions, such as logging of syscall results, can be performed.
5090    All errnos that do_syscall() returns must be -TARGET_<errcode>. */
5091 abi_long do_syscall(void *cpu_env, int num, abi_long arg1,
5092                     abi_long arg2, abi_long arg3, abi_long arg4,
5093                     abi_long arg5, abi_long arg6, abi_long arg7,
5094                     abi_long arg8)
5095 {
5096     CPUState *cpu = ENV_GET_CPU(cpu_env);
5097     abi_long ret;
5098     struct stat st;
5099     struct statfs stfs;
5100     void *p;
5101
5102 #ifdef DEBUG
5103     gemu_log("syscall %d", num);
5104 #endif
5105     if(do_strace)
5106         print_syscall(num, arg1, arg2, arg3, arg4, arg5, arg6);
5107
5108     switch(num) {
5109     case TARGET_NR_exit:
5110         /* In old applications this may be used to implement _exit(2).
5111            However in threaded applictions it is used for thread termination,
5112            and _exit_group is used for application termination.
5113            Do thread termination if we have more then one thread.  */
5114         /* FIXME: This probably breaks if a signal arrives.  We should probably
5115            be disabling signals.  */
5116         if (first_cpu->next_cpu) {
5117             TaskState *ts;
5118             CPUState **lastp;
5119             CPUState *p;
5120
5121             cpu_list_lock();
5122             lastp = &first_cpu;
5123             p = first_cpu;
5124             while (p && p != cpu) {
5125                 lastp = &p->next_cpu;
5126                 p = p->next_cpu;
5127             }
5128             /* If we didn't find the CPU for this thread then something is
5129                horribly wrong.  */
5130             if (!p) {
5131                 abort();
5132             }
5133             /* Remove the CPU from the list.  */
5134             *lastp = p->next_cpu;
5135             cpu_list_unlock();
5136             ts = ((CPUArchState *)cpu_env)->opaque;
5137             if (ts->child_tidptr) {
5138                 put_user_u32(0, ts->child_tidptr);
5139                 sys_futex(g2h(ts->child_tidptr), FUTEX_WAKE, INT_MAX,
5140                           NULL, NULL, 0);
5141             }
5142             thread_cpu = NULL;
5143             object_unref(OBJECT(ENV_GET_CPU(cpu_env)));
5144             g_free(ts);
5145             pthread_exit(NULL);
5146         }
5147 #ifdef TARGET_GPROF
5148         _mcleanup();
5149 #endif
5150         gdb_exit(cpu_env, arg1);
5151         _exit(arg1);
5152         ret = 0; /* avoid warning */
5153         break;
5154     case TARGET_NR_read:
5155         if (arg3 == 0)
5156             ret = 0;
5157         else {
5158             if (!(p = lock_user(VERIFY_WRITE, arg2, arg3, 0)))
5159                 goto efault;
5160             ret = get_errno(read(arg1, p, arg3));
5161             unlock_user(p, arg2, ret);
5162         }
5163         break;
5164     case TARGET_NR_write:
5165         if (!(p = lock_user(VERIFY_READ, arg2, arg3, 1)))
5166             goto efault;
5167         ret = get_errno(write(arg1, p, arg3));
5168         unlock_user(p, arg2, 0);
5169         break;
5170     case TARGET_NR_open:
5171         if (!(p = lock_user_string(arg1)))
5172             goto efault;
5173         ret = get_errno(do_open(cpu_env, p,
5174                                 target_to_host_bitmask(arg2, fcntl_flags_tbl),
5175                                 arg3));
5176         unlock_user(p, arg1, 0);
5177         break;
5178 #if defined(TARGET_NR_openat) && defined(__NR_openat)
5179     case TARGET_NR_openat:
5180         if (!(p = lock_user_string(arg2)))
5181             goto efault;
5182         ret = get_errno(sys_openat(arg1,
5183                                    path(p),
5184                                    target_to_host_bitmask(arg3, fcntl_flags_tbl),
5185                                    arg4));
5186         unlock_user(p, arg2, 0);
5187         break;
5188 #endif
5189     case TARGET_NR_close:
5190         ret = get_errno(close(arg1));
5191         break;
5192     case TARGET_NR_brk:
5193         ret = do_brk(arg1);
5194         break;
5195     case TARGET_NR_fork:
5196         ret = get_errno(do_fork(cpu_env, SIGCHLD, 0, 0, 0, 0));
5197         break;
5198 #ifdef TARGET_NR_waitpid
5199     case TARGET_NR_waitpid:
5200         {
5201             int status;
5202             ret = get_errno(waitpid(arg1, &status, arg3));
5203             if (!is_error(ret) && arg2 && ret
5204                 && put_user_s32(host_to_target_waitstatus(status), arg2))
5205                 goto efault;
5206         }
5207         break;
5208 #endif
5209 #ifdef TARGET_NR_waitid
5210     case TARGET_NR_waitid:
5211         {
5212             siginfo_t info;
5213             info.si_pid = 0;
5214             ret = get_errno(waitid(arg1, arg2, &info, arg4));
5215             if (!is_error(ret) && arg3 && info.si_pid != 0) {
5216                 if (!(p = lock_user(VERIFY_WRITE, arg3, sizeof(target_siginfo_t), 0)))
5217                     goto efault;
5218                 host_to_target_siginfo(p, &info);
5219                 unlock_user(p, arg3, sizeof(target_siginfo_t));
5220             }
5221         }
5222         break;
5223 #endif
5224 #ifdef TARGET_NR_creat /* not on alpha */
5225     case TARGET_NR_creat:
5226         if (!(p = lock_user_string(arg1)))
5227             goto efault;
5228         ret = get_errno(creat(p, arg2));
5229         unlock_user(p, arg1, 0);
5230         break;
5231 #endif
5232     case TARGET_NR_link:
5233         {
5234             void * p2;
5235             p = lock_user_string(arg1);
5236             p2 = lock_user_string(arg2);
5237             if (!p || !p2)
5238                 ret = -TARGET_EFAULT;
5239             else
5240                 ret = get_errno(link(p, p2));
5241             unlock_user(p2, arg2, 0);
5242             unlock_user(p, arg1, 0);
5243         }
5244         break;
5245 #if defined(TARGET_NR_linkat)
5246     case TARGET_NR_linkat:
5247         {
5248             void * p2 = NULL;
5249             if (!arg2 || !arg4)
5250                 goto efault;
5251             p  = lock_user_string(arg2);
5252             p2 = lock_user_string(arg4);
5253             if (!p || !p2)
5254                 ret = -TARGET_EFAULT;
5255             else
5256                 ret = get_errno(linkat(arg1, p, arg3, p2, arg5));
5257             unlock_user(p, arg2, 0);
5258             unlock_user(p2, arg4, 0);
5259         }
5260         break;
5261 #endif
5262     case TARGET_NR_unlink:
5263         if (!(p = lock_user_string(arg1)))
5264             goto efault;
5265         ret = get_errno(unlink(p));
5266         unlock_user(p, arg1, 0);
5267         break;
5268 #if defined(TARGET_NR_unlinkat)
5269     case TARGET_NR_unlinkat:
5270         if (!(p = lock_user_string(arg2)))
5271             goto efault;
5272         ret = get_errno(unlinkat(arg1, p, arg3));
5273         unlock_user(p, arg2, 0);
5274         break;
5275 #endif
5276     case TARGET_NR_execve:
5277         {
5278             char **argp, **envp;
5279             int argc, envc;
5280             abi_ulong gp;
5281             abi_ulong guest_argp;
5282             abi_ulong guest_envp;
5283             abi_ulong addr;
5284             char **q;
5285             int total_size = 0;
5286
5287             argc = 0;
5288             guest_argp = arg2;
5289             for (gp = guest_argp; gp; gp += sizeof(abi_ulong)) {
5290                 if (get_user_ual(addr, gp))
5291                     goto efault;
5292                 if (!addr)
5293                     break;
5294                 argc++;
5295             }
5296             envc = 0;
5297             guest_envp = arg3;
5298             for (gp = guest_envp; gp; gp += sizeof(abi_ulong)) {
5299                 if (get_user_ual(addr, gp))
5300                     goto efault;
5301                 if (!addr)
5302                     break;
5303                 envc++;
5304             }
5305
5306             argp = alloca((argc + 1) * sizeof(void *));
5307             envp = alloca((envc + 1) * sizeof(void *));
5308
5309             for (gp = guest_argp, q = argp; gp;
5310                   gp += sizeof(abi_ulong), q++) {
5311                 if (get_user_ual(addr, gp))
5312                     goto execve_efault;
5313                 if (!addr)
5314                     break;
5315                 if (!(*q = lock_user_string(addr)))
5316                     goto execve_efault;
5317                 total_size += strlen(*q) + 1;
5318             }
5319             *q = NULL;
5320
5321             for (gp = guest_envp, q = envp; gp;
5322                   gp += sizeof(abi_ulong), q++) {
5323                 if (get_user_ual(addr, gp))
5324                     goto execve_efault;
5325                 if (!addr)
5326                     break;
5327                 if (!(*q = lock_user_string(addr)))
5328                     goto execve_efault;
5329                 total_size += strlen(*q) + 1;
5330             }
5331             *q = NULL;
5332
5333             /* This case will not be caught by the host's execve() if its
5334                page size is bigger than the target's. */
5335             if (total_size > MAX_ARG_PAGES * TARGET_PAGE_SIZE) {
5336                 ret = -TARGET_E2BIG;
5337                 goto execve_end;
5338             }
5339             if (!(p = lock_user_string(arg1)))
5340                 goto execve_efault;
5341             ret = get_errno(execve(p, argp, envp));
5342             unlock_user(p, arg1, 0);
5343
5344             goto execve_end;
5345
5346         execve_efault:
5347             ret = -TARGET_EFAULT;
5348
5349         execve_end:
5350             for (gp = guest_argp, q = argp; *q;
5351                   gp += sizeof(abi_ulong), q++) {
5352                 if (get_user_ual(addr, gp)
5353                     || !addr)
5354                     break;
5355                 unlock_user(*q, addr, 0);
5356             }
5357             for (gp = guest_envp, q = envp; *q;
5358                   gp += sizeof(abi_ulong), q++) {
5359                 if (get_user_ual(addr, gp)
5360                     || !addr)
5361                     break;
5362                 unlock_user(*q, addr, 0);
5363             }
5364         }
5365         break;
5366     case TARGET_NR_chdir:
5367         if (!(p = lock_user_string(arg1)))
5368             goto efault;
5369         ret = get_errno(chdir(p));
5370         unlock_user(p, arg1, 0);
5371         break;
5372 #ifdef TARGET_NR_time
5373     case TARGET_NR_time:
5374         {
5375             time_t host_time;
5376             ret = get_errno(time(&host_time));
5377             if (!is_error(ret)
5378                 && arg1
5379                 && put_user_sal(host_time, arg1))
5380                 goto efault;
5381         }
5382         break;
5383 #endif
5384     case TARGET_NR_mknod:
5385         if (!(p = lock_user_string(arg1)))
5386             goto efault;
5387         ret = get_errno(mknod(p, arg2, arg3));
5388         unlock_user(p, arg1, 0);
5389         break;
5390 #if defined(TARGET_NR_mknodat)
5391     case TARGET_NR_mknodat:
5392         if (!(p = lock_user_string(arg2)))
5393             goto efault;
5394         ret = get_errno(mknodat(arg1, p, arg3, arg4));
5395         unlock_user(p, arg2, 0);
5396         break;
5397 #endif
5398     case TARGET_NR_chmod:
5399         if (!(p = lock_user_string(arg1)))
5400             goto efault;
5401         ret = get_errno(chmod(p, arg2));
5402         unlock_user(p, arg1, 0);
5403         break;
5404 #ifdef TARGET_NR_break
5405     case TARGET_NR_break:
5406         goto unimplemented;
5407 #endif
5408 #ifdef TARGET_NR_oldstat
5409     case TARGET_NR_oldstat:
5410         goto unimplemented;
5411 #endif
5412     case TARGET_NR_lseek:
5413         ret = get_errno(lseek(arg1, arg2, arg3));
5414         break;
5415 #if defined(TARGET_NR_getxpid) && defined(TARGET_ALPHA)
5416     /* Alpha specific */
5417     case TARGET_NR_getxpid:
5418         ((CPUAlphaState *)cpu_env)->ir[IR_A4] = getppid();
5419         ret = get_errno(getpid());
5420         break;
5421 #endif
5422 #ifdef TARGET_NR_getpid
5423     case TARGET_NR_getpid:
5424         ret = get_errno(getpid());
5425         break;
5426 #endif
5427     case TARGET_NR_mount:
5428                 {
5429                         /* need to look at the data field */
5430                         void *p2, *p3;
5431                         p = lock_user_string(arg1);
5432                         p2 = lock_user_string(arg2);
5433                         p3 = lock_user_string(arg3);
5434                         if (!p || !p2 || !p3)
5435                             ret = -TARGET_EFAULT;
5436                         else {
5437                             /* FIXME - arg5 should be locked, but it isn't clear how to
5438                              * do that since it's not guaranteed to be a NULL-terminated
5439                              * string.
5440                              */
5441                             if ( ! arg5 )
5442                                 ret = get_errno(mount(p, p2, p3, (unsigned long)arg4, NULL));
5443                             else
5444                                 ret = get_errno(mount(p, p2, p3, (unsigned long)arg4, g2h(arg5)));
5445                         }
5446                         unlock_user(p, arg1, 0);
5447                         unlock_user(p2, arg2, 0);
5448                         unlock_user(p3, arg3, 0);
5449                         break;
5450                 }
5451 #ifdef TARGET_NR_umount
5452     case TARGET_NR_umount:
5453         if (!(p = lock_user_string(arg1)))
5454             goto efault;
5455         ret = get_errno(umount(p));
5456         unlock_user(p, arg1, 0);
5457         break;
5458 #endif
5459 #ifdef TARGET_NR_stime /* not on alpha */
5460     case TARGET_NR_stime:
5461         {
5462             time_t host_time;
5463             if (get_user_sal(host_time, arg1))
5464                 goto efault;
5465             ret = get_errno(stime(&host_time));
5466         }
5467         break;
5468 #endif
5469     case TARGET_NR_ptrace:
5470         goto unimplemented;
5471 #ifdef TARGET_NR_alarm /* not on alpha */
5472     case TARGET_NR_alarm:
5473         ret = alarm(arg1);
5474         break;
5475 #endif
5476 #ifdef TARGET_NR_oldfstat
5477     case TARGET_NR_oldfstat:
5478         goto unimplemented;
5479 #endif
5480 #ifdef TARGET_NR_pause /* not on alpha */
5481     case TARGET_NR_pause:
5482         ret = get_errno(pause());
5483         break;
5484 #endif
5485 #ifdef TARGET_NR_utime
5486     case TARGET_NR_utime:
5487         {
5488             struct utimbuf tbuf, *host_tbuf;
5489             struct target_utimbuf *target_tbuf;
5490             if (arg2) {
5491                 if (!lock_user_struct(VERIFY_READ, target_tbuf, arg2, 1))
5492                     goto efault;
5493                 tbuf.actime = tswapal(target_tbuf->actime);
5494                 tbuf.modtime = tswapal(target_tbuf->modtime);
5495                 unlock_user_struct(target_tbuf, arg2, 0);
5496                 host_tbuf = &tbuf;
5497             } else {
5498                 host_tbuf = NULL;
5499             }
5500             if (!(p = lock_user_string(arg1)))
5501                 goto efault;
5502             ret = get_errno(utime(p, host_tbuf));
5503             unlock_user(p, arg1, 0);
5504         }
5505         break;
5506 #endif
5507     case TARGET_NR_utimes:
5508         {
5509             struct timeval *tvp, tv[2];
5510             if (arg2) {
5511                 if (copy_from_user_timeval(&tv[0], arg2)
5512                     || copy_from_user_timeval(&tv[1],
5513                                               arg2 + sizeof(struct target_timeval)))
5514                     goto efault;
5515                 tvp = tv;
5516             } else {
5517                 tvp = NULL;
5518             }
5519             if (!(p = lock_user_string(arg1)))
5520                 goto efault;
5521             ret = get_errno(utimes(p, tvp));
5522             unlock_user(p, arg1, 0);
5523         }
5524         break;
5525 #if defined(TARGET_NR_futimesat)
5526     case TARGET_NR_futimesat:
5527         {
5528             struct timeval *tvp, tv[2];
5529             if (arg3) {
5530                 if (copy_from_user_timeval(&tv[0], arg3)
5531                     || copy_from_user_timeval(&tv[1],
5532                                               arg3 + sizeof(struct target_timeval)))
5533                     goto efault;
5534                 tvp = tv;
5535             } else {
5536                 tvp = NULL;
5537             }
5538             if (!(p = lock_user_string(arg2)))
5539                 goto efault;
5540             ret = get_errno(futimesat(arg1, path(p), tvp));
5541             unlock_user(p, arg2, 0);
5542         }
5543         break;
5544 #endif
5545 #ifdef TARGET_NR_stty
5546     case TARGET_NR_stty:
5547         goto unimplemented;
5548 #endif
5549 #ifdef TARGET_NR_gtty
5550     case TARGET_NR_gtty:
5551         goto unimplemented;
5552 #endif
5553     case TARGET_NR_access:
5554         if (!(p = lock_user_string(arg1)))
5555             goto efault;
5556         ret = get_errno(access(path(p), arg2));
5557         unlock_user(p, arg1, 0);
5558         break;
5559 #if defined(TARGET_NR_faccessat) && defined(__NR_faccessat)
5560     case TARGET_NR_faccessat:
5561         if (!(p = lock_user_string(arg2)))
5562             goto efault;
5563         ret = get_errno(faccessat(arg1, p, arg3, 0));
5564         unlock_user(p, arg2, 0);
5565         break;
5566 #endif
5567 #ifdef TARGET_NR_nice /* not on alpha */
5568     case TARGET_NR_nice:
5569         ret = get_errno(nice(arg1));
5570         break;
5571 #endif
5572 #ifdef TARGET_NR_ftime
5573     case TARGET_NR_ftime:
5574         goto unimplemented;
5575 #endif
5576     case TARGET_NR_sync:
5577         sync();
5578         ret = 0;
5579         break;
5580     case TARGET_NR_kill:
5581         ret = get_errno(kill(arg1, target_to_host_signal(arg2)));
5582         break;
5583     case TARGET_NR_rename:
5584         {
5585             void *p2;
5586             p = lock_user_string(arg1);
5587             p2 = lock_user_string(arg2);
5588             if (!p || !p2)
5589                 ret = -TARGET_EFAULT;
5590             else
5591                 ret = get_errno(rename(p, p2));
5592             unlock_user(p2, arg2, 0);
5593             unlock_user(p, arg1, 0);
5594         }
5595         break;
5596 #if defined(TARGET_NR_renameat)
5597     case TARGET_NR_renameat:
5598         {
5599             void *p2;
5600             p  = lock_user_string(arg2);
5601             p2 = lock_user_string(arg4);
5602             if (!p || !p2)
5603                 ret = -TARGET_EFAULT;
5604             else
5605                 ret = get_errno(renameat(arg1, p, arg3, p2));
5606             unlock_user(p2, arg4, 0);
5607             unlock_user(p, arg2, 0);
5608         }
5609         break;
5610 #endif
5611     case TARGET_NR_mkdir:
5612         if (!(p = lock_user_string(arg1)))
5613             goto efault;
5614         ret = get_errno(mkdir(p, arg2));
5615         unlock_user(p, arg1, 0);
5616         break;
5617 #if defined(TARGET_NR_mkdirat)
5618     case TARGET_NR_mkdirat:
5619         if (!(p = lock_user_string(arg2)))
5620             goto efault;
5621         ret = get_errno(mkdirat(arg1, p, arg3));
5622         unlock_user(p, arg2, 0);
5623         break;
5624 #endif
5625     case TARGET_NR_rmdir:
5626         if (!(p = lock_user_string(arg1)))
5627             goto efault;
5628         ret = get_errno(rmdir(p));
5629         unlock_user(p, arg1, 0);
5630         break;
5631     case TARGET_NR_dup:
5632         ret = get_errno(dup(arg1));
5633         break;
5634     case TARGET_NR_pipe:
5635         ret = do_pipe(cpu_env, arg1, 0, 0);
5636         break;
5637 #ifdef TARGET_NR_pipe2
5638     case TARGET_NR_pipe2:
5639         ret = do_pipe(cpu_env, arg1,
5640                       target_to_host_bitmask(arg2, fcntl_flags_tbl), 1);
5641         break;
5642 #endif
5643     case TARGET_NR_times:
5644         {
5645             struct target_tms *tmsp;
5646             struct tms tms;
5647             ret = get_errno(times(&tms));
5648             if (arg1) {
5649                 tmsp = lock_user(VERIFY_WRITE, arg1, sizeof(struct target_tms), 0);
5650                 if (!tmsp)
5651                     goto efault;
5652                 tmsp->tms_utime = tswapal(host_to_target_clock_t(tms.tms_utime));
5653                 tmsp->tms_stime = tswapal(host_to_target_clock_t(tms.tms_stime));
5654                 tmsp->tms_cutime = tswapal(host_to_target_clock_t(tms.tms_cutime));
5655                 tmsp->tms_cstime = tswapal(host_to_target_clock_t(tms.tms_cstime));
5656             }
5657             if (!is_error(ret))
5658                 ret = host_to_target_clock_t(ret);
5659         }
5660         break;
5661 #ifdef TARGET_NR_prof
5662     case TARGET_NR_prof:
5663         goto unimplemented;
5664 #endif
5665 #ifdef TARGET_NR_signal
5666     case TARGET_NR_signal:
5667         goto unimplemented;
5668 #endif
5669     case TARGET_NR_acct:
5670         if (arg1 == 0) {
5671             ret = get_errno(acct(NULL));
5672         } else {
5673             if (!(p = lock_user_string(arg1)))
5674                 goto efault;
5675             ret = get_errno(acct(path(p)));
5676             unlock_user(p, arg1, 0);
5677         }
5678         break;
5679 #ifdef TARGET_NR_umount2 /* not on alpha */
5680     case TARGET_NR_umount2:
5681         if (!(p = lock_user_string(arg1)))
5682             goto efault;
5683         ret = get_errno(umount2(p, arg2));
5684         unlock_user(p, arg1, 0);
5685         break;
5686 #endif
5687 #ifdef TARGET_NR_lock
5688     case TARGET_NR_lock:
5689         goto unimplemented;
5690 #endif
5691     case TARGET_NR_ioctl:
5692         ret = do_ioctl(arg1, arg2, arg3);
5693         break;
5694     case TARGET_NR_fcntl:
5695         ret = do_fcntl(arg1, arg2, arg3);
5696         break;
5697 #ifdef TARGET_NR_mpx
5698     case TARGET_NR_mpx:
5699         goto unimplemented;
5700 #endif
5701     case TARGET_NR_setpgid:
5702         ret = get_errno(setpgid(arg1, arg2));
5703         break;
5704 #ifdef TARGET_NR_ulimit
5705     case TARGET_NR_ulimit:
5706         goto unimplemented;
5707 #endif
5708 #ifdef TARGET_NR_oldolduname
5709     case TARGET_NR_oldolduname:
5710         goto unimplemented;
5711 #endif
5712     case TARGET_NR_umask:
5713         ret = get_errno(umask(arg1));
5714         break;
5715     case TARGET_NR_chroot:
5716         if (!(p = lock_user_string(arg1)))
5717             goto efault;
5718         ret = get_errno(chroot(p));
5719         unlock_user(p, arg1, 0);
5720         break;
5721     case TARGET_NR_ustat:
5722         goto unimplemented;
5723     case TARGET_NR_dup2:
5724         ret = get_errno(dup2(arg1, arg2));
5725         break;
5726 #if defined(CONFIG_DUP3) && defined(TARGET_NR_dup3)
5727     case TARGET_NR_dup3:
5728         ret = get_errno(dup3(arg1, arg2, arg3));
5729         break;
5730 #endif
5731 #ifdef TARGET_NR_getppid /* not on alpha */
5732     case TARGET_NR_getppid:
5733         ret = get_errno(getppid());
5734         break;
5735 #endif
5736     case TARGET_NR_getpgrp:
5737         ret = get_errno(getpgrp());
5738         break;
5739     case TARGET_NR_setsid:
5740         ret = get_errno(setsid());
5741         break;
5742 #ifdef TARGET_NR_sigaction
5743     case TARGET_NR_sigaction:
5744         {
5745 #if defined(TARGET_ALPHA)
5746             struct target_sigaction act, oact, *pact = 0;
5747             struct target_old_sigaction *old_act;
5748             if (arg2) {
5749                 if (!lock_user_struct(VERIFY_READ, old_act, arg2, 1))
5750                     goto efault;
5751                 act._sa_handler = old_act->_sa_handler;
5752                 target_siginitset(&act.sa_mask, old_act->sa_mask);
5753                 act.sa_flags = old_act->sa_flags;
5754                 act.sa_restorer = 0;
5755                 unlock_user_struct(old_act, arg2, 0);
5756                 pact = &act;
5757             }
5758             ret = get_errno(do_sigaction(arg1, pact, &oact));
5759             if (!is_error(ret) && arg3) {
5760                 if (!lock_user_struct(VERIFY_WRITE, old_act, arg3, 0))
5761                     goto efault;
5762                 old_act->_sa_handler = oact._sa_handler;
5763                 old_act->sa_mask = oact.sa_mask.sig[0];
5764                 old_act->sa_flags = oact.sa_flags;
5765                 unlock_user_struct(old_act, arg3, 1);
5766             }
5767 #elif defined(TARGET_MIPS)
5768             struct target_sigaction act, oact, *pact, *old_act;
5769
5770             if (arg2) {
5771                 if (!lock_user_struct(VERIFY_READ, old_act, arg2, 1))
5772                     goto efault;
5773                 act._sa_handler = old_act->_sa_handler;
5774                 target_siginitset(&act.sa_mask, old_act->sa_mask.sig[0]);
5775                 act.sa_flags = old_act->sa_flags;
5776                 unlock_user_struct(old_act, arg2, 0);
5777                 pact = &act;
5778             } else {
5779                 pact = NULL;
5780             }
5781
5782             ret = get_errno(do_sigaction(arg1, pact, &oact));
5783
5784             if (!is_error(ret) && arg3) {
5785                 if (!lock_user_struct(VERIFY_WRITE, old_act, arg3, 0))
5786                     goto efault;
5787                 old_act->_sa_handler = oact._sa_handler;
5788                 old_act->sa_flags = oact.sa_flags;
5789                 old_act->sa_mask.sig[0] = oact.sa_mask.sig[0];
5790                 old_act->sa_mask.sig[1] = 0;
5791                 old_act->sa_mask.sig[2] = 0;
5792                 old_act->sa_mask.sig[3] = 0;
5793                 unlock_user_struct(old_act, arg3, 1);
5794             }
5795 #else
5796             struct target_old_sigaction *old_act;
5797             struct target_sigaction act, oact, *pact;
5798             if (arg2) {
5799                 if (!lock_user_struct(VERIFY_READ, old_act, arg2, 1))
5800                     goto efault;
5801                 act._sa_handler = old_act->_sa_handler;
5802                 target_siginitset(&act.sa_mask, old_act->sa_mask);
5803                 act.sa_flags = old_act->sa_flags;
5804                 act.sa_restorer = old_act->sa_restorer;
5805                 unlock_user_struct(old_act, arg2, 0);
5806                 pact = &act;
5807             } else {
5808                 pact = NULL;
5809             }
5810             ret = get_errno(do_sigaction(arg1, pact, &oact));
5811             if (!is_error(ret) && arg3) {
5812                 if (!lock_user_struct(VERIFY_WRITE, old_act, arg3, 0))
5813                     goto efault;
5814                 old_act->_sa_handler = oact._sa_handler;
5815                 old_act->sa_mask = oact.sa_mask.sig[0];
5816                 old_act->sa_flags = oact.sa_flags;
5817                 old_act->sa_restorer = oact.sa_restorer;
5818                 unlock_user_struct(old_act, arg3, 1);
5819             }
5820 #endif
5821         }
5822         break;
5823 #endif
5824     case TARGET_NR_rt_sigaction:
5825         {
5826 #if defined(TARGET_ALPHA)
5827             struct target_sigaction act, oact, *pact = 0;
5828             struct target_rt_sigaction *rt_act;
5829             /* ??? arg4 == sizeof(sigset_t).  */
5830             if (arg2) {
5831                 if (!lock_user_struct(VERIFY_READ, rt_act, arg2, 1))
5832                     goto efault;
5833                 act._sa_handler = rt_act->_sa_handler;
5834                 act.sa_mask = rt_act->sa_mask;
5835                 act.sa_flags = rt_act->sa_flags;
5836                 act.sa_restorer = arg5;
5837                 unlock_user_struct(rt_act, arg2, 0);
5838                 pact = &act;
5839             }
5840             ret = get_errno(do_sigaction(arg1, pact, &oact));
5841             if (!is_error(ret) && arg3) {
5842                 if (!lock_user_struct(VERIFY_WRITE, rt_act, arg3, 0))
5843                     goto efault;
5844                 rt_act->_sa_handler = oact._sa_handler;
5845                 rt_act->sa_mask = oact.sa_mask;
5846                 rt_act->sa_flags = oact.sa_flags;
5847                 unlock_user_struct(rt_act, arg3, 1);
5848             }
5849 #else
5850             struct target_sigaction *act;
5851             struct target_sigaction *oact;
5852
5853             if (arg2) {
5854                 if (!lock_user_struct(VERIFY_READ, act, arg2, 1))
5855                     goto efault;
5856             } else
5857                 act = NULL;
5858             if (arg3) {
5859                 if (!lock_user_struct(VERIFY_WRITE, oact, arg3, 0)) {
5860                     ret = -TARGET_EFAULT;
5861                     goto rt_sigaction_fail;
5862                 }
5863             } else
5864                 oact = NULL;
5865             ret = get_errno(do_sigaction(arg1, act, oact));
5866         rt_sigaction_fail:
5867             if (act)
5868                 unlock_user_struct(act, arg2, 0);
5869             if (oact)
5870                 unlock_user_struct(oact, arg3, 1);
5871 #endif
5872         }
5873         break;
5874 #ifdef TARGET_NR_sgetmask /* not on alpha */
5875     case TARGET_NR_sgetmask:
5876         {
5877             sigset_t cur_set;
5878             abi_ulong target_set;
5879             sigprocmask(0, NULL, &cur_set);
5880             host_to_target_old_sigset(&target_set, &cur_set);
5881             ret = target_set;
5882         }
5883         break;
5884 #endif
5885 #ifdef TARGET_NR_ssetmask /* not on alpha */
5886     case TARGET_NR_ssetmask:
5887         {
5888             sigset_t set, oset, cur_set;
5889             abi_ulong target_set = arg1;
5890             sigprocmask(0, NULL, &cur_set);
5891             target_to_host_old_sigset(&set, &target_set);
5892             sigorset(&set, &set, &cur_set);
5893             sigprocmask(SIG_SETMASK, &set, &oset);
5894             host_to_target_old_sigset(&target_set, &oset);
5895             ret = target_set;
5896         }
5897         break;
5898 #endif
5899 #ifdef TARGET_NR_sigprocmask
5900     case TARGET_NR_sigprocmask:
5901         {
5902 #if defined(TARGET_ALPHA)
5903             sigset_t set, oldset;
5904             abi_ulong mask;
5905             int how;
5906
5907             switch (arg1) {
5908             case TARGET_SIG_BLOCK:
5909                 how = SIG_BLOCK;
5910                 break;
5911             case TARGET_SIG_UNBLOCK:
5912                 how = SIG_UNBLOCK;
5913                 break;
5914             case TARGET_SIG_SETMASK:
5915                 how = SIG_SETMASK;
5916                 break;
5917             default:
5918                 ret = -TARGET_EINVAL;
5919                 goto fail;
5920             }
5921             mask = arg2;
5922             target_to_host_old_sigset(&set, &mask);
5923
5924             ret = get_errno(sigprocmask(how, &set, &oldset));
5925             if (!is_error(ret)) {
5926                 host_to_target_old_sigset(&mask, &oldset);
5927                 ret = mask;
5928                 ((CPUAlphaState *)cpu_env)->ir[IR_V0] = 0; /* force no error */
5929             }
5930 #else
5931             sigset_t set, oldset, *set_ptr;
5932             int how;
5933
5934             if (arg2) {
5935                 switch (arg1) {
5936                 case TARGET_SIG_BLOCK:
5937                     how = SIG_BLOCK;
5938                     break;
5939                 case TARGET_SIG_UNBLOCK:
5940                     how = SIG_UNBLOCK;
5941                     break;
5942                 case TARGET_SIG_SETMASK:
5943                     how = SIG_SETMASK;
5944                     break;
5945                 default:
5946                     ret = -TARGET_EINVAL;
5947                     goto fail;
5948                 }
5949                 if (!(p = lock_user(VERIFY_READ, arg2, sizeof(target_sigset_t), 1)))
5950                     goto efault;
5951                 target_to_host_old_sigset(&set, p);
5952                 unlock_user(p, arg2, 0);
5953                 set_ptr = &set;
5954             } else {
5955                 how = 0;
5956                 set_ptr = NULL;
5957             }
5958             ret = get_errno(sigprocmask(how, set_ptr, &oldset));
5959             if (!is_error(ret) && arg3) {
5960                 if (!(p = lock_user(VERIFY_WRITE, arg3, sizeof(target_sigset_t), 0)))
5961                     goto efault;
5962                 host_to_target_old_sigset(p, &oldset);
5963                 unlock_user(p, arg3, sizeof(target_sigset_t));
5964             }
5965 #endif
5966         }
5967         break;
5968 #endif
5969     case TARGET_NR_rt_sigprocmask:
5970         {
5971             int how = arg1;
5972             sigset_t set, oldset, *set_ptr;
5973
5974             if (arg2) {
5975                 switch(how) {
5976                 case TARGET_SIG_BLOCK:
5977                     how = SIG_BLOCK;
5978                     break;
5979                 case TARGET_SIG_UNBLOCK:
5980                     how = SIG_UNBLOCK;
5981                     break;
5982                 case TARGET_SIG_SETMASK:
5983                     how = SIG_SETMASK;
5984                     break;
5985                 default:
5986                     ret = -TARGET_EINVAL;
5987                     goto fail;
5988                 }
5989                 if (!(p = lock_user(VERIFY_READ, arg2, sizeof(target_sigset_t), 1)))
5990                     goto efault;
5991                 target_to_host_sigset(&set, p);
5992                 unlock_user(p, arg2, 0);
5993                 set_ptr = &set;
5994             } else {
5995                 how = 0;
5996                 set_ptr = NULL;
5997             }
5998             ret = get_errno(sigprocmask(how, set_ptr, &oldset));
5999             if (!is_error(ret) && arg3) {
6000                 if (!(p = lock_user(VERIFY_WRITE, arg3, sizeof(target_sigset_t), 0)))
6001                     goto efault;
6002                 host_to_target_sigset(p, &oldset);
6003                 unlock_user(p, arg3, sizeof(target_sigset_t));
6004             }
6005         }
6006         break;
6007 #ifdef TARGET_NR_sigpending
6008     case TARGET_NR_sigpending:
6009         {
6010             sigset_t set;
6011             ret = get_errno(sigpending(&set));
6012             if (!is_error(ret)) {
6013                 if (!(p = lock_user(VERIFY_WRITE, arg1, sizeof(target_sigset_t), 0)))
6014                     goto efault;
6015                 host_to_target_old_sigset(p, &set);
6016                 unlock_user(p, arg1, sizeof(target_sigset_t));
6017             }
6018         }
6019         break;
6020 #endif
6021     case TARGET_NR_rt_sigpending:
6022         {
6023             sigset_t set;
6024             ret = get_errno(sigpending(&set));
6025             if (!is_error(ret)) {
6026                 if (!(p = lock_user(VERIFY_WRITE, arg1, sizeof(target_sigset_t), 0)))
6027                     goto efault;
6028                 host_to_target_sigset(p, &set);
6029                 unlock_user(p, arg1, sizeof(target_sigset_t));
6030             }
6031         }
6032         break;
6033 #ifdef TARGET_NR_sigsuspend
6034     case TARGET_NR_sigsuspend:
6035         {
6036             sigset_t set;
6037 #if defined(TARGET_ALPHA)
6038             abi_ulong mask = arg1;
6039             target_to_host_old_sigset(&set, &mask);
6040 #else
6041             if (!(p = lock_user(VERIFY_READ, arg1, sizeof(target_sigset_t), 1)))
6042                 goto efault;
6043             target_to_host_old_sigset(&set, p);
6044             unlock_user(p, arg1, 0);
6045 #endif
6046             ret = get_errno(sigsuspend(&set));
6047         }
6048         break;
6049 #endif
6050     case TARGET_NR_rt_sigsuspend:
6051         {
6052             sigset_t set;
6053             if (!(p = lock_user(VERIFY_READ, arg1, sizeof(target_sigset_t), 1)))
6054                 goto efault;
6055             target_to_host_sigset(&set, p);
6056             unlock_user(p, arg1, 0);
6057             ret = get_errno(sigsuspend(&set));
6058         }
6059         break;
6060     case TARGET_NR_rt_sigtimedwait:
6061         {
6062             sigset_t set;
6063             struct timespec uts, *puts;
6064             siginfo_t uinfo;
6065
6066             if (!(p = lock_user(VERIFY_READ, arg1, sizeof(target_sigset_t), 1)))
6067                 goto efault;
6068             target_to_host_sigset(&set, p);
6069             unlock_user(p, arg1, 0);
6070             if (arg3) {
6071                 puts = &uts;
6072                 target_to_host_timespec(puts, arg3);
6073             } else {
6074                 puts = NULL;
6075             }
6076             ret = get_errno(sigtimedwait(&set, &uinfo, puts));
6077             if (!is_error(ret) && arg2) {
6078                 if (!(p = lock_user(VERIFY_WRITE, arg2, sizeof(target_siginfo_t), 0)))
6079                     goto efault;
6080                 host_to_target_siginfo(p, &uinfo);
6081                 unlock_user(p, arg2, sizeof(target_siginfo_t));
6082             }
6083         }
6084         break;
6085     case TARGET_NR_rt_sigqueueinfo:
6086         {
6087             siginfo_t uinfo;
6088             if (!(p = lock_user(VERIFY_READ, arg3, sizeof(target_sigset_t), 1)))
6089                 goto efault;
6090             target_to_host_siginfo(&uinfo, p);
6091             unlock_user(p, arg1, 0);
6092             ret = get_errno(sys_rt_sigqueueinfo(arg1, arg2, &uinfo));
6093         }
6094         break;
6095 #ifdef TARGET_NR_sigreturn
6096     case TARGET_NR_sigreturn:
6097         /* NOTE: ret is eax, so not transcoding must be done */
6098         ret = do_sigreturn(cpu_env);
6099         break;
6100 #endif
6101     case TARGET_NR_rt_sigreturn:
6102         /* NOTE: ret is eax, so not transcoding must be done */
6103         ret = do_rt_sigreturn(cpu_env);
6104         break;
6105     case TARGET_NR_sethostname:
6106         if (!(p = lock_user_string(arg1)))
6107             goto efault;
6108         ret = get_errno(sethostname(p, arg2));
6109         unlock_user(p, arg1, 0);
6110         break;
6111     case TARGET_NR_setrlimit:
6112         {
6113             int resource = target_to_host_resource(arg1);
6114             struct target_rlimit *target_rlim;
6115             struct rlimit rlim;
6116             if (!lock_user_struct(VERIFY_READ, target_rlim, arg2, 1))
6117                 goto efault;
6118             rlim.rlim_cur = target_to_host_rlim(target_rlim->rlim_cur);
6119             rlim.rlim_max = target_to_host_rlim(target_rlim->rlim_max);
6120             unlock_user_struct(target_rlim, arg2, 0);
6121             ret = get_errno(setrlimit(resource, &rlim));
6122         }
6123         break;
6124     case TARGET_NR_getrlimit:
6125         {
6126             int resource = target_to_host_resource(arg1);
6127             struct target_rlimit *target_rlim;
6128             struct rlimit rlim;
6129
6130             ret = get_errno(getrlimit(resource, &rlim));
6131             if (!is_error(ret)) {
6132                 if (!lock_user_struct(VERIFY_WRITE, target_rlim, arg2, 0))
6133                     goto efault;
6134                 target_rlim->rlim_cur = host_to_target_rlim(rlim.rlim_cur);
6135                 target_rlim->rlim_max = host_to_target_rlim(rlim.rlim_max);
6136                 unlock_user_struct(target_rlim, arg2, 1);
6137             }
6138         }
6139         break;
6140     case TARGET_NR_getrusage:
6141         {
6142             struct rusage rusage;
6143             ret = get_errno(getrusage(arg1, &rusage));
6144             if (!is_error(ret)) {
6145                 host_to_target_rusage(arg2, &rusage);
6146             }
6147         }
6148         break;
6149     case TARGET_NR_gettimeofday:
6150         {
6151             struct timeval tv;
6152             ret = get_errno(gettimeofday(&tv, NULL));
6153             if (!is_error(ret)) {
6154                 if (copy_to_user_timeval(arg1, &tv))
6155                     goto efault;
6156             }
6157         }
6158         break;
6159     case TARGET_NR_settimeofday:
6160         {
6161             struct timeval tv;
6162             if (copy_from_user_timeval(&tv, arg1))
6163                 goto efault;
6164             ret = get_errno(settimeofday(&tv, NULL));
6165         }
6166         break;
6167 #if defined(TARGET_NR_select)
6168     case TARGET_NR_select:
6169 #if defined(TARGET_S390X) || defined(TARGET_ALPHA)
6170         ret = do_select(arg1, arg2, arg3, arg4, arg5);
6171 #else
6172         {
6173             struct target_sel_arg_struct *sel;
6174             abi_ulong inp, outp, exp, tvp;
6175             long nsel;
6176
6177             if (!lock_user_struct(VERIFY_READ, sel, arg1, 1))
6178                 goto efault;
6179             nsel = tswapal(sel->n);
6180             inp = tswapal(sel->inp);
6181             outp = tswapal(sel->outp);
6182             exp = tswapal(sel->exp);
6183             tvp = tswapal(sel->tvp);
6184             unlock_user_struct(sel, arg1, 0);
6185             ret = do_select(nsel, inp, outp, exp, tvp);
6186         }
6187 #endif
6188         break;
6189 #endif
6190 #ifdef TARGET_NR_pselect6
6191     case TARGET_NR_pselect6:
6192         {
6193             abi_long rfd_addr, wfd_addr, efd_addr, n, ts_addr;
6194             fd_set rfds, wfds, efds;
6195             fd_set *rfds_ptr, *wfds_ptr, *efds_ptr;
6196             struct timespec ts, *ts_ptr;
6197
6198             /*
6199              * The 6th arg is actually two args smashed together,
6200              * so we cannot use the C library.
6201              */
6202             sigset_t set;
6203             struct {
6204                 sigset_t *set;
6205                 size_t size;
6206             } sig, *sig_ptr;
6207
6208             abi_ulong arg_sigset, arg_sigsize, *arg7;
6209             target_sigset_t *target_sigset;
6210
6211             n = arg1;
6212             rfd_addr = arg2;
6213             wfd_addr = arg3;
6214             efd_addr = arg4;
6215             ts_addr = arg5;
6216
6217             ret = copy_from_user_fdset_ptr(&rfds, &rfds_ptr, rfd_addr, n);
6218             if (ret) {
6219                 goto fail;
6220             }
6221             ret = copy_from_user_fdset_ptr(&wfds, &wfds_ptr, wfd_addr, n);
6222             if (ret) {
6223                 goto fail;
6224             }
6225             ret = copy_from_user_fdset_ptr(&efds, &efds_ptr, efd_addr, n);
6226             if (ret) {
6227                 goto fail;
6228             }
6229
6230             /*
6231              * This takes a timespec, and not a timeval, so we cannot
6232              * use the do_select() helper ...
6233              */
6234             if (ts_addr) {
6235                 if (target_to_host_timespec(&ts, ts_addr)) {
6236                     goto efault;
6237                 }
6238                 ts_ptr = &ts;
6239             } else {
6240                 ts_ptr = NULL;
6241             }
6242
6243             /* Extract the two packed args for the sigset */
6244             if (arg6) {
6245                 sig_ptr = &sig;
6246                 sig.size = _NSIG / 8;
6247
6248                 arg7 = lock_user(VERIFY_READ, arg6, sizeof(*arg7) * 2, 1);
6249                 if (!arg7) {
6250                     goto efault;
6251                 }
6252                 arg_sigset = tswapal(arg7[0]);
6253                 arg_sigsize = tswapal(arg7[1]);
6254                 unlock_user(arg7, arg6, 0);
6255
6256                 if (arg_sigset) {
6257                     sig.set = &set;
6258                     if (arg_sigsize != sizeof(*target_sigset)) {
6259                         /* Like the kernel, we enforce correct size sigsets */
6260                         ret = -TARGET_EINVAL;
6261                         goto fail;
6262                     }
6263                     target_sigset = lock_user(VERIFY_READ, arg_sigset,
6264                                               sizeof(*target_sigset), 1);
6265                     if (!target_sigset) {
6266                         goto efault;
6267                     }
6268                     target_to_host_sigset(&set, target_sigset);
6269                     unlock_user(target_sigset, arg_sigset, 0);
6270                 } else {
6271                     sig.set = NULL;
6272                 }
6273             } else {
6274                 sig_ptr = NULL;
6275             }
6276
6277             ret = get_errno(sys_pselect6(n, rfds_ptr, wfds_ptr, efds_ptr,
6278                                          ts_ptr, sig_ptr));
6279
6280             if (!is_error(ret)) {
6281                 if (rfd_addr && copy_to_user_fdset(rfd_addr, &rfds, n))
6282                     goto efault;
6283                 if (wfd_addr && copy_to_user_fdset(wfd_addr, &wfds, n))
6284                     goto efault;
6285                 if (efd_addr && copy_to_user_fdset(efd_addr, &efds, n))
6286                     goto efault;
6287
6288                 if (ts_addr && host_to_target_timespec(ts_addr, &ts))
6289                     goto efault;
6290             }
6291         }
6292         break;
6293 #endif
6294     case TARGET_NR_symlink:
6295         {
6296             void *p2;
6297             p = lock_user_string(arg1);
6298             p2 = lock_user_string(arg2);
6299             if (!p || !p2)
6300                 ret = -TARGET_EFAULT;
6301             else
6302                 ret = get_errno(symlink(p, p2));
6303             unlock_user(p2, arg2, 0);
6304             unlock_user(p, arg1, 0);
6305         }
6306         break;
6307 #if defined(TARGET_NR_symlinkat)
6308     case TARGET_NR_symlinkat:
6309         {
6310             void *p2;
6311             p  = lock_user_string(arg1);
6312             p2 = lock_user_string(arg3);
6313             if (!p || !p2)
6314                 ret = -TARGET_EFAULT;
6315             else
6316                 ret = get_errno(symlinkat(p, arg2, p2));
6317             unlock_user(p2, arg3, 0);
6318             unlock_user(p, arg1, 0);
6319         }
6320         break;
6321 #endif
6322 #ifdef TARGET_NR_oldlstat
6323     case TARGET_NR_oldlstat:
6324         goto unimplemented;
6325 #endif
6326     case TARGET_NR_readlink:
6327         {
6328             void *p2;
6329             p = lock_user_string(arg1);
6330             p2 = lock_user(VERIFY_WRITE, arg2, arg3, 0);
6331             if (!p || !p2) {
6332                 ret = -TARGET_EFAULT;
6333             } else if (is_proc_myself((const char *)p, "exe")) {
6334                 char real[PATH_MAX], *temp;
6335                 temp = realpath(exec_path, real);
6336                 ret = temp == NULL ? get_errno(-1) : strlen(real) ;
6337                 snprintf((char *)p2, arg3, "%s", real);
6338             } else {
6339                 ret = get_errno(readlink(path(p), p2, arg3));
6340             }
6341             unlock_user(p2, arg2, ret);
6342             unlock_user(p, arg1, 0);
6343         }
6344         break;
6345 #if defined(TARGET_NR_readlinkat)
6346     case TARGET_NR_readlinkat:
6347         {
6348             void *p2;
6349             p  = lock_user_string(arg2);
6350             p2 = lock_user(VERIFY_WRITE, arg3, arg4, 0);
6351             if (!p || !p2) {
6352                 ret = -TARGET_EFAULT;
6353             } else if (is_proc_myself((const char *)p, "exe")) {
6354                 char real[PATH_MAX], *temp;
6355                 temp = realpath(exec_path, real);
6356                 ret = temp == NULL ? get_errno(-1) : strlen(real) ;
6357                 snprintf((char *)p2, arg4, "%s", real);
6358             } else {
6359                 ret = get_errno(readlinkat(arg1, path(p), p2, arg4));
6360             }
6361             unlock_user(p2, arg3, ret);
6362             unlock_user(p, arg2, 0);
6363         }
6364         break;
6365 #endif
6366 #ifdef TARGET_NR_uselib
6367     case TARGET_NR_uselib:
6368         goto unimplemented;
6369 #endif
6370 #ifdef TARGET_NR_swapon
6371     case TARGET_NR_swapon:
6372         if (!(p = lock_user_string(arg1)))
6373             goto efault;
6374         ret = get_errno(swapon(p, arg2));
6375         unlock_user(p, arg1, 0);
6376         break;
6377 #endif
6378     case TARGET_NR_reboot:
6379         if (arg3 == LINUX_REBOOT_CMD_RESTART2) {
6380            /* arg4 must be ignored in all other cases */
6381            p = lock_user_string(arg4);
6382            if (!p) {
6383               goto efault;
6384            }
6385            ret = get_errno(reboot(arg1, arg2, arg3, p));
6386            unlock_user(p, arg4, 0);
6387         } else {
6388            ret = get_errno(reboot(arg1, arg2, arg3, NULL));
6389         }
6390         break;
6391 #ifdef TARGET_NR_readdir
6392     case TARGET_NR_readdir:
6393         goto unimplemented;
6394 #endif
6395 #ifdef TARGET_NR_mmap
6396     case TARGET_NR_mmap:
6397 #if (defined(TARGET_I386) && defined(TARGET_ABI32)) || defined(TARGET_ARM) || \
6398     defined(TARGET_M68K) || defined(TARGET_CRIS) || defined(TARGET_MICROBLAZE) \
6399     || defined(TARGET_S390X)
6400         {
6401             abi_ulong *v;
6402             abi_ulong v1, v2, v3, v4, v5, v6;
6403             if (!(v = lock_user(VERIFY_READ, arg1, 6 * sizeof(abi_ulong), 1)))
6404                 goto efault;
6405             v1 = tswapal(v[0]);
6406             v2 = tswapal(v[1]);
6407             v3 = tswapal(v[2]);
6408             v4 = tswapal(v[3]);
6409             v5 = tswapal(v[4]);
6410             v6 = tswapal(v[5]);
6411             unlock_user(v, arg1, 0);
6412             ret = get_errno(target_mmap(v1, v2, v3,
6413                                         target_to_host_bitmask(v4, mmap_flags_tbl),
6414                                         v5, v6));
6415         }
6416 #else
6417         ret = get_errno(target_mmap(arg1, arg2, arg3,
6418                                     target_to_host_bitmask(arg4, mmap_flags_tbl),
6419                                     arg5,
6420                                     arg6));
6421 #endif
6422         break;
6423 #endif
6424 #ifdef TARGET_NR_mmap2
6425     case TARGET_NR_mmap2:
6426 #ifndef MMAP_SHIFT
6427 #define MMAP_SHIFT 12
6428 #endif
6429         ret = get_errno(target_mmap(arg1, arg2, arg3,
6430                                     target_to_host_bitmask(arg4, mmap_flags_tbl),
6431                                     arg5,
6432                                     arg6 << MMAP_SHIFT));
6433         break;
6434 #endif
6435     case TARGET_NR_munmap:
6436         ret = get_errno(target_munmap(arg1, arg2));
6437         break;
6438     case TARGET_NR_mprotect:
6439         {
6440             TaskState *ts = ((CPUArchState *)cpu_env)->opaque;
6441             /* Special hack to detect libc making the stack executable.  */
6442             if ((arg3 & PROT_GROWSDOWN)
6443                 && arg1 >= ts->info->stack_limit
6444                 && arg1 <= ts->info->start_stack) {
6445                 arg3 &= ~PROT_GROWSDOWN;
6446                 arg2 = arg2 + arg1 - ts->info->stack_limit;
6447                 arg1 = ts->info->stack_limit;
6448             }
6449         }
6450         ret = get_errno(target_mprotect(arg1, arg2, arg3));
6451         break;
6452 #ifdef TARGET_NR_mremap
6453     case TARGET_NR_mremap:
6454         ret = get_errno(target_mremap(arg1, arg2, arg3, arg4, arg5));
6455         break;
6456 #endif
6457         /* ??? msync/mlock/munlock are broken for softmmu.  */
6458 #ifdef TARGET_NR_msync
6459     case TARGET_NR_msync:
6460         ret = get_errno(msync(g2h(arg1), arg2, arg3));
6461         break;
6462 #endif
6463 #ifdef TARGET_NR_mlock
6464     case TARGET_NR_mlock:
6465         ret = get_errno(mlock(g2h(arg1), arg2));
6466         break;
6467 #endif
6468 #ifdef TARGET_NR_munlock
6469     case TARGET_NR_munlock:
6470         ret = get_errno(munlock(g2h(arg1), arg2));
6471         break;
6472 #endif
6473 #ifdef TARGET_NR_mlockall
6474     case TARGET_NR_mlockall:
6475         ret = get_errno(mlockall(arg1));
6476         break;
6477 #endif
6478 #ifdef TARGET_NR_munlockall
6479     case TARGET_NR_munlockall:
6480         ret = get_errno(munlockall());
6481         break;
6482 #endif
6483     case TARGET_NR_truncate:
6484         if (!(p = lock_user_string(arg1)))
6485             goto efault;
6486         ret = get_errno(truncate(p, arg2));
6487         unlock_user(p, arg1, 0);
6488         break;
6489     case TARGET_NR_ftruncate:
6490         ret = get_errno(ftruncate(arg1, arg2));
6491         break;
6492     case TARGET_NR_fchmod:
6493         ret = get_errno(fchmod(arg1, arg2));
6494         break;
6495 #if defined(TARGET_NR_fchmodat)
6496     case TARGET_NR_fchmodat:
6497         if (!(p = lock_user_string(arg2)))
6498             goto efault;
6499         ret = get_errno(fchmodat(arg1, p, arg3, 0));
6500         unlock_user(p, arg2, 0);
6501         break;
6502 #endif
6503     case TARGET_NR_getpriority:
6504         /* Note that negative values are valid for getpriority, so we must
6505            differentiate based on errno settings.  */
6506         errno = 0;
6507         ret = getpriority(arg1, arg2);
6508         if (ret == -1 && errno != 0) {
6509             ret = -host_to_target_errno(errno);
6510             break;
6511         }
6512 #ifdef TARGET_ALPHA
6513         /* Return value is the unbiased priority.  Signal no error.  */
6514         ((CPUAlphaState *)cpu_env)->ir[IR_V0] = 0;
6515 #else
6516         /* Return value is a biased priority to avoid negative numbers.  */
6517         ret = 20 - ret;
6518 #endif
6519         break;
6520     case TARGET_NR_setpriority:
6521         ret = get_errno(setpriority(arg1, arg2, arg3));
6522         break;
6523 #ifdef TARGET_NR_profil
6524     case TARGET_NR_profil:
6525         goto unimplemented;
6526 #endif
6527     case TARGET_NR_statfs:
6528         if (!(p = lock_user_string(arg1)))
6529             goto efault;
6530         ret = get_errno(statfs(path(p), &stfs));
6531         unlock_user(p, arg1, 0);
6532     convert_statfs:
6533         if (!is_error(ret)) {
6534             struct target_statfs *target_stfs;
6535
6536             if (!lock_user_struct(VERIFY_WRITE, target_stfs, arg2, 0))
6537                 goto efault;
6538             __put_user(stfs.f_type, &target_stfs->f_type);
6539             __put_user(stfs.f_bsize, &target_stfs->f_bsize);
6540             __put_user(stfs.f_blocks, &target_stfs->f_blocks);
6541             __put_user(stfs.f_bfree, &target_stfs->f_bfree);
6542             __put_user(stfs.f_bavail, &target_stfs->f_bavail);
6543             __put_user(stfs.f_files, &target_stfs->f_files);
6544             __put_user(stfs.f_ffree, &target_stfs->f_ffree);
6545             __put_user(stfs.f_fsid.__val[0], &target_stfs->f_fsid.val[0]);
6546             __put_user(stfs.f_fsid.__val[1], &target_stfs->f_fsid.val[1]);
6547             __put_user(stfs.f_namelen, &target_stfs->f_namelen);
6548             __put_user(stfs.f_frsize, &target_stfs->f_frsize);
6549             memset(target_stfs->f_spare, 0, sizeof(target_stfs->f_spare));
6550             unlock_user_struct(target_stfs, arg2, 1);
6551         }
6552         break;
6553     case TARGET_NR_fstatfs:
6554         ret = get_errno(fstatfs(arg1, &stfs));
6555         goto convert_statfs;
6556 #ifdef TARGET_NR_statfs64
6557     case TARGET_NR_statfs64:
6558         if (!(p = lock_user_string(arg1)))
6559             goto efault;
6560         ret = get_errno(statfs(path(p), &stfs));
6561         unlock_user(p, arg1, 0);
6562     convert_statfs64:
6563         if (!is_error(ret)) {
6564             struct target_statfs64 *target_stfs;
6565
6566             if (!lock_user_struct(VERIFY_WRITE, target_stfs, arg3, 0))
6567                 goto efault;
6568             __put_user(stfs.f_type, &target_stfs->f_type);
6569             __put_user(stfs.f_bsize, &target_stfs->f_bsize);
6570             __put_user(stfs.f_blocks, &target_stfs->f_blocks);
6571             __put_user(stfs.f_bfree, &target_stfs->f_bfree);
6572             __put_user(stfs.f_bavail, &target_stfs->f_bavail);
6573             __put_user(stfs.f_files, &target_stfs->f_files);
6574             __put_user(stfs.f_ffree, &target_stfs->f_ffree);
6575             __put_user(stfs.f_fsid.__val[0], &target_stfs->f_fsid.val[0]);
6576             __put_user(stfs.f_fsid.__val[1], &target_stfs->f_fsid.val[1]);
6577             __put_user(stfs.f_namelen, &target_stfs->f_namelen);
6578             __put_user(stfs.f_frsize, &target_stfs->f_frsize);
6579             memset(target_stfs->f_spare, 0, sizeof(target_stfs->f_spare));
6580             unlock_user_struct(target_stfs, arg3, 1);
6581         }
6582         break;
6583     case TARGET_NR_fstatfs64:
6584         ret = get_errno(fstatfs(arg1, &stfs));
6585         goto convert_statfs64;
6586 #endif
6587 #ifdef TARGET_NR_ioperm
6588     case TARGET_NR_ioperm:
6589         goto unimplemented;
6590 #endif
6591 #ifdef TARGET_NR_socketcall
6592     case TARGET_NR_socketcall:
6593         ret = do_socketcall(arg1, arg2);
6594         break;
6595 #endif
6596 #ifdef TARGET_NR_accept
6597     case TARGET_NR_accept:
6598         ret = do_accept4(arg1, arg2, arg3, 0);
6599         break;
6600 #endif
6601 #ifdef TARGET_NR_accept4
6602     case TARGET_NR_accept4:
6603 #ifdef CONFIG_ACCEPT4
6604         ret = do_accept4(arg1, arg2, arg3, arg4);
6605 #else
6606         goto unimplemented;
6607 #endif
6608         break;
6609 #endif
6610 #ifdef TARGET_NR_bind
6611     case TARGET_NR_bind:
6612         ret = do_bind(arg1, arg2, arg3);
6613         break;
6614 #endif
6615 #ifdef TARGET_NR_connect
6616     case TARGET_NR_connect:
6617         ret = do_connect(arg1, arg2, arg3);
6618         break;
6619 #endif
6620 #ifdef TARGET_NR_getpeername
6621     case TARGET_NR_getpeername:
6622         ret = do_getpeername(arg1, arg2, arg3);
6623         break;
6624 #endif
6625 #ifdef TARGET_NR_getsockname
6626     case TARGET_NR_getsockname:
6627         ret = do_getsockname(arg1, arg2, arg3);
6628         break;
6629 #endif
6630 #ifdef TARGET_NR_getsockopt
6631     case TARGET_NR_getsockopt:
6632         ret = do_getsockopt(arg1, arg2, arg3, arg4, arg5);
6633         break;
6634 #endif
6635 #ifdef TARGET_NR_listen
6636     case TARGET_NR_listen:
6637         ret = get_errno(listen(arg1, arg2));
6638         break;
6639 #endif
6640 #ifdef TARGET_NR_recv
6641     case TARGET_NR_recv:
6642         ret = do_recvfrom(arg1, arg2, arg3, arg4, 0, 0);
6643         break;
6644 #endif
6645 #ifdef TARGET_NR_recvfrom
6646     case TARGET_NR_recvfrom:
6647         ret = do_recvfrom(arg1, arg2, arg3, arg4, arg5, arg6);
6648         break;
6649 #endif
6650 #ifdef TARGET_NR_recvmsg
6651     case TARGET_NR_recvmsg:
6652         ret = do_sendrecvmsg(arg1, arg2, arg3, 0);
6653         break;
6654 #endif
6655 #ifdef TARGET_NR_send
6656     case TARGET_NR_send:
6657         ret = do_sendto(arg1, arg2, arg3, arg4, 0, 0);
6658         break;
6659 #endif
6660 #ifdef TARGET_NR_sendmsg
6661     case TARGET_NR_sendmsg:
6662         ret = do_sendrecvmsg(arg1, arg2, arg3, 1);
6663         break;
6664 #endif
6665 #ifdef TARGET_NR_sendto
6666     case TARGET_NR_sendto:
6667         ret = do_sendto(arg1, arg2, arg3, arg4, arg5, arg6);
6668         break;
6669 #endif
6670 #ifdef TARGET_NR_shutdown
6671     case TARGET_NR_shutdown:
6672         ret = get_errno(shutdown(arg1, arg2));
6673         break;
6674 #endif
6675 #ifdef TARGET_NR_socket
6676     case TARGET_NR_socket:
6677         ret = do_socket(arg1, arg2, arg3);
6678         break;
6679 #endif
6680 #ifdef TARGET_NR_socketpair
6681     case TARGET_NR_socketpair:
6682         ret = do_socketpair(arg1, arg2, arg3, arg4);
6683         break;
6684 #endif
6685 #ifdef TARGET_NR_setsockopt
6686     case TARGET_NR_setsockopt:
6687         ret = do_setsockopt(arg1, arg2, arg3, arg4, (socklen_t) arg5);
6688         break;
6689 #endif
6690
6691     case TARGET_NR_syslog:
6692         if (!(p = lock_user_string(arg2)))
6693             goto efault;
6694         ret = get_errno(sys_syslog((int)arg1, p, (int)arg3));
6695         unlock_user(p, arg2, 0);
6696         break;
6697
6698     case TARGET_NR_setitimer:
6699         {
6700             struct itimerval value, ovalue, *pvalue;
6701
6702             if (arg2) {
6703                 pvalue = &value;
6704                 if (copy_from_user_timeval(&pvalue->it_interval, arg2)
6705                     || copy_from_user_timeval(&pvalue->it_value,
6706                                               arg2 + sizeof(struct target_timeval)))
6707                     goto efault;
6708             } else {
6709                 pvalue = NULL;
6710             }
6711             ret = get_errno(setitimer(arg1, pvalue, &ovalue));
6712             if (!is_error(ret) && arg3) {
6713                 if (copy_to_user_timeval(arg3,
6714                                          &ovalue.it_interval)
6715                     || copy_to_user_timeval(arg3 + sizeof(struct target_timeval),
6716                                             &ovalue.it_value))
6717                     goto efault;
6718             }
6719         }
6720         break;
6721     case TARGET_NR_getitimer:
6722         {
6723             struct itimerval value;
6724
6725             ret = get_errno(getitimer(arg1, &value));
6726             if (!is_error(ret) && arg2) {
6727                 if (copy_to_user_timeval(arg2,
6728                                          &value.it_interval)
6729                     || copy_to_user_timeval(arg2 + sizeof(struct target_timeval),
6730                                             &value.it_value))
6731                     goto efault;
6732             }
6733         }
6734         break;
6735     case TARGET_NR_stat:
6736         if (!(p = lock_user_string(arg1)))
6737             goto efault;
6738         ret = get_errno(stat(path(p), &st));
6739         unlock_user(p, arg1, 0);
6740         goto do_stat;
6741     case TARGET_NR_lstat:
6742         if (!(p = lock_user_string(arg1)))
6743             goto efault;
6744         ret = get_errno(lstat(path(p), &st));
6745         unlock_user(p, arg1, 0);
6746         goto do_stat;
6747     case TARGET_NR_fstat:
6748         {
6749             ret = get_errno(fstat(arg1, &st));
6750         do_stat:
6751             if (!is_error(ret)) {
6752                 struct target_stat *target_st;
6753
6754                 if (!lock_user_struct(VERIFY_WRITE, target_st, arg2, 0))
6755                     goto efault;
6756                 memset(target_st, 0, sizeof(*target_st));
6757                 __put_user(st.st_dev, &target_st->st_dev);
6758                 __put_user(st.st_ino, &target_st->st_ino);
6759                 __put_user(st.st_mode, &target_st->st_mode);
6760                 __put_user(st.st_uid, &target_st->st_uid);
6761                 __put_user(st.st_gid, &target_st->st_gid);
6762                 __put_user(st.st_nlink, &target_st->st_nlink);
6763                 __put_user(st.st_rdev, &target_st->st_rdev);
6764                 __put_user(st.st_size, &target_st->st_size);
6765                 __put_user(st.st_blksize, &target_st->st_blksize);
6766                 __put_user(st.st_blocks, &target_st->st_blocks);
6767                 __put_user(st.st_atime, &target_st->target_st_atime);
6768                 __put_user(st.st_mtime, &target_st->target_st_mtime);
6769                 __put_user(st.st_ctime, &target_st->target_st_ctime);
6770                 unlock_user_struct(target_st, arg2, 1);
6771             }
6772         }
6773         break;
6774 #ifdef TARGET_NR_olduname
6775     case TARGET_NR_olduname:
6776         goto unimplemented;
6777 #endif
6778 #ifdef TARGET_NR_iopl
6779     case TARGET_NR_iopl:
6780         goto unimplemented;
6781 #endif
6782     case TARGET_NR_vhangup:
6783         ret = get_errno(vhangup());
6784         break;
6785 #ifdef TARGET_NR_idle
6786     case TARGET_NR_idle:
6787         goto unimplemented;
6788 #endif
6789 #ifdef TARGET_NR_syscall
6790     case TARGET_NR_syscall:
6791         ret = do_syscall(cpu_env, arg1 & 0xffff, arg2, arg3, arg4, arg5,
6792                          arg6, arg7, arg8, 0);
6793         break;
6794 #endif
6795     case TARGET_NR_wait4:
6796         {
6797             int status;
6798             abi_long status_ptr = arg2;
6799             struct rusage rusage, *rusage_ptr;
6800             abi_ulong target_rusage = arg4;
6801             if (target_rusage)
6802                 rusage_ptr = &rusage;
6803             else
6804                 rusage_ptr = NULL;
6805             ret = get_errno(wait4(arg1, &status, arg3, rusage_ptr));
6806             if (!is_error(ret)) {
6807                 if (status_ptr && ret) {
6808                     status = host_to_target_waitstatus(status);
6809                     if (put_user_s32(status, status_ptr))
6810                         goto efault;
6811                 }
6812                 if (target_rusage)
6813                     host_to_target_rusage(target_rusage, &rusage);
6814             }
6815         }
6816         break;
6817 #ifdef TARGET_NR_swapoff
6818     case TARGET_NR_swapoff:
6819         if (!(p = lock_user_string(arg1)))
6820             goto efault;
6821         ret = get_errno(swapoff(p));
6822         unlock_user(p, arg1, 0);
6823         break;
6824 #endif
6825     case TARGET_NR_sysinfo:
6826         {
6827             struct target_sysinfo *target_value;
6828             struct sysinfo value;
6829             ret = get_errno(sysinfo(&value));
6830             if (!is_error(ret) && arg1)
6831             {
6832                 if (!lock_user_struct(VERIFY_WRITE, target_value, arg1, 0))
6833                     goto efault;
6834                 __put_user(value.uptime, &target_value->uptime);
6835                 __put_user(value.loads[0], &target_value->loads[0]);
6836                 __put_user(value.loads[1], &target_value->loads[1]);
6837                 __put_user(value.loads[2], &target_value->loads[2]);
6838                 __put_user(value.totalram, &target_value->totalram);
6839                 __put_user(value.freeram, &target_value->freeram);
6840                 __put_user(value.sharedram, &target_value->sharedram);
6841                 __put_user(value.bufferram, &target_value->bufferram);
6842                 __put_user(value.totalswap, &target_value->totalswap);
6843                 __put_user(value.freeswap, &target_value->freeswap);
6844                 __put_user(value.procs, &target_value->procs);
6845                 __put_user(value.totalhigh, &target_value->totalhigh);
6846                 __put_user(value.freehigh, &target_value->freehigh);
6847                 __put_user(value.mem_unit, &target_value->mem_unit);
6848                 unlock_user_struct(target_value, arg1, 1);
6849             }
6850         }
6851         break;
6852 #ifdef TARGET_NR_ipc
6853     case TARGET_NR_ipc:
6854         ret = do_ipc(arg1, arg2, arg3, arg4, arg5, arg6);
6855         break;
6856 #endif
6857 #ifdef TARGET_NR_semget
6858     case TARGET_NR_semget:
6859         ret = get_errno(semget(arg1, arg2, arg3));
6860         break;
6861 #endif
6862 #ifdef TARGET_NR_semop
6863     case TARGET_NR_semop:
6864         ret = do_semop(arg1, arg2, arg3);
6865         break;
6866 #endif
6867 #ifdef TARGET_NR_semctl
6868     case TARGET_NR_semctl:
6869         ret = do_semctl(arg1, arg2, arg3, (union target_semun)(abi_ulong)arg4);
6870         break;
6871 #endif
6872 #ifdef TARGET_NR_msgctl
6873     case TARGET_NR_msgctl:
6874         ret = do_msgctl(arg1, arg2, arg3);
6875         break;
6876 #endif
6877 #ifdef TARGET_NR_msgget
6878     case TARGET_NR_msgget:
6879         ret = get_errno(msgget(arg1, arg2));
6880         break;
6881 #endif
6882 #ifdef TARGET_NR_msgrcv
6883     case TARGET_NR_msgrcv:
6884         ret = do_msgrcv(arg1, arg2, arg3, arg4, arg5);
6885         break;
6886 #endif
6887 #ifdef TARGET_NR_msgsnd
6888     case TARGET_NR_msgsnd:
6889         ret = do_msgsnd(arg1, arg2, arg3, arg4);
6890         break;
6891 #endif
6892 #ifdef TARGET_NR_shmget
6893     case TARGET_NR_shmget:
6894         ret = get_errno(shmget(arg1, arg2, arg3));
6895         break;
6896 #endif
6897 #ifdef TARGET_NR_shmctl
6898     case TARGET_NR_shmctl:
6899         ret = do_shmctl(arg1, arg2, arg3);
6900         break;
6901 #endif
6902 #ifdef TARGET_NR_shmat
6903     case TARGET_NR_shmat:
6904         ret = do_shmat(arg1, arg2, arg3);
6905         break;
6906 #endif
6907 #ifdef TARGET_NR_shmdt
6908     case TARGET_NR_shmdt:
6909         ret = do_shmdt(arg1);
6910         break;
6911 #endif
6912     case TARGET_NR_fsync:
6913         ret = get_errno(fsync(arg1));
6914         break;
6915     case TARGET_NR_clone:
6916         /* Linux manages to have three different orderings for its
6917          * arguments to clone(); the BACKWARDS and BACKWARDS2 defines
6918          * match the kernel's CONFIG_CLONE_* settings.
6919          * Microblaze is further special in that it uses a sixth
6920          * implicit argument to clone for the TLS pointer.
6921          */
6922 #if defined(TARGET_MICROBLAZE)
6923         ret = get_errno(do_fork(cpu_env, arg1, arg2, arg4, arg6, arg5));
6924 #elif defined(TARGET_CLONE_BACKWARDS)
6925         ret = get_errno(do_fork(cpu_env, arg1, arg2, arg3, arg4, arg5));
6926 #elif defined(TARGET_CLONE_BACKWARDS2)
6927         ret = get_errno(do_fork(cpu_env, arg2, arg1, arg3, arg5, arg4));
6928 #else
6929         ret = get_errno(do_fork(cpu_env, arg1, arg2, arg3, arg5, arg4));
6930 #endif
6931         break;
6932 #ifdef __NR_exit_group
6933         /* new thread calls */
6934     case TARGET_NR_exit_group:
6935 #ifdef TARGET_GPROF
6936         _mcleanup();
6937 #endif
6938         gdb_exit(cpu_env, arg1);
6939         ret = get_errno(exit_group(arg1));
6940         break;
6941 #endif
6942     case TARGET_NR_setdomainname:
6943         if (!(p = lock_user_string(arg1)))
6944             goto efault;
6945         ret = get_errno(setdomainname(p, arg2));
6946         unlock_user(p, arg1, 0);
6947         break;
6948     case TARGET_NR_uname:
6949         /* no need to transcode because we use the linux syscall */
6950         {
6951             struct new_utsname * buf;
6952
6953             if (!lock_user_struct(VERIFY_WRITE, buf, arg1, 0))
6954                 goto efault;
6955             ret = get_errno(sys_uname(buf));
6956             if (!is_error(ret)) {
6957                 /* Overrite the native machine name with whatever is being
6958                    emulated. */
6959                 strcpy (buf->machine, cpu_to_uname_machine(cpu_env));
6960                 /* Allow the user to override the reported release.  */
6961                 if (qemu_uname_release && *qemu_uname_release)
6962                   strcpy (buf->release, qemu_uname_release);
6963             }
6964             unlock_user_struct(buf, arg1, 1);
6965         }
6966         break;
6967 #ifdef TARGET_I386
6968     case TARGET_NR_modify_ldt:
6969         ret = do_modify_ldt(cpu_env, arg1, arg2, arg3);
6970         break;
6971 #if !defined(TARGET_X86_64)
6972     case TARGET_NR_vm86old:
6973         goto unimplemented;
6974     case TARGET_NR_vm86:
6975         ret = do_vm86(cpu_env, arg1, arg2);
6976         break;
6977 #endif
6978 #endif
6979     case TARGET_NR_adjtimex:
6980         goto unimplemented;
6981 #ifdef TARGET_NR_create_module
6982     case TARGET_NR_create_module:
6983 #endif
6984     case TARGET_NR_init_module:
6985     case TARGET_NR_delete_module:
6986 #ifdef TARGET_NR_get_kernel_syms
6987     case TARGET_NR_get_kernel_syms:
6988 #endif
6989         goto unimplemented;
6990     case TARGET_NR_quotactl:
6991         goto unimplemented;
6992     case TARGET_NR_getpgid:
6993         ret = get_errno(getpgid(arg1));
6994         break;
6995     case TARGET_NR_fchdir:
6996         ret = get_errno(fchdir(arg1));
6997         break;
6998 #ifdef TARGET_NR_bdflush /* not on x86_64 */
6999     case TARGET_NR_bdflush:
7000         goto unimplemented;
7001 #endif
7002 #ifdef TARGET_NR_sysfs
7003     case TARGET_NR_sysfs:
7004         goto unimplemented;
7005 #endif
7006     case TARGET_NR_personality:
7007         ret = get_errno(personality(arg1));
7008         break;
7009 #ifdef TARGET_NR_afs_syscall
7010     case TARGET_NR_afs_syscall:
7011         goto unimplemented;
7012 #endif
7013 #ifdef TARGET_NR__llseek /* Not on alpha */
7014     case TARGET_NR__llseek:
7015         {
7016             int64_t res;
7017 #if !defined(__NR_llseek)
7018             res = lseek(arg1, ((uint64_t)arg2 << 32) | arg3, arg5);
7019             if (res == -1) {
7020                 ret = get_errno(res);
7021             } else {
7022                 ret = 0;
7023             }
7024 #else
7025             ret = get_errno(_llseek(arg1, arg2, arg3, &res, arg5));
7026 #endif
7027             if ((ret == 0) && put_user_s64(res, arg4)) {
7028                 goto efault;
7029             }
7030         }
7031         break;
7032 #endif
7033     case TARGET_NR_getdents:
7034 #ifdef __NR_getdents
7035 #if TARGET_ABI_BITS == 32 && HOST_LONG_BITS == 64
7036         {
7037             struct target_dirent *target_dirp;
7038             struct linux_dirent *dirp;
7039             abi_long count = arg3;
7040
7041             dirp = malloc(count);
7042             if (!dirp) {
7043                 ret = -TARGET_ENOMEM;
7044                 goto fail;
7045             }
7046
7047             ret = get_errno(sys_getdents(arg1, dirp, count));
7048             if (!is_error(ret)) {
7049                 struct linux_dirent *de;
7050                 struct target_dirent *tde;
7051                 int len = ret;
7052                 int reclen, treclen;
7053                 int count1, tnamelen;
7054
7055                 count1 = 0;
7056                 de = dirp;
7057                 if (!(target_dirp = lock_user(VERIFY_WRITE, arg2, count, 0)))
7058                     goto efault;
7059                 tde = target_dirp;
7060                 while (len > 0) {
7061                     reclen = de->d_reclen;
7062                     tnamelen = reclen - offsetof(struct linux_dirent, d_name);
7063                     assert(tnamelen >= 0);
7064                     treclen = tnamelen + offsetof(struct target_dirent, d_name);
7065                     assert(count1 + treclen <= count);
7066                     tde->d_reclen = tswap16(treclen);
7067                     tde->d_ino = tswapal(de->d_ino);
7068                     tde->d_off = tswapal(de->d_off);
7069                     memcpy(tde->d_name, de->d_name, tnamelen);
7070                     de = (struct linux_dirent *)((char *)de + reclen);
7071                     len -= reclen;
7072                     tde = (struct target_dirent *)((char *)tde + treclen);
7073                     count1 += treclen;
7074                 }
7075                 ret = count1;
7076                 unlock_user(target_dirp, arg2, ret);
7077             }
7078             free(dirp);
7079         }
7080 #else
7081         {
7082             struct linux_dirent *dirp;
7083             abi_long count = arg3;
7084
7085             if (!(dirp = lock_user(VERIFY_WRITE, arg2, count, 0)))
7086                 goto efault;
7087             ret = get_errno(sys_getdents(arg1, dirp, count));
7088             if (!is_error(ret)) {
7089                 struct linux_dirent *de;
7090                 int len = ret;
7091                 int reclen;
7092                 de = dirp;
7093                 while (len > 0) {
7094                     reclen = de->d_reclen;
7095                     if (reclen > len)
7096                         break;
7097                     de->d_reclen = tswap16(reclen);
7098                     tswapls(&de->d_ino);
7099                     tswapls(&de->d_off);
7100                     de = (struct linux_dirent *)((char *)de + reclen);
7101                     len -= reclen;
7102                 }
7103             }
7104             unlock_user(dirp, arg2, ret);
7105         }
7106 #endif
7107 #else
7108         /* Implement getdents in terms of getdents64 */
7109         {
7110             struct linux_dirent64 *dirp;
7111             abi_long count = arg3;
7112
7113             dirp = lock_user(VERIFY_WRITE, arg2, count, 0);
7114             if (!dirp) {
7115                 goto efault;
7116             }
7117             ret = get_errno(sys_getdents64(arg1, dirp, count));
7118             if (!is_error(ret)) {
7119                 /* Convert the dirent64 structs to target dirent.  We do this
7120                  * in-place, since we can guarantee that a target_dirent is no
7121                  * larger than a dirent64; however this means we have to be
7122                  * careful to read everything before writing in the new format.
7123                  */
7124                 struct linux_dirent64 *de;
7125                 struct target_dirent *tde;
7126                 int len = ret;
7127                 int tlen = 0;
7128
7129                 de = dirp;
7130                 tde = (struct target_dirent *)dirp;
7131                 while (len > 0) {
7132                     int namelen, treclen;
7133                     int reclen = de->d_reclen;
7134                     uint64_t ino = de->d_ino;
7135                     int64_t off = de->d_off;
7136                     uint8_t type = de->d_type;
7137
7138                     namelen = strlen(de->d_name);
7139                     treclen = offsetof(struct target_dirent, d_name)
7140                         + namelen + 2;
7141                     treclen = QEMU_ALIGN_UP(treclen, sizeof(abi_long));
7142
7143                     memmove(tde->d_name, de->d_name, namelen + 1);
7144                     tde->d_ino = tswapal(ino);
7145                     tde->d_off = tswapal(off);
7146                     tde->d_reclen = tswap16(treclen);
7147                     /* The target_dirent type is in what was formerly a padding
7148                      * byte at the end of the structure:
7149                      */
7150                     *(((char *)tde) + treclen - 1) = type;
7151
7152                     de = (struct linux_dirent64 *)((char *)de + reclen);
7153                     tde = (struct target_dirent *)((char *)tde + treclen);
7154                     len -= reclen;
7155                     tlen += treclen;
7156                 }
7157                 ret = tlen;
7158             }
7159             unlock_user(dirp, arg2, ret);
7160         }
7161 #endif
7162         break;
7163 #if defined(TARGET_NR_getdents64) && defined(__NR_getdents64)
7164     case TARGET_NR_getdents64:
7165         {
7166             struct linux_dirent64 *dirp;
7167             abi_long count = arg3;
7168             if (!(dirp = lock_user(VERIFY_WRITE, arg2, count, 0)))
7169                 goto efault;
7170             ret = get_errno(sys_getdents64(arg1, dirp, count));
7171             if (!is_error(ret)) {
7172                 struct linux_dirent64 *de;
7173                 int len = ret;
7174                 int reclen;
7175                 de = dirp;
7176                 while (len > 0) {
7177                     reclen = de->d_reclen;
7178                     if (reclen > len)
7179                         break;
7180                     de->d_reclen = tswap16(reclen);
7181                     tswap64s((uint64_t *)&de->d_ino);
7182                     tswap64s((uint64_t *)&de->d_off);
7183                     de = (struct linux_dirent64 *)((char *)de + reclen);
7184                     len -= reclen;
7185                 }
7186             }
7187             unlock_user(dirp, arg2, ret);
7188         }
7189         break;
7190 #endif /* TARGET_NR_getdents64 */
7191 #if defined(TARGET_NR__newselect)
7192     case TARGET_NR__newselect:
7193         ret = do_select(arg1, arg2, arg3, arg4, arg5);
7194         break;
7195 #endif
7196 #if defined(TARGET_NR_poll) || defined(TARGET_NR_ppoll)
7197 # ifdef TARGET_NR_poll
7198     case TARGET_NR_poll:
7199 # endif
7200 # ifdef TARGET_NR_ppoll
7201     case TARGET_NR_ppoll:
7202 # endif
7203         {
7204             struct target_pollfd *target_pfd;
7205             unsigned int nfds = arg2;
7206             int timeout = arg3;
7207             struct pollfd *pfd;
7208             unsigned int i;
7209
7210             target_pfd = lock_user(VERIFY_WRITE, arg1, sizeof(struct target_pollfd) * nfds, 1);
7211             if (!target_pfd)
7212                 goto efault;
7213
7214             pfd = alloca(sizeof(struct pollfd) * nfds);
7215             for(i = 0; i < nfds; i++) {
7216                 pfd[i].fd = tswap32(target_pfd[i].fd);
7217                 pfd[i].events = tswap16(target_pfd[i].events);
7218             }
7219
7220 # ifdef TARGET_NR_ppoll
7221             if (num == TARGET_NR_ppoll) {
7222                 struct timespec _timeout_ts, *timeout_ts = &_timeout_ts;
7223                 target_sigset_t *target_set;
7224                 sigset_t _set, *set = &_set;
7225
7226                 if (arg3) {
7227                     if (target_to_host_timespec(timeout_ts, arg3)) {
7228                         unlock_user(target_pfd, arg1, 0);
7229                         goto efault;
7230                     }
7231                 } else {
7232                     timeout_ts = NULL;
7233                 }
7234
7235                 if (arg4) {
7236                     target_set = lock_user(VERIFY_READ, arg4, sizeof(target_sigset_t), 1);
7237                     if (!target_set) {
7238                         unlock_user(target_pfd, arg1, 0);
7239                         goto efault;
7240                     }
7241                     target_to_host_sigset(set, target_set);
7242                 } else {
7243                     set = NULL;
7244                 }
7245
7246                 ret = get_errno(sys_ppoll(pfd, nfds, timeout_ts, set, _NSIG/8));
7247
7248                 if (!is_error(ret) && arg3) {
7249                     host_to_target_timespec(arg3, timeout_ts);
7250                 }
7251                 if (arg4) {
7252                     unlock_user(target_set, arg4, 0);
7253                 }
7254             } else
7255 # endif
7256                 ret = get_errno(poll(pfd, nfds, timeout));
7257
7258             if (!is_error(ret)) {
7259                 for(i = 0; i < nfds; i++) {
7260                     target_pfd[i].revents = tswap16(pfd[i].revents);
7261                 }
7262             }
7263             unlock_user(target_pfd, arg1, sizeof(struct target_pollfd) * nfds);
7264         }
7265         break;
7266 #endif
7267     case TARGET_NR_flock:
7268         /* NOTE: the flock constant seems to be the same for every
7269            Linux platform */
7270         ret = get_errno(flock(arg1, arg2));
7271         break;
7272     case TARGET_NR_readv:
7273         {
7274             struct iovec *vec = lock_iovec(VERIFY_WRITE, arg2, arg3, 0);
7275             if (vec != NULL) {
7276                 ret = get_errno(readv(arg1, vec, arg3));
7277                 unlock_iovec(vec, arg2, arg3, 1);
7278             } else {
7279                 ret = -host_to_target_errno(errno);
7280             }
7281         }
7282         break;
7283     case TARGET_NR_writev:
7284         {
7285             struct iovec *vec = lock_iovec(VERIFY_READ, arg2, arg3, 1);
7286             if (vec != NULL) {
7287                 ret = get_errno(writev(arg1, vec, arg3));
7288                 unlock_iovec(vec, arg2, arg3, 0);
7289             } else {
7290                 ret = -host_to_target_errno(errno);
7291             }
7292         }
7293         break;
7294     case TARGET_NR_getsid:
7295         ret = get_errno(getsid(arg1));
7296         break;
7297 #if defined(TARGET_NR_fdatasync) /* Not on alpha (osf_datasync ?) */
7298     case TARGET_NR_fdatasync:
7299         ret = get_errno(fdatasync(arg1));
7300         break;
7301 #endif
7302     case TARGET_NR__sysctl:
7303         /* We don't implement this, but ENOTDIR is always a safe
7304            return value. */
7305         ret = -TARGET_ENOTDIR;
7306         break;
7307     case TARGET_NR_sched_getaffinity:
7308         {
7309             unsigned int mask_size;
7310             unsigned long *mask;
7311
7312             /*
7313              * sched_getaffinity needs multiples of ulong, so need to take
7314              * care of mismatches between target ulong and host ulong sizes.
7315              */
7316             if (arg2 & (sizeof(abi_ulong) - 1)) {
7317                 ret = -TARGET_EINVAL;
7318                 break;
7319             }
7320             mask_size = (arg2 + (sizeof(*mask) - 1)) & ~(sizeof(*mask) - 1);
7321
7322             mask = alloca(mask_size);
7323             ret = get_errno(sys_sched_getaffinity(arg1, mask_size, mask));
7324
7325             if (!is_error(ret)) {
7326                 if (copy_to_user(arg3, mask, ret)) {
7327                     goto efault;
7328                 }
7329             }
7330         }
7331         break;
7332     case TARGET_NR_sched_setaffinity:
7333         {
7334             unsigned int mask_size;
7335             unsigned long *mask;
7336
7337             /*
7338              * sched_setaffinity needs multiples of ulong, so need to take
7339              * care of mismatches between target ulong and host ulong sizes.
7340              */
7341             if (arg2 & (sizeof(abi_ulong) - 1)) {
7342                 ret = -TARGET_EINVAL;
7343                 break;
7344             }
7345             mask_size = (arg2 + (sizeof(*mask) - 1)) & ~(sizeof(*mask) - 1);
7346
7347             mask = alloca(mask_size);
7348             if (!lock_user_struct(VERIFY_READ, p, arg3, 1)) {
7349                 goto efault;
7350             }
7351             memcpy(mask, p, arg2);
7352             unlock_user_struct(p, arg2, 0);
7353
7354             ret = get_errno(sys_sched_setaffinity(arg1, mask_size, mask));
7355         }
7356         break;
7357     case TARGET_NR_sched_setparam:
7358         {
7359             struct sched_param *target_schp;
7360             struct sched_param schp;
7361
7362             if (!lock_user_struct(VERIFY_READ, target_schp, arg2, 1))
7363                 goto efault;
7364             schp.sched_priority = tswap32(target_schp->sched_priority);
7365             unlock_user_struct(target_schp, arg2, 0);
7366             ret = get_errno(sched_setparam(arg1, &schp));
7367         }
7368         break;
7369     case TARGET_NR_sched_getparam:
7370         {
7371             struct sched_param *target_schp;
7372             struct sched_param schp;
7373             ret = get_errno(sched_getparam(arg1, &schp));
7374             if (!is_error(ret)) {
7375                 if (!lock_user_struct(VERIFY_WRITE, target_schp, arg2, 0))
7376                     goto efault;
7377                 target_schp->sched_priority = tswap32(schp.sched_priority);
7378                 unlock_user_struct(target_schp, arg2, 1);
7379             }
7380         }
7381         break;
7382     case TARGET_NR_sched_setscheduler:
7383         {
7384             struct sched_param *target_schp;
7385             struct sched_param schp;
7386             if (!lock_user_struct(VERIFY_READ, target_schp, arg3, 1))
7387                 goto efault;
7388             schp.sched_priority = tswap32(target_schp->sched_priority);
7389             unlock_user_struct(target_schp, arg3, 0);
7390             ret = get_errno(sched_setscheduler(arg1, arg2, &schp));
7391         }
7392         break;
7393     case TARGET_NR_sched_getscheduler:
7394         ret = get_errno(sched_getscheduler(arg1));
7395         break;
7396     case TARGET_NR_sched_yield:
7397         ret = get_errno(sched_yield());
7398         break;
7399     case TARGET_NR_sched_get_priority_max:
7400         ret = get_errno(sched_get_priority_max(arg1));
7401         break;
7402     case TARGET_NR_sched_get_priority_min:
7403         ret = get_errno(sched_get_priority_min(arg1));
7404         break;
7405     case TARGET_NR_sched_rr_get_interval:
7406         {
7407             struct timespec ts;
7408             ret = get_errno(sched_rr_get_interval(arg1, &ts));
7409             if (!is_error(ret)) {
7410                 host_to_target_timespec(arg2, &ts);
7411             }
7412         }
7413         break;
7414     case TARGET_NR_nanosleep:
7415         {
7416             struct timespec req, rem;
7417             target_to_host_timespec(&req, arg1);
7418             ret = get_errno(nanosleep(&req, &rem));
7419             if (is_error(ret) && arg2) {
7420                 host_to_target_timespec(arg2, &rem);
7421             }
7422         }
7423         break;
7424 #ifdef TARGET_NR_query_module
7425     case TARGET_NR_query_module:
7426         goto unimplemented;
7427 #endif
7428 #ifdef TARGET_NR_nfsservctl
7429     case TARGET_NR_nfsservctl:
7430         goto unimplemented;
7431 #endif
7432     case TARGET_NR_prctl:
7433         switch (arg1) {
7434         case PR_GET_PDEATHSIG:
7435         {
7436             int deathsig;
7437             ret = get_errno(prctl(arg1, &deathsig, arg3, arg4, arg5));
7438             if (!is_error(ret) && arg2
7439                 && put_user_ual(deathsig, arg2)) {
7440                 goto efault;
7441             }
7442             break;
7443         }
7444 #ifdef PR_GET_NAME
7445         case PR_GET_NAME:
7446         {
7447             void *name = lock_user(VERIFY_WRITE, arg2, 16, 1);
7448             if (!name) {
7449                 goto efault;
7450             }
7451             ret = get_errno(prctl(arg1, (unsigned long)name,
7452                                   arg3, arg4, arg5));
7453             unlock_user(name, arg2, 16);
7454             break;
7455         }
7456         case PR_SET_NAME:
7457         {
7458             void *name = lock_user(VERIFY_READ, arg2, 16, 1);
7459             if (!name) {
7460                 goto efault;
7461             }
7462             ret = get_errno(prctl(arg1, (unsigned long)name,
7463                                   arg3, arg4, arg5));
7464             unlock_user(name, arg2, 0);
7465             break;
7466         }
7467 #endif
7468         default:
7469             /* Most prctl options have no pointer arguments */
7470             ret = get_errno(prctl(arg1, arg2, arg3, arg4, arg5));
7471             break;
7472         }
7473         break;
7474 #ifdef TARGET_NR_arch_prctl
7475     case TARGET_NR_arch_prctl:
7476 #if defined(TARGET_I386) && !defined(TARGET_ABI32)
7477         ret = do_arch_prctl(cpu_env, arg1, arg2);
7478         break;
7479 #else
7480         goto unimplemented;
7481 #endif
7482 #endif
7483 #ifdef TARGET_NR_pread64
7484     case TARGET_NR_pread64:
7485         if (regpairs_aligned(cpu_env)) {
7486             arg4 = arg5;
7487             arg5 = arg6;
7488         }
7489         if (!(p = lock_user(VERIFY_WRITE, arg2, arg3, 0)))
7490             goto efault;
7491         ret = get_errno(pread64(arg1, p, arg3, target_offset64(arg4, arg5)));
7492         unlock_user(p, arg2, ret);
7493         break;
7494     case TARGET_NR_pwrite64:
7495         if (regpairs_aligned(cpu_env)) {
7496             arg4 = arg5;
7497             arg5 = arg6;
7498         }
7499         if (!(p = lock_user(VERIFY_READ, arg2, arg3, 1)))
7500             goto efault;
7501         ret = get_errno(pwrite64(arg1, p, arg3, target_offset64(arg4, arg5)));
7502         unlock_user(p, arg2, 0);
7503         break;
7504 #endif
7505     case TARGET_NR_getcwd:
7506         if (!(p = lock_user(VERIFY_WRITE, arg1, arg2, 0)))
7507             goto efault;
7508         ret = get_errno(sys_getcwd1(p, arg2));
7509         unlock_user(p, arg1, ret);
7510         break;
7511     case TARGET_NR_capget:
7512         goto unimplemented;
7513     case TARGET_NR_capset:
7514         goto unimplemented;
7515     case TARGET_NR_sigaltstack:
7516 #if defined(TARGET_I386) || defined(TARGET_ARM) || defined(TARGET_MIPS) || \
7517     defined(TARGET_SPARC) || defined(TARGET_PPC) || defined(TARGET_ALPHA) || \
7518     defined(TARGET_M68K) || defined(TARGET_S390X) || defined(TARGET_OPENRISC)
7519         ret = do_sigaltstack(arg1, arg2, get_sp_from_cpustate((CPUArchState *)cpu_env));
7520         break;
7521 #else
7522         goto unimplemented;
7523 #endif
7524
7525 #ifdef CONFIG_SENDFILE
7526     case TARGET_NR_sendfile:
7527     {
7528         off_t *offp = NULL;
7529         off_t off;
7530         if (arg3) {
7531             ret = get_user_sal(off, arg3);
7532             if (is_error(ret)) {
7533                 break;
7534             }
7535             offp = &off;
7536         }
7537         ret = get_errno(sendfile(arg1, arg2, offp, arg4));
7538         if (!is_error(ret) && arg3) {
7539             abi_long ret2 = put_user_sal(off, arg3);
7540             if (is_error(ret2)) {
7541                 ret = ret2;
7542             }
7543         }
7544         break;
7545     }
7546 #ifdef TARGET_NR_sendfile64
7547     case TARGET_NR_sendfile64:
7548     {
7549         off_t *offp = NULL;
7550         off_t off;
7551         if (arg3) {
7552             ret = get_user_s64(off, arg3);
7553             if (is_error(ret)) {
7554                 break;
7555             }
7556             offp = &off;
7557         }
7558         ret = get_errno(sendfile(arg1, arg2, offp, arg4));
7559         if (!is_error(ret) && arg3) {
7560             abi_long ret2 = put_user_s64(off, arg3);
7561             if (is_error(ret2)) {
7562                 ret = ret2;
7563             }
7564         }
7565         break;
7566     }
7567 #endif
7568 #else
7569     case TARGET_NR_sendfile:
7570 #ifdef TARGET_NR_sendfile64
7571     case TARGET_NR_sendfile64:
7572 #endif
7573         goto unimplemented;
7574 #endif
7575
7576 #ifdef TARGET_NR_getpmsg
7577     case TARGET_NR_getpmsg:
7578         goto unimplemented;
7579 #endif
7580 #ifdef TARGET_NR_putpmsg
7581     case TARGET_NR_putpmsg:
7582         goto unimplemented;
7583 #endif
7584 #ifdef TARGET_NR_vfork
7585     case TARGET_NR_vfork:
7586         ret = get_errno(do_fork(cpu_env, CLONE_VFORK | CLONE_VM | SIGCHLD,
7587                         0, 0, 0, 0));
7588         break;
7589 #endif
7590 #ifdef TARGET_NR_ugetrlimit
7591     case TARGET_NR_ugetrlimit:
7592     {
7593         struct rlimit rlim;
7594         int resource = target_to_host_resource(arg1);
7595         ret = get_errno(getrlimit(resource, &rlim));
7596         if (!is_error(ret)) {
7597             struct target_rlimit *target_rlim;
7598             if (!lock_user_struct(VERIFY_WRITE, target_rlim, arg2, 0))
7599                 goto efault;
7600             target_rlim->rlim_cur = host_to_target_rlim(rlim.rlim_cur);
7601             target_rlim->rlim_max = host_to_target_rlim(rlim.rlim_max);
7602             unlock_user_struct(target_rlim, arg2, 1);
7603         }
7604         break;
7605     }
7606 #endif
7607 #ifdef TARGET_NR_truncate64
7608     case TARGET_NR_truncate64:
7609         if (!(p = lock_user_string(arg1)))
7610             goto efault;
7611         ret = target_truncate64(cpu_env, p, arg2, arg3, arg4);
7612         unlock_user(p, arg1, 0);
7613         break;
7614 #endif
7615 #ifdef TARGET_NR_ftruncate64
7616     case TARGET_NR_ftruncate64:
7617         ret = target_ftruncate64(cpu_env, arg1, arg2, arg3, arg4);
7618         break;
7619 #endif
7620 #ifdef TARGET_NR_stat64
7621     case TARGET_NR_stat64:
7622         if (!(p = lock_user_string(arg1)))
7623             goto efault;
7624         ret = get_errno(stat(path(p), &st));
7625         unlock_user(p, arg1, 0);
7626         if (!is_error(ret))
7627             ret = host_to_target_stat64(cpu_env, arg2, &st);
7628         break;
7629 #endif
7630 #ifdef TARGET_NR_lstat64
7631     case TARGET_NR_lstat64:
7632         if (!(p = lock_user_string(arg1)))
7633             goto efault;
7634         ret = get_errno(lstat(path(p), &st));
7635         unlock_user(p, arg1, 0);
7636         if (!is_error(ret))
7637             ret = host_to_target_stat64(cpu_env, arg2, &st);
7638         break;
7639 #endif
7640 #ifdef TARGET_NR_fstat64
7641     case TARGET_NR_fstat64:
7642         ret = get_errno(fstat(arg1, &st));
7643         if (!is_error(ret))
7644             ret = host_to_target_stat64(cpu_env, arg2, &st);
7645         break;
7646 #endif
7647 #if (defined(TARGET_NR_fstatat64) || defined(TARGET_NR_newfstatat))
7648 #ifdef TARGET_NR_fstatat64
7649     case TARGET_NR_fstatat64:
7650 #endif
7651 #ifdef TARGET_NR_newfstatat
7652     case TARGET_NR_newfstatat:
7653 #endif
7654         if (!(p = lock_user_string(arg2)))
7655             goto efault;
7656         ret = get_errno(fstatat(arg1, path(p), &st, arg4));
7657         if (!is_error(ret))
7658             ret = host_to_target_stat64(cpu_env, arg3, &st);
7659         break;
7660 #endif
7661     case TARGET_NR_lchown:
7662         if (!(p = lock_user_string(arg1)))
7663             goto efault;
7664         ret = get_errno(lchown(p, low2highuid(arg2), low2highgid(arg3)));
7665         unlock_user(p, arg1, 0);
7666         break;
7667 #ifdef TARGET_NR_getuid
7668     case TARGET_NR_getuid:
7669         ret = get_errno(high2lowuid(getuid()));
7670         break;
7671 #endif
7672 #ifdef TARGET_NR_getgid
7673     case TARGET_NR_getgid:
7674         ret = get_errno(high2lowgid(getgid()));
7675         break;
7676 #endif
7677 #ifdef TARGET_NR_geteuid
7678     case TARGET_NR_geteuid:
7679         ret = get_errno(high2lowuid(geteuid()));
7680         break;
7681 #endif
7682 #ifdef TARGET_NR_getegid
7683     case TARGET_NR_getegid:
7684         ret = get_errno(high2lowgid(getegid()));
7685         break;
7686 #endif
7687     case TARGET_NR_setreuid:
7688         ret = get_errno(setreuid(low2highuid(arg1), low2highuid(arg2)));
7689         break;
7690     case TARGET_NR_setregid:
7691         ret = get_errno(setregid(low2highgid(arg1), low2highgid(arg2)));
7692         break;
7693     case TARGET_NR_getgroups:
7694         {
7695             int gidsetsize = arg1;
7696             target_id *target_grouplist;
7697             gid_t *grouplist;
7698             int i;
7699
7700             grouplist = alloca(gidsetsize * sizeof(gid_t));
7701             ret = get_errno(getgroups(gidsetsize, grouplist));
7702             if (gidsetsize == 0)
7703                 break;
7704             if (!is_error(ret)) {
7705                 target_grouplist = lock_user(VERIFY_WRITE, arg2, gidsetsize * sizeof(target_id), 0);
7706                 if (!target_grouplist)
7707                     goto efault;
7708                 for(i = 0;i < ret; i++)
7709                     target_grouplist[i] = tswapid(high2lowgid(grouplist[i]));
7710                 unlock_user(target_grouplist, arg2, gidsetsize * sizeof(target_id));
7711             }
7712         }
7713         break;
7714     case TARGET_NR_setgroups:
7715         {
7716             int gidsetsize = arg1;
7717             target_id *target_grouplist;
7718             gid_t *grouplist = NULL;
7719             int i;
7720             if (gidsetsize) {
7721                 grouplist = alloca(gidsetsize * sizeof(gid_t));
7722                 target_grouplist = lock_user(VERIFY_READ, arg2, gidsetsize * sizeof(target_id), 1);
7723                 if (!target_grouplist) {
7724                     ret = -TARGET_EFAULT;
7725                     goto fail;
7726                 }
7727                 for (i = 0; i < gidsetsize; i++) {
7728                     grouplist[i] = low2highgid(tswapid(target_grouplist[i]));
7729                 }
7730                 unlock_user(target_grouplist, arg2, 0);
7731             }
7732             ret = get_errno(setgroups(gidsetsize, grouplist));
7733         }
7734         break;
7735     case TARGET_NR_fchown:
7736         ret = get_errno(fchown(arg1, low2highuid(arg2), low2highgid(arg3)));
7737         break;
7738 #if defined(TARGET_NR_fchownat)
7739     case TARGET_NR_fchownat:
7740         if (!(p = lock_user_string(arg2))) 
7741             goto efault;
7742         ret = get_errno(fchownat(arg1, p, low2highuid(arg3),
7743                                  low2highgid(arg4), arg5));
7744         unlock_user(p, arg2, 0);
7745         break;
7746 #endif
7747 #ifdef TARGET_NR_setresuid
7748     case TARGET_NR_setresuid:
7749         ret = get_errno(setresuid(low2highuid(arg1),
7750                                   low2highuid(arg2),
7751                                   low2highuid(arg3)));
7752         break;
7753 #endif
7754 #ifdef TARGET_NR_getresuid
7755     case TARGET_NR_getresuid:
7756         {
7757             uid_t ruid, euid, suid;
7758             ret = get_errno(getresuid(&ruid, &euid, &suid));
7759             if (!is_error(ret)) {
7760                 if (put_user_u16(high2lowuid(ruid), arg1)
7761                     || put_user_u16(high2lowuid(euid), arg2)
7762                     || put_user_u16(high2lowuid(suid), arg3))
7763                     goto efault;
7764             }
7765         }
7766         break;
7767 #endif
7768 #ifdef TARGET_NR_getresgid
7769     case TARGET_NR_setresgid:
7770         ret = get_errno(setresgid(low2highgid(arg1),
7771                                   low2highgid(arg2),
7772                                   low2highgid(arg3)));
7773         break;
7774 #endif
7775 #ifdef TARGET_NR_getresgid
7776     case TARGET_NR_getresgid:
7777         {
7778             gid_t rgid, egid, sgid;
7779             ret = get_errno(getresgid(&rgid, &egid, &sgid));
7780             if (!is_error(ret)) {
7781                 if (put_user_u16(high2lowgid(rgid), arg1)
7782                     || put_user_u16(high2lowgid(egid), arg2)
7783                     || put_user_u16(high2lowgid(sgid), arg3))
7784                     goto efault;
7785             }
7786         }
7787         break;
7788 #endif
7789     case TARGET_NR_chown:
7790         if (!(p = lock_user_string(arg1)))
7791             goto efault;
7792         ret = get_errno(chown(p, low2highuid(arg2), low2highgid(arg3)));
7793         unlock_user(p, arg1, 0);
7794         break;
7795     case TARGET_NR_setuid:
7796         ret = get_errno(setuid(low2highuid(arg1)));
7797         break;
7798     case TARGET_NR_setgid:
7799         ret = get_errno(setgid(low2highgid(arg1)));
7800         break;
7801     case TARGET_NR_setfsuid:
7802         ret = get_errno(setfsuid(arg1));
7803         break;
7804     case TARGET_NR_setfsgid:
7805         ret = get_errno(setfsgid(arg1));
7806         break;
7807
7808 #ifdef TARGET_NR_lchown32
7809     case TARGET_NR_lchown32:
7810         if (!(p = lock_user_string(arg1)))
7811             goto efault;
7812         ret = get_errno(lchown(p, arg2, arg3));
7813         unlock_user(p, arg1, 0);
7814         break;
7815 #endif
7816 #ifdef TARGET_NR_getuid32
7817     case TARGET_NR_getuid32:
7818         ret = get_errno(getuid());
7819         break;
7820 #endif
7821
7822 #if defined(TARGET_NR_getxuid) && defined(TARGET_ALPHA)
7823    /* Alpha specific */
7824     case TARGET_NR_getxuid:
7825          {
7826             uid_t euid;
7827             euid=geteuid();
7828             ((CPUAlphaState *)cpu_env)->ir[IR_A4]=euid;
7829          }
7830         ret = get_errno(getuid());
7831         break;
7832 #endif
7833 #if defined(TARGET_NR_getxgid) && defined(TARGET_ALPHA)
7834    /* Alpha specific */
7835     case TARGET_NR_getxgid:
7836          {
7837             uid_t egid;
7838             egid=getegid();
7839             ((CPUAlphaState *)cpu_env)->ir[IR_A4]=egid;
7840          }
7841         ret = get_errno(getgid());
7842         break;
7843 #endif
7844 #if defined(TARGET_NR_osf_getsysinfo) && defined(TARGET_ALPHA)
7845     /* Alpha specific */
7846     case TARGET_NR_osf_getsysinfo:
7847         ret = -TARGET_EOPNOTSUPP;
7848         switch (arg1) {
7849           case TARGET_GSI_IEEE_FP_CONTROL:
7850             {
7851                 uint64_t swcr, fpcr = cpu_alpha_load_fpcr (cpu_env);
7852
7853                 /* Copied from linux ieee_fpcr_to_swcr.  */
7854                 swcr = (fpcr >> 35) & SWCR_STATUS_MASK;
7855                 swcr |= (fpcr >> 36) & SWCR_MAP_DMZ;
7856                 swcr |= (~fpcr >> 48) & (SWCR_TRAP_ENABLE_INV
7857                                         | SWCR_TRAP_ENABLE_DZE
7858                                         | SWCR_TRAP_ENABLE_OVF);
7859                 swcr |= (~fpcr >> 57) & (SWCR_TRAP_ENABLE_UNF
7860                                         | SWCR_TRAP_ENABLE_INE);
7861                 swcr |= (fpcr >> 47) & SWCR_MAP_UMZ;
7862                 swcr |= (~fpcr >> 41) & SWCR_TRAP_ENABLE_DNO;
7863
7864                 if (put_user_u64 (swcr, arg2))
7865                         goto efault;
7866                 ret = 0;
7867             }
7868             break;
7869
7870           /* case GSI_IEEE_STATE_AT_SIGNAL:
7871              -- Not implemented in linux kernel.
7872              case GSI_UACPROC:
7873              -- Retrieves current unaligned access state; not much used.
7874              case GSI_PROC_TYPE:
7875              -- Retrieves implver information; surely not used.
7876              case GSI_GET_HWRPB:
7877              -- Grabs a copy of the HWRPB; surely not used.
7878           */
7879         }
7880         break;
7881 #endif
7882 #if defined(TARGET_NR_osf_setsysinfo) && defined(TARGET_ALPHA)
7883     /* Alpha specific */
7884     case TARGET_NR_osf_setsysinfo:
7885         ret = -TARGET_EOPNOTSUPP;
7886         switch (arg1) {
7887           case TARGET_SSI_IEEE_FP_CONTROL:
7888             {
7889                 uint64_t swcr, fpcr, orig_fpcr;
7890
7891                 if (get_user_u64 (swcr, arg2)) {
7892                     goto efault;
7893                 }
7894                 orig_fpcr = cpu_alpha_load_fpcr(cpu_env);
7895                 fpcr = orig_fpcr & FPCR_DYN_MASK;
7896
7897                 /* Copied from linux ieee_swcr_to_fpcr.  */
7898                 fpcr |= (swcr & SWCR_STATUS_MASK) << 35;
7899                 fpcr |= (swcr & SWCR_MAP_DMZ) << 36;
7900                 fpcr |= (~swcr & (SWCR_TRAP_ENABLE_INV
7901                                   | SWCR_TRAP_ENABLE_DZE
7902                                   | SWCR_TRAP_ENABLE_OVF)) << 48;
7903                 fpcr |= (~swcr & (SWCR_TRAP_ENABLE_UNF
7904                                   | SWCR_TRAP_ENABLE_INE)) << 57;
7905                 fpcr |= (swcr & SWCR_MAP_UMZ ? FPCR_UNDZ | FPCR_UNFD : 0);
7906                 fpcr |= (~swcr & SWCR_TRAP_ENABLE_DNO) << 41;
7907
7908                 cpu_alpha_store_fpcr(cpu_env, fpcr);
7909                 ret = 0;
7910             }
7911             break;
7912
7913           case TARGET_SSI_IEEE_RAISE_EXCEPTION:
7914             {
7915                 uint64_t exc, fpcr, orig_fpcr;
7916                 int si_code;
7917
7918                 if (get_user_u64(exc, arg2)) {
7919                     goto efault;
7920                 }
7921
7922                 orig_fpcr = cpu_alpha_load_fpcr(cpu_env);
7923
7924                 /* We only add to the exception status here.  */
7925                 fpcr = orig_fpcr | ((exc & SWCR_STATUS_MASK) << 35);
7926
7927                 cpu_alpha_store_fpcr(cpu_env, fpcr);
7928                 ret = 0;
7929
7930                 /* Old exceptions are not signaled.  */
7931                 fpcr &= ~(orig_fpcr & FPCR_STATUS_MASK);
7932
7933                 /* If any exceptions set by this call,
7934                    and are unmasked, send a signal.  */
7935                 si_code = 0;
7936                 if ((fpcr & (FPCR_INE | FPCR_INED)) == FPCR_INE) {
7937                     si_code = TARGET_FPE_FLTRES;
7938                 }
7939                 if ((fpcr & (FPCR_UNF | FPCR_UNFD)) == FPCR_UNF) {
7940                     si_code = TARGET_FPE_FLTUND;
7941                 }
7942                 if ((fpcr & (FPCR_OVF | FPCR_OVFD)) == FPCR_OVF) {
7943                     si_code = TARGET_FPE_FLTOVF;
7944                 }
7945                 if ((fpcr & (FPCR_DZE | FPCR_DZED)) == FPCR_DZE) {
7946                     si_code = TARGET_FPE_FLTDIV;
7947                 }
7948                 if ((fpcr & (FPCR_INV | FPCR_INVD)) == FPCR_INV) {
7949                     si_code = TARGET_FPE_FLTINV;
7950                 }
7951                 if (si_code != 0) {
7952                     target_siginfo_t info;
7953                     info.si_signo = SIGFPE;
7954                     info.si_errno = 0;
7955                     info.si_code = si_code;
7956                     info._sifields._sigfault._addr
7957                         = ((CPUArchState *)cpu_env)->pc;
7958                     queue_signal((CPUArchState *)cpu_env, info.si_signo, &info);
7959                 }
7960             }
7961             break;
7962
7963           /* case SSI_NVPAIRS:
7964              -- Used with SSIN_UACPROC to enable unaligned accesses.
7965              case SSI_IEEE_STATE_AT_SIGNAL:
7966              case SSI_IEEE_IGNORE_STATE_AT_SIGNAL:
7967              -- Not implemented in linux kernel
7968           */
7969         }
7970         break;
7971 #endif
7972 #ifdef TARGET_NR_osf_sigprocmask
7973     /* Alpha specific.  */
7974     case TARGET_NR_osf_sigprocmask:
7975         {
7976             abi_ulong mask;
7977             int how;
7978             sigset_t set, oldset;
7979
7980             switch(arg1) {
7981             case TARGET_SIG_BLOCK:
7982                 how = SIG_BLOCK;
7983                 break;
7984             case TARGET_SIG_UNBLOCK:
7985                 how = SIG_UNBLOCK;
7986                 break;
7987             case TARGET_SIG_SETMASK:
7988                 how = SIG_SETMASK;
7989                 break;
7990             default:
7991                 ret = -TARGET_EINVAL;
7992                 goto fail;
7993             }
7994             mask = arg2;
7995             target_to_host_old_sigset(&set, &mask);
7996             sigprocmask(how, &set, &oldset);
7997             host_to_target_old_sigset(&mask, &oldset);
7998             ret = mask;
7999         }
8000         break;
8001 #endif
8002
8003 #ifdef TARGET_NR_getgid32
8004     case TARGET_NR_getgid32:
8005         ret = get_errno(getgid());
8006         break;
8007 #endif
8008 #ifdef TARGET_NR_geteuid32
8009     case TARGET_NR_geteuid32:
8010         ret = get_errno(geteuid());
8011         break;
8012 #endif
8013 #ifdef TARGET_NR_getegid32
8014     case TARGET_NR_getegid32:
8015         ret = get_errno(getegid());
8016         break;
8017 #endif
8018 #ifdef TARGET_NR_setreuid32
8019     case TARGET_NR_setreuid32:
8020         ret = get_errno(setreuid(arg1, arg2));
8021         break;
8022 #endif
8023 #ifdef TARGET_NR_setregid32
8024     case TARGET_NR_setregid32:
8025         ret = get_errno(setregid(arg1, arg2));
8026         break;
8027 #endif
8028 #ifdef TARGET_NR_getgroups32
8029     case TARGET_NR_getgroups32:
8030         {
8031             int gidsetsize = arg1;
8032             uint32_t *target_grouplist;
8033             gid_t *grouplist;
8034             int i;
8035
8036             grouplist = alloca(gidsetsize * sizeof(gid_t));
8037             ret = get_errno(getgroups(gidsetsize, grouplist));
8038             if (gidsetsize == 0)
8039                 break;
8040             if (!is_error(ret)) {
8041                 target_grouplist = lock_user(VERIFY_WRITE, arg2, gidsetsize * 4, 0);
8042                 if (!target_grouplist) {
8043                     ret = -TARGET_EFAULT;
8044                     goto fail;
8045                 }
8046                 for(i = 0;i < ret; i++)
8047                     target_grouplist[i] = tswap32(grouplist[i]);
8048                 unlock_user(target_grouplist, arg2, gidsetsize * 4);
8049             }
8050         }
8051         break;
8052 #endif
8053 #ifdef TARGET_NR_setgroups32
8054     case TARGET_NR_setgroups32:
8055         {
8056             int gidsetsize = arg1;
8057             uint32_t *target_grouplist;
8058             gid_t *grouplist;
8059             int i;
8060
8061             grouplist = alloca(gidsetsize * sizeof(gid_t));
8062             target_grouplist = lock_user(VERIFY_READ, arg2, gidsetsize * 4, 1);
8063             if (!target_grouplist) {
8064                 ret = -TARGET_EFAULT;
8065                 goto fail;
8066             }
8067             for(i = 0;i < gidsetsize; i++)
8068                 grouplist[i] = tswap32(target_grouplist[i]);
8069             unlock_user(target_grouplist, arg2, 0);
8070             ret = get_errno(setgroups(gidsetsize, grouplist));
8071         }
8072         break;
8073 #endif
8074 #ifdef TARGET_NR_fchown32
8075     case TARGET_NR_fchown32:
8076         ret = get_errno(fchown(arg1, arg2, arg3));
8077         break;
8078 #endif
8079 #ifdef TARGET_NR_setresuid32
8080     case TARGET_NR_setresuid32:
8081         ret = get_errno(setresuid(arg1, arg2, arg3));
8082         break;
8083 #endif
8084 #ifdef TARGET_NR_getresuid32
8085     case TARGET_NR_getresuid32:
8086         {
8087             uid_t ruid, euid, suid;
8088             ret = get_errno(getresuid(&ruid, &euid, &suid));
8089             if (!is_error(ret)) {
8090                 if (put_user_u32(ruid, arg1)
8091                     || put_user_u32(euid, arg2)
8092                     || put_user_u32(suid, arg3))
8093                     goto efault;
8094             }
8095         }
8096         break;
8097 #endif
8098 #ifdef TARGET_NR_setresgid32
8099     case TARGET_NR_setresgid32:
8100         ret = get_errno(setresgid(arg1, arg2, arg3));
8101         break;
8102 #endif
8103 #ifdef TARGET_NR_getresgid32
8104     case TARGET_NR_getresgid32:
8105         {
8106             gid_t rgid, egid, sgid;
8107             ret = get_errno(getresgid(&rgid, &egid, &sgid));
8108             if (!is_error(ret)) {
8109                 if (put_user_u32(rgid, arg1)
8110                     || put_user_u32(egid, arg2)
8111                     || put_user_u32(sgid, arg3))
8112                     goto efault;
8113             }
8114         }
8115         break;
8116 #endif
8117 #ifdef TARGET_NR_chown32
8118     case TARGET_NR_chown32:
8119         if (!(p = lock_user_string(arg1)))
8120             goto efault;
8121         ret = get_errno(chown(p, arg2, arg3));
8122         unlock_user(p, arg1, 0);
8123         break;
8124 #endif
8125 #ifdef TARGET_NR_setuid32
8126     case TARGET_NR_setuid32:
8127         ret = get_errno(setuid(arg1));
8128         break;
8129 #endif
8130 #ifdef TARGET_NR_setgid32
8131     case TARGET_NR_setgid32:
8132         ret = get_errno(setgid(arg1));
8133         break;
8134 #endif
8135 #ifdef TARGET_NR_setfsuid32
8136     case TARGET_NR_setfsuid32:
8137         ret = get_errno(setfsuid(arg1));
8138         break;
8139 #endif
8140 #ifdef TARGET_NR_setfsgid32
8141     case TARGET_NR_setfsgid32:
8142         ret = get_errno(setfsgid(arg1));
8143         break;
8144 #endif
8145
8146     case TARGET_NR_pivot_root:
8147         goto unimplemented;
8148 #ifdef TARGET_NR_mincore
8149     case TARGET_NR_mincore:
8150         {
8151             void *a;
8152             ret = -TARGET_EFAULT;
8153             if (!(a = lock_user(VERIFY_READ, arg1,arg2, 0)))
8154                 goto efault;
8155             if (!(p = lock_user_string(arg3)))
8156                 goto mincore_fail;
8157             ret = get_errno(mincore(a, arg2, p));
8158             unlock_user(p, arg3, ret);
8159             mincore_fail:
8160             unlock_user(a, arg1, 0);
8161         }
8162         break;
8163 #endif
8164 #ifdef TARGET_NR_arm_fadvise64_64
8165     case TARGET_NR_arm_fadvise64_64:
8166         {
8167                 /*
8168                  * arm_fadvise64_64 looks like fadvise64_64 but
8169                  * with different argument order
8170                  */
8171                 abi_long temp;
8172                 temp = arg3;
8173                 arg3 = arg4;
8174                 arg4 = temp;
8175         }
8176 #endif
8177 #if defined(TARGET_NR_fadvise64_64) || defined(TARGET_NR_arm_fadvise64_64) || defined(TARGET_NR_fadvise64)
8178 #ifdef TARGET_NR_fadvise64_64
8179     case TARGET_NR_fadvise64_64:
8180 #endif
8181 #ifdef TARGET_NR_fadvise64
8182     case TARGET_NR_fadvise64:
8183 #endif
8184 #ifdef TARGET_S390X
8185         switch (arg4) {
8186         case 4: arg4 = POSIX_FADV_NOREUSE + 1; break; /* make sure it's an invalid value */
8187         case 5: arg4 = POSIX_FADV_NOREUSE + 2; break; /* ditto */
8188         case 6: arg4 = POSIX_FADV_DONTNEED; break;
8189         case 7: arg4 = POSIX_FADV_NOREUSE; break;
8190         default: break;
8191         }
8192 #endif
8193         ret = -posix_fadvise(arg1, arg2, arg3, arg4);
8194         break;
8195 #endif
8196 #ifdef TARGET_NR_madvise
8197     case TARGET_NR_madvise:
8198         /* A straight passthrough may not be safe because qemu sometimes
8199            turns private file-backed mappings into anonymous mappings.
8200            This will break MADV_DONTNEED.
8201            This is a hint, so ignoring and returning success is ok.  */
8202         ret = get_errno(0);
8203         break;
8204 #endif
8205 #if TARGET_ABI_BITS == 32
8206     case TARGET_NR_fcntl64:
8207     {
8208         int cmd;
8209         struct flock64 fl;
8210         struct target_flock64 *target_fl;
8211 #ifdef TARGET_ARM
8212         struct target_eabi_flock64 *target_efl;
8213 #endif
8214
8215         cmd = target_to_host_fcntl_cmd(arg2);
8216         if (cmd == -TARGET_EINVAL) {
8217             ret = cmd;
8218             break;
8219         }
8220
8221         switch(arg2) {
8222         case TARGET_F_GETLK64:
8223 #ifdef TARGET_ARM
8224             if (((CPUARMState *)cpu_env)->eabi) {
8225                 if (!lock_user_struct(VERIFY_READ, target_efl, arg3, 1)) 
8226                     goto efault;
8227                 fl.l_type = tswap16(target_efl->l_type);
8228                 fl.l_whence = tswap16(target_efl->l_whence);
8229                 fl.l_start = tswap64(target_efl->l_start);
8230                 fl.l_len = tswap64(target_efl->l_len);
8231                 fl.l_pid = tswap32(target_efl->l_pid);
8232                 unlock_user_struct(target_efl, arg3, 0);
8233             } else
8234 #endif
8235             {
8236                 if (!lock_user_struct(VERIFY_READ, target_fl, arg3, 1)) 
8237                     goto efault;
8238                 fl.l_type = tswap16(target_fl->l_type);
8239                 fl.l_whence = tswap16(target_fl->l_whence);
8240                 fl.l_start = tswap64(target_fl->l_start);
8241                 fl.l_len = tswap64(target_fl->l_len);
8242                 fl.l_pid = tswap32(target_fl->l_pid);
8243                 unlock_user_struct(target_fl, arg3, 0);
8244             }
8245             ret = get_errno(fcntl(arg1, cmd, &fl));
8246             if (ret == 0) {
8247 #ifdef TARGET_ARM
8248                 if (((CPUARMState *)cpu_env)->eabi) {
8249                     if (!lock_user_struct(VERIFY_WRITE, target_efl, arg3, 0)) 
8250                         goto efault;
8251                     target_efl->l_type = tswap16(fl.l_type);
8252                     target_efl->l_whence = tswap16(fl.l_whence);
8253                     target_efl->l_start = tswap64(fl.l_start);
8254                     target_efl->l_len = tswap64(fl.l_len);
8255                     target_efl->l_pid = tswap32(fl.l_pid);
8256                     unlock_user_struct(target_efl, arg3, 1);
8257                 } else
8258 #endif
8259                 {
8260                     if (!lock_user_struct(VERIFY_WRITE, target_fl, arg3, 0)) 
8261                         goto efault;
8262                     target_fl->l_type = tswap16(fl.l_type);
8263                     target_fl->l_whence = tswap16(fl.l_whence);
8264                     target_fl->l_start = tswap64(fl.l_start);
8265                     target_fl->l_len = tswap64(fl.l_len);
8266                     target_fl->l_pid = tswap32(fl.l_pid);
8267                     unlock_user_struct(target_fl, arg3, 1);
8268                 }
8269             }
8270             break;
8271
8272         case TARGET_F_SETLK64:
8273         case TARGET_F_SETLKW64:
8274 #ifdef TARGET_ARM
8275             if (((CPUARMState *)cpu_env)->eabi) {
8276                 if (!lock_user_struct(VERIFY_READ, target_efl, arg3, 1)) 
8277                     goto efault;
8278                 fl.l_type = tswap16(target_efl->l_type);
8279                 fl.l_whence = tswap16(target_efl->l_whence);
8280                 fl.l_start = tswap64(target_efl->l_start);
8281                 fl.l_len = tswap64(target_efl->l_len);
8282                 fl.l_pid = tswap32(target_efl->l_pid);
8283                 unlock_user_struct(target_efl, arg3, 0);
8284             } else
8285 #endif
8286             {
8287                 if (!lock_user_struct(VERIFY_READ, target_fl, arg3, 1)) 
8288                     goto efault;
8289                 fl.l_type = tswap16(target_fl->l_type);
8290                 fl.l_whence = tswap16(target_fl->l_whence);
8291                 fl.l_start = tswap64(target_fl->l_start);
8292                 fl.l_len = tswap64(target_fl->l_len);
8293                 fl.l_pid = tswap32(target_fl->l_pid);
8294                 unlock_user_struct(target_fl, arg3, 0);
8295             }
8296             ret = get_errno(fcntl(arg1, cmd, &fl));
8297             break;
8298         default:
8299             ret = do_fcntl(arg1, arg2, arg3);
8300             break;
8301         }
8302         break;
8303     }
8304 #endif
8305 #ifdef TARGET_NR_cacheflush
8306     case TARGET_NR_cacheflush:
8307         /* self-modifying code is handled automatically, so nothing needed */
8308         ret = 0;
8309         break;
8310 #endif
8311 #ifdef TARGET_NR_security
8312     case TARGET_NR_security:
8313         goto unimplemented;
8314 #endif
8315 #ifdef TARGET_NR_getpagesize
8316     case TARGET_NR_getpagesize:
8317         ret = TARGET_PAGE_SIZE;
8318         break;
8319 #endif
8320     case TARGET_NR_gettid:
8321         ret = get_errno(gettid());
8322         break;
8323 #ifdef TARGET_NR_readahead
8324     case TARGET_NR_readahead:
8325 #if TARGET_ABI_BITS == 32
8326         if (regpairs_aligned(cpu_env)) {
8327             arg2 = arg3;
8328             arg3 = arg4;
8329             arg4 = arg5;
8330         }
8331         ret = get_errno(readahead(arg1, ((off64_t)arg3 << 32) | arg2, arg4));
8332 #else
8333         ret = get_errno(readahead(arg1, arg2, arg3));
8334 #endif
8335         break;
8336 #endif
8337 #ifdef CONFIG_ATTR
8338 #ifdef TARGET_NR_setxattr
8339     case TARGET_NR_listxattr:
8340     case TARGET_NR_llistxattr:
8341     {
8342         void *p, *b = 0;
8343         if (arg2) {
8344             b = lock_user(VERIFY_WRITE, arg2, arg3, 0);
8345             if (!b) {
8346                 ret = -TARGET_EFAULT;
8347                 break;
8348             }
8349         }
8350         p = lock_user_string(arg1);
8351         if (p) {
8352             if (num == TARGET_NR_listxattr) {
8353                 ret = get_errno(listxattr(p, b, arg3));
8354             } else {
8355                 ret = get_errno(llistxattr(p, b, arg3));
8356             }
8357         } else {
8358             ret = -TARGET_EFAULT;
8359         }
8360         unlock_user(p, arg1, 0);
8361         unlock_user(b, arg2, arg3);
8362         break;
8363     }
8364     case TARGET_NR_flistxattr:
8365     {
8366         void *b = 0;
8367         if (arg2) {
8368             b = lock_user(VERIFY_WRITE, arg2, arg3, 0);
8369             if (!b) {
8370                 ret = -TARGET_EFAULT;
8371                 break;
8372             }
8373         }
8374         ret = get_errno(flistxattr(arg1, b, arg3));
8375         unlock_user(b, arg2, arg3);
8376         break;
8377     }
8378     case TARGET_NR_setxattr:
8379     case TARGET_NR_lsetxattr:
8380         {
8381             void *p, *n, *v = 0;
8382             if (arg3) {
8383                 v = lock_user(VERIFY_READ, arg3, arg4, 1);
8384                 if (!v) {
8385                     ret = -TARGET_EFAULT;
8386                     break;
8387                 }
8388             }
8389             p = lock_user_string(arg1);
8390             n = lock_user_string(arg2);
8391             if (p && n) {
8392                 if (num == TARGET_NR_setxattr) {
8393                     ret = get_errno(setxattr(p, n, v, arg4, arg5));
8394                 } else {
8395                     ret = get_errno(lsetxattr(p, n, v, arg4, arg5));
8396                 }
8397             } else {
8398                 ret = -TARGET_EFAULT;
8399             }
8400             unlock_user(p, arg1, 0);
8401             unlock_user(n, arg2, 0);
8402             unlock_user(v, arg3, 0);
8403         }
8404         break;
8405     case TARGET_NR_fsetxattr:
8406         {
8407             void *n, *v = 0;
8408             if (arg3) {
8409                 v = lock_user(VERIFY_READ, arg3, arg4, 1);
8410                 if (!v) {
8411                     ret = -TARGET_EFAULT;
8412                     break;
8413                 }
8414             }
8415             n = lock_user_string(arg2);
8416             if (n) {
8417                 ret = get_errno(fsetxattr(arg1, n, v, arg4, arg5));
8418             } else {
8419                 ret = -TARGET_EFAULT;
8420             }
8421             unlock_user(n, arg2, 0);
8422             unlock_user(v, arg3, 0);
8423         }
8424         break;
8425     case TARGET_NR_getxattr:
8426     case TARGET_NR_lgetxattr:
8427         {
8428             void *p, *n, *v = 0;
8429             if (arg3) {
8430                 v = lock_user(VERIFY_WRITE, arg3, arg4, 0);
8431                 if (!v) {
8432                     ret = -TARGET_EFAULT;
8433                     break;
8434                 }
8435             }
8436             p = lock_user_string(arg1);
8437             n = lock_user_string(arg2);
8438             if (p && n) {
8439                 if (num == TARGET_NR_getxattr) {
8440                     ret = get_errno(getxattr(p, n, v, arg4));
8441                 } else {
8442                     ret = get_errno(lgetxattr(p, n, v, arg4));
8443                 }
8444             } else {
8445                 ret = -TARGET_EFAULT;
8446             }
8447             unlock_user(p, arg1, 0);
8448             unlock_user(n, arg2, 0);
8449             unlock_user(v, arg3, arg4);
8450         }
8451         break;
8452     case TARGET_NR_fgetxattr:
8453         {
8454             void *n, *v = 0;
8455             if (arg3) {
8456                 v = lock_user(VERIFY_WRITE, arg3, arg4, 0);
8457                 if (!v) {
8458                     ret = -TARGET_EFAULT;
8459                     break;
8460                 }
8461             }
8462             n = lock_user_string(arg2);
8463             if (n) {
8464                 ret = get_errno(fgetxattr(arg1, n, v, arg4));
8465             } else {
8466                 ret = -TARGET_EFAULT;
8467             }
8468             unlock_user(n, arg2, 0);
8469             unlock_user(v, arg3, arg4);
8470         }
8471         break;
8472     case TARGET_NR_removexattr:
8473     case TARGET_NR_lremovexattr:
8474         {
8475             void *p, *n;
8476             p = lock_user_string(arg1);
8477             n = lock_user_string(arg2);
8478             if (p && n) {
8479                 if (num == TARGET_NR_removexattr) {
8480                     ret = get_errno(removexattr(p, n));
8481                 } else {
8482                     ret = get_errno(lremovexattr(p, n));
8483                 }
8484             } else {
8485                 ret = -TARGET_EFAULT;
8486             }
8487             unlock_user(p, arg1, 0);
8488             unlock_user(n, arg2, 0);
8489         }
8490         break;
8491     case TARGET_NR_fremovexattr:
8492         {
8493             void *n;
8494             n = lock_user_string(arg2);
8495             if (n) {
8496                 ret = get_errno(fremovexattr(arg1, n));
8497             } else {
8498                 ret = -TARGET_EFAULT;
8499             }
8500             unlock_user(n, arg2, 0);
8501         }
8502         break;
8503 #endif
8504 #endif /* CONFIG_ATTR */
8505 #ifdef TARGET_NR_set_thread_area
8506     case TARGET_NR_set_thread_area:
8507 #if defined(TARGET_MIPS)
8508       ((CPUMIPSState *) cpu_env)->tls_value = arg1;
8509       ret = 0;
8510       break;
8511 #elif defined(TARGET_CRIS)
8512       if (arg1 & 0xff)
8513           ret = -TARGET_EINVAL;
8514       else {
8515           ((CPUCRISState *) cpu_env)->pregs[PR_PID] = arg1;
8516           ret = 0;
8517       }
8518       break;
8519 #elif defined(TARGET_I386) && defined(TARGET_ABI32)
8520       ret = do_set_thread_area(cpu_env, arg1);
8521       break;
8522 #elif defined(TARGET_M68K)
8523       {
8524           TaskState *ts = ((CPUArchState *)cpu_env)->opaque;
8525           ts->tp_value = arg1;
8526           ret = 0;
8527           break;
8528       }
8529 #else
8530       goto unimplemented_nowarn;
8531 #endif
8532 #endif
8533 #ifdef TARGET_NR_get_thread_area
8534     case TARGET_NR_get_thread_area:
8535 #if defined(TARGET_I386) && defined(TARGET_ABI32)
8536         ret = do_get_thread_area(cpu_env, arg1);
8537         break;
8538 #elif defined(TARGET_M68K)
8539         {
8540             TaskState *ts = ((CPUArchState *)cpu_env)->opaque;
8541             ret = ts->tp_value;
8542             break;
8543         }
8544 #else
8545         goto unimplemented_nowarn;
8546 #endif
8547 #endif
8548 #ifdef TARGET_NR_getdomainname
8549     case TARGET_NR_getdomainname:
8550         goto unimplemented_nowarn;
8551 #endif
8552
8553 #ifdef TARGET_NR_clock_gettime
8554     case TARGET_NR_clock_gettime:
8555     {
8556         struct timespec ts;
8557         ret = get_errno(clock_gettime(arg1, &ts));
8558         if (!is_error(ret)) {
8559             host_to_target_timespec(arg2, &ts);
8560         }
8561         break;
8562     }
8563 #endif
8564 #ifdef TARGET_NR_clock_getres
8565     case TARGET_NR_clock_getres:
8566     {
8567         struct timespec ts;
8568         ret = get_errno(clock_getres(arg1, &ts));
8569         if (!is_error(ret)) {
8570             host_to_target_timespec(arg2, &ts);
8571         }
8572         break;
8573     }
8574 #endif
8575 #ifdef TARGET_NR_clock_nanosleep
8576     case TARGET_NR_clock_nanosleep:
8577     {
8578         struct timespec ts;
8579         target_to_host_timespec(&ts, arg3);
8580         ret = get_errno(clock_nanosleep(arg1, arg2, &ts, arg4 ? &ts : NULL));
8581         if (arg4)
8582             host_to_target_timespec(arg4, &ts);
8583         break;
8584     }
8585 #endif
8586
8587 #if defined(TARGET_NR_set_tid_address) && defined(__NR_set_tid_address)
8588     case TARGET_NR_set_tid_address:
8589         ret = get_errno(set_tid_address((int *)g2h(arg1)));
8590         break;
8591 #endif
8592
8593 #if defined(TARGET_NR_tkill) && defined(__NR_tkill)
8594     case TARGET_NR_tkill:
8595         ret = get_errno(sys_tkill((int)arg1, target_to_host_signal(arg2)));
8596         break;
8597 #endif
8598
8599 #if defined(TARGET_NR_tgkill) && defined(__NR_tgkill)
8600     case TARGET_NR_tgkill:
8601         ret = get_errno(sys_tgkill((int)arg1, (int)arg2,
8602                         target_to_host_signal(arg3)));
8603         break;
8604 #endif
8605
8606 #ifdef TARGET_NR_set_robust_list
8607     case TARGET_NR_set_robust_list:
8608     case TARGET_NR_get_robust_list:
8609         /* The ABI for supporting robust futexes has userspace pass
8610          * the kernel a pointer to a linked list which is updated by
8611          * userspace after the syscall; the list is walked by the kernel
8612          * when the thread exits. Since the linked list in QEMU guest
8613          * memory isn't a valid linked list for the host and we have
8614          * no way to reliably intercept the thread-death event, we can't
8615          * support these. Silently return ENOSYS so that guest userspace
8616          * falls back to a non-robust futex implementation (which should
8617          * be OK except in the corner case of the guest crashing while
8618          * holding a mutex that is shared with another process via
8619          * shared memory).
8620          */
8621         goto unimplemented_nowarn;
8622 #endif
8623
8624 #if defined(TARGET_NR_utimensat)
8625     case TARGET_NR_utimensat:
8626         {
8627             struct timespec *tsp, ts[2];
8628             if (!arg3) {
8629                 tsp = NULL;
8630             } else {
8631                 target_to_host_timespec(ts, arg3);
8632                 target_to_host_timespec(ts+1, arg3+sizeof(struct target_timespec));
8633                 tsp = ts;
8634             }
8635             if (!arg2)
8636                 ret = get_errno(sys_utimensat(arg1, NULL, tsp, arg4));
8637             else {
8638                 if (!(p = lock_user_string(arg2))) {
8639                     ret = -TARGET_EFAULT;
8640                     goto fail;
8641                 }
8642                 ret = get_errno(sys_utimensat(arg1, path(p), tsp, arg4));
8643                 unlock_user(p, arg2, 0);
8644             }
8645         }
8646         break;
8647 #endif
8648     case TARGET_NR_futex:
8649         ret = do_futex(arg1, arg2, arg3, arg4, arg5, arg6);
8650         break;
8651 #if defined(TARGET_NR_inotify_init) && defined(__NR_inotify_init)
8652     case TARGET_NR_inotify_init:
8653         ret = get_errno(sys_inotify_init());
8654         break;
8655 #endif
8656 #ifdef CONFIG_INOTIFY1
8657 #if defined(TARGET_NR_inotify_init1) && defined(__NR_inotify_init1)
8658     case TARGET_NR_inotify_init1:
8659         ret = get_errno(sys_inotify_init1(arg1));
8660         break;
8661 #endif
8662 #endif
8663 #if defined(TARGET_NR_inotify_add_watch) && defined(__NR_inotify_add_watch)
8664     case TARGET_NR_inotify_add_watch:
8665         p = lock_user_string(arg2);
8666         ret = get_errno(sys_inotify_add_watch(arg1, path(p), arg3));
8667         unlock_user(p, arg2, 0);
8668         break;
8669 #endif
8670 #if defined(TARGET_NR_inotify_rm_watch) && defined(__NR_inotify_rm_watch)
8671     case TARGET_NR_inotify_rm_watch:
8672         ret = get_errno(sys_inotify_rm_watch(arg1, arg2));
8673         break;
8674 #endif
8675
8676 #if defined(TARGET_NR_mq_open) && defined(__NR_mq_open)
8677     case TARGET_NR_mq_open:
8678         {
8679             struct mq_attr posix_mq_attr;
8680
8681             p = lock_user_string(arg1 - 1);
8682             if (arg4 != 0)
8683                 copy_from_user_mq_attr (&posix_mq_attr, arg4);
8684             ret = get_errno(mq_open(p, arg2, arg3, &posix_mq_attr));
8685             unlock_user (p, arg1, 0);
8686         }
8687         break;
8688
8689     case TARGET_NR_mq_unlink:
8690         p = lock_user_string(arg1 - 1);
8691         ret = get_errno(mq_unlink(p));
8692         unlock_user (p, arg1, 0);
8693         break;
8694
8695     case TARGET_NR_mq_timedsend:
8696         {
8697             struct timespec ts;
8698
8699             p = lock_user (VERIFY_READ, arg2, arg3, 1);
8700             if (arg5 != 0) {
8701                 target_to_host_timespec(&ts, arg5);
8702                 ret = get_errno(mq_timedsend(arg1, p, arg3, arg4, &ts));
8703                 host_to_target_timespec(arg5, &ts);
8704             }
8705             else
8706                 ret = get_errno(mq_send(arg1, p, arg3, arg4));
8707             unlock_user (p, arg2, arg3);
8708         }
8709         break;
8710
8711     case TARGET_NR_mq_timedreceive:
8712         {
8713             struct timespec ts;
8714             unsigned int prio;
8715
8716             p = lock_user (VERIFY_READ, arg2, arg3, 1);
8717             if (arg5 != 0) {
8718                 target_to_host_timespec(&ts, arg5);
8719                 ret = get_errno(mq_timedreceive(arg1, p, arg3, &prio, &ts));
8720                 host_to_target_timespec(arg5, &ts);
8721             }
8722             else
8723                 ret = get_errno(mq_receive(arg1, p, arg3, &prio));
8724             unlock_user (p, arg2, arg3);
8725             if (arg4 != 0)
8726                 put_user_u32(prio, arg4);
8727         }
8728         break;
8729
8730     /* Not implemented for now... */
8731 /*     case TARGET_NR_mq_notify: */
8732 /*         break; */
8733
8734     case TARGET_NR_mq_getsetattr:
8735         {
8736             struct mq_attr posix_mq_attr_in, posix_mq_attr_out;
8737             ret = 0;
8738             if (arg3 != 0) {
8739                 ret = mq_getattr(arg1, &posix_mq_attr_out);
8740                 copy_to_user_mq_attr(arg3, &posix_mq_attr_out);
8741             }
8742             if (arg2 != 0) {
8743                 copy_from_user_mq_attr(&posix_mq_attr_in, arg2);
8744                 ret |= mq_setattr(arg1, &posix_mq_attr_in, &posix_mq_attr_out);
8745             }
8746
8747         }
8748         break;
8749 #endif
8750
8751 #ifdef CONFIG_SPLICE
8752 #ifdef TARGET_NR_tee
8753     case TARGET_NR_tee:
8754         {
8755             ret = get_errno(tee(arg1,arg2,arg3,arg4));
8756         }
8757         break;
8758 #endif
8759 #ifdef TARGET_NR_splice
8760     case TARGET_NR_splice:
8761         {
8762             loff_t loff_in, loff_out;
8763             loff_t *ploff_in = NULL, *ploff_out = NULL;
8764             if(arg2) {
8765                 get_user_u64(loff_in, arg2);
8766                 ploff_in = &loff_in;
8767             }
8768             if(arg4) {
8769                 get_user_u64(loff_out, arg2);
8770                 ploff_out = &loff_out;
8771             }
8772             ret = get_errno(splice(arg1, ploff_in, arg3, ploff_out, arg5, arg6));
8773         }
8774         break;
8775 #endif
8776 #ifdef TARGET_NR_vmsplice
8777         case TARGET_NR_vmsplice:
8778         {
8779             struct iovec *vec = lock_iovec(VERIFY_READ, arg2, arg3, 1);
8780             if (vec != NULL) {
8781                 ret = get_errno(vmsplice(arg1, vec, arg3, arg4));
8782                 unlock_iovec(vec, arg2, arg3, 0);
8783             } else {
8784                 ret = -host_to_target_errno(errno);
8785             }
8786         }
8787         break;
8788 #endif
8789 #endif /* CONFIG_SPLICE */
8790 #ifdef CONFIG_EVENTFD
8791 #if defined(TARGET_NR_eventfd)
8792     case TARGET_NR_eventfd:
8793         ret = get_errno(eventfd(arg1, 0));
8794         break;
8795 #endif
8796 #if defined(TARGET_NR_eventfd2)
8797     case TARGET_NR_eventfd2:
8798     {
8799         int host_flags = arg2 & (~(TARGET_O_NONBLOCK | TARGET_O_CLOEXEC));
8800         if (arg2 & TARGET_O_NONBLOCK) {
8801             host_flags |= O_NONBLOCK;
8802         }
8803         if (arg2 & TARGET_O_CLOEXEC) {
8804             host_flags |= O_CLOEXEC;
8805         }
8806         ret = get_errno(eventfd(arg1, host_flags));
8807         break;
8808     }
8809 #endif
8810 #endif /* CONFIG_EVENTFD  */
8811 #if defined(CONFIG_FALLOCATE) && defined(TARGET_NR_fallocate)
8812     case TARGET_NR_fallocate:
8813 #if TARGET_ABI_BITS == 32
8814         ret = get_errno(fallocate(arg1, arg2, target_offset64(arg3, arg4),
8815                                   target_offset64(arg5, arg6)));
8816 #else
8817         ret = get_errno(fallocate(arg1, arg2, arg3, arg4));
8818 #endif
8819         break;
8820 #endif
8821 #if defined(CONFIG_SYNC_FILE_RANGE)
8822 #if defined(TARGET_NR_sync_file_range)
8823     case TARGET_NR_sync_file_range:
8824 #if TARGET_ABI_BITS == 32
8825 #if defined(TARGET_MIPS)
8826         ret = get_errno(sync_file_range(arg1, target_offset64(arg3, arg4),
8827                                         target_offset64(arg5, arg6), arg7));
8828 #else
8829         ret = get_errno(sync_file_range(arg1, target_offset64(arg2, arg3),
8830                                         target_offset64(arg4, arg5), arg6));
8831 #endif /* !TARGET_MIPS */
8832 #else
8833         ret = get_errno(sync_file_range(arg1, arg2, arg3, arg4));
8834 #endif
8835         break;
8836 #endif
8837 #if defined(TARGET_NR_sync_file_range2)
8838     case TARGET_NR_sync_file_range2:
8839         /* This is like sync_file_range but the arguments are reordered */
8840 #if TARGET_ABI_BITS == 32
8841         ret = get_errno(sync_file_range(arg1, target_offset64(arg3, arg4),
8842                                         target_offset64(arg5, arg6), arg2));
8843 #else
8844         ret = get_errno(sync_file_range(arg1, arg3, arg4, arg2));
8845 #endif
8846         break;
8847 #endif
8848 #endif
8849 #if defined(CONFIG_EPOLL)
8850 #if defined(TARGET_NR_epoll_create)
8851     case TARGET_NR_epoll_create:
8852         ret = get_errno(epoll_create(arg1));
8853         break;
8854 #endif
8855 #if defined(TARGET_NR_epoll_create1) && defined(CONFIG_EPOLL_CREATE1)
8856     case TARGET_NR_epoll_create1:
8857         ret = get_errno(epoll_create1(arg1));
8858         break;
8859 #endif
8860 #if defined(TARGET_NR_epoll_ctl)
8861     case TARGET_NR_epoll_ctl:
8862     {
8863         struct epoll_event ep;
8864         struct epoll_event *epp = 0;
8865         if (arg4) {
8866             struct target_epoll_event *target_ep;
8867             if (!lock_user_struct(VERIFY_READ, target_ep, arg4, 1)) {
8868                 goto efault;
8869             }
8870             ep.events = tswap32(target_ep->events);
8871             /* The epoll_data_t union is just opaque data to the kernel,
8872              * so we transfer all 64 bits across and need not worry what
8873              * actual data type it is.
8874              */
8875             ep.data.u64 = tswap64(target_ep->data.u64);
8876             unlock_user_struct(target_ep, arg4, 0);
8877             epp = &ep;
8878         }
8879         ret = get_errno(epoll_ctl(arg1, arg2, arg3, epp));
8880         break;
8881     }
8882 #endif
8883
8884 #if defined(TARGET_NR_epoll_pwait) && defined(CONFIG_EPOLL_PWAIT)
8885 #define IMPLEMENT_EPOLL_PWAIT
8886 #endif
8887 #if defined(TARGET_NR_epoll_wait) || defined(IMPLEMENT_EPOLL_PWAIT)
8888 #if defined(TARGET_NR_epoll_wait)
8889     case TARGET_NR_epoll_wait:
8890 #endif
8891 #if defined(IMPLEMENT_EPOLL_PWAIT)
8892     case TARGET_NR_epoll_pwait:
8893 #endif
8894     {
8895         struct target_epoll_event *target_ep;
8896         struct epoll_event *ep;
8897         int epfd = arg1;
8898         int maxevents = arg3;
8899         int timeout = arg4;
8900
8901         target_ep = lock_user(VERIFY_WRITE, arg2,
8902                               maxevents * sizeof(struct target_epoll_event), 1);
8903         if (!target_ep) {
8904             goto efault;
8905         }
8906
8907         ep = alloca(maxevents * sizeof(struct epoll_event));
8908
8909         switch (num) {
8910 #if defined(IMPLEMENT_EPOLL_PWAIT)
8911         case TARGET_NR_epoll_pwait:
8912         {
8913             target_sigset_t *target_set;
8914             sigset_t _set, *set = &_set;
8915
8916             if (arg5) {
8917                 target_set = lock_user(VERIFY_READ, arg5,
8918                                        sizeof(target_sigset_t), 1);
8919                 if (!target_set) {
8920                     unlock_user(target_ep, arg2, 0);
8921                     goto efault;
8922                 }
8923                 target_to_host_sigset(set, target_set);
8924                 unlock_user(target_set, arg5, 0);
8925             } else {
8926                 set = NULL;
8927             }
8928
8929             ret = get_errno(epoll_pwait(epfd, ep, maxevents, timeout, set));
8930             break;
8931         }
8932 #endif
8933 #if defined(TARGET_NR_epoll_wait)
8934         case TARGET_NR_epoll_wait:
8935             ret = get_errno(epoll_wait(epfd, ep, maxevents, timeout));
8936             break;
8937 #endif
8938         default:
8939             ret = -TARGET_ENOSYS;
8940         }
8941         if (!is_error(ret)) {
8942             int i;
8943             for (i = 0; i < ret; i++) {
8944                 target_ep[i].events = tswap32(ep[i].events);
8945                 target_ep[i].data.u64 = tswap64(ep[i].data.u64);
8946             }
8947         }
8948         unlock_user(target_ep, arg2, ret * sizeof(struct target_epoll_event));
8949         break;
8950     }
8951 #endif
8952 #endif
8953 #ifdef TARGET_NR_prlimit64
8954     case TARGET_NR_prlimit64:
8955     {
8956         /* args: pid, resource number, ptr to new rlimit, ptr to old rlimit */
8957         struct target_rlimit64 *target_rnew, *target_rold;
8958         struct host_rlimit64 rnew, rold, *rnewp = 0;
8959         if (arg3) {
8960             if (!lock_user_struct(VERIFY_READ, target_rnew, arg3, 1)) {
8961                 goto efault;
8962             }
8963             rnew.rlim_cur = tswap64(target_rnew->rlim_cur);
8964             rnew.rlim_max = tswap64(target_rnew->rlim_max);
8965             unlock_user_struct(target_rnew, arg3, 0);
8966             rnewp = &rnew;
8967         }
8968
8969         ret = get_errno(sys_prlimit64(arg1, arg2, rnewp, arg4 ? &rold : 0));
8970         if (!is_error(ret) && arg4) {
8971             if (!lock_user_struct(VERIFY_WRITE, target_rold, arg4, 1)) {
8972                 goto efault;
8973             }
8974             target_rold->rlim_cur = tswap64(rold.rlim_cur);
8975             target_rold->rlim_max = tswap64(rold.rlim_max);
8976             unlock_user_struct(target_rold, arg4, 1);
8977         }
8978         break;
8979     }
8980 #endif
8981 #ifdef TARGET_NR_gethostname
8982     case TARGET_NR_gethostname:
8983     {
8984         char *name = lock_user(VERIFY_WRITE, arg1, arg2, 0);
8985         if (name) {
8986             ret = get_errno(gethostname(name, arg2));
8987             unlock_user(name, arg1, arg2);
8988         } else {
8989             ret = -TARGET_EFAULT;
8990         }
8991         break;
8992     }
8993 #endif
8994     default:
8995     unimplemented:
8996         gemu_log("qemu: Unsupported syscall: %d\n", num);
8997 #if defined(TARGET_NR_setxattr) || defined(TARGET_NR_get_thread_area) || defined(TARGET_NR_getdomainname) || defined(TARGET_NR_set_robust_list)
8998     unimplemented_nowarn:
8999 #endif
9000         ret = -TARGET_ENOSYS;
9001         break;
9002     }
9003 fail:
9004 #ifdef DEBUG
9005     gemu_log(" = " TARGET_ABI_FMT_ld "\n", ret);
9006 #endif
9007     if(do_strace)
9008         print_syscall_ret(num, ret);
9009     return ret;
9010 efault:
9011     ret = -TARGET_EFAULT;
9012     goto fail;
9013 }