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