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