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