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