xref: /openbmc/qemu/linux-user/syscall.c (revision 3f9ac9b39bd82b51f6aa46103836ae12bcbcb22e)
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, write to the Free Software
18  *  Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston,
19  *  MA 02110-1301, USA.
20  */
21 #define _ATFILE_SOURCE
22 #include <stdlib.h>
23 #include <stdio.h>
24 #include <stdarg.h>
25 #include <string.h>
26 #include <elf.h>
27 #include <endian.h>
28 #include <errno.h>
29 #include <unistd.h>
30 #include <fcntl.h>
31 #include <time.h>
32 #include <limits.h>
33 #include <mqueue.h>
34 #include <sys/types.h>
35 #include <sys/ipc.h>
36 #include <sys/msg.h>
37 #include <sys/wait.h>
38 #include <sys/time.h>
39 #include <sys/stat.h>
40 #include <sys/mount.h>
41 #include <sys/prctl.h>
42 #include <sys/resource.h>
43 #include <sys/mman.h>
44 #include <sys/swap.h>
45 #include <signal.h>
46 #include <sched.h>
47 #include <sys/socket.h>
48 #include <sys/un.h>
49 #include <sys/uio.h>
50 #include <sys/poll.h>
51 #include <sys/times.h>
52 #include <sys/shm.h>
53 #include <sys/sem.h>
54 #include <sys/statfs.h>
55 #include <utime.h>
56 #include <sys/sysinfo.h>
57 #include <sys/utsname.h>
58 //#include <sys/user.h>
59 #include <netinet/ip.h>
60 #include <netinet/tcp.h>
61 #include <qemu-common.h>
62 #ifdef HAVE_GPROF
63 #include <sys/gmon.h>
64 #endif
65 
66 #define termios host_termios
67 #define winsize host_winsize
68 #define termio host_termio
69 #define sgttyb host_sgttyb /* same as target */
70 #define tchars host_tchars /* same as target */
71 #define ltchars host_ltchars /* same as target */
72 
73 #include <linux/termios.h>
74 #include <linux/unistd.h>
75 #include <linux/utsname.h>
76 #include <linux/cdrom.h>
77 #include <linux/hdreg.h>
78 #include <linux/soundcard.h>
79 #include <linux/kd.h>
80 #include <linux/mtio.h>
81 #include <linux/fs.h>
82 #include "linux_loop.h"
83 
84 #include "qemu.h"
85 #include "qemu-common.h"
86 
87 #if defined(USE_NPTL)
88 #include <linux/futex.h>
89 #define CLONE_NPTL_FLAGS2 (CLONE_SETTLS | \
90     CLONE_PARENT_SETTID | CLONE_CHILD_SETTID | CLONE_CHILD_CLEARTID)
91 #else
92 /* XXX: Hardcode the above values.  */
93 #define CLONE_NPTL_FLAGS2 0
94 #endif
95 
96 //#define DEBUG
97 
98 //#include <linux/msdos_fs.h>
99 #define	VFAT_IOCTL_READDIR_BOTH		_IOR('r', 1, struct linux_dirent [2])
100 #define	VFAT_IOCTL_READDIR_SHORT	_IOR('r', 2, struct linux_dirent [2])
101 
102 
103 #undef _syscall0
104 #undef _syscall1
105 #undef _syscall2
106 #undef _syscall3
107 #undef _syscall4
108 #undef _syscall5
109 #undef _syscall6
110 
111 #define _syscall0(type,name)		\
112 static type name (void)			\
113 {					\
114 	return syscall(__NR_##name);	\
115 }
116 
117 #define _syscall1(type,name,type1,arg1)		\
118 static type name (type1 arg1)			\
119 {						\
120 	return syscall(__NR_##name, arg1);	\
121 }
122 
123 #define _syscall2(type,name,type1,arg1,type2,arg2)	\
124 static type name (type1 arg1,type2 arg2)		\
125 {							\
126 	return syscall(__NR_##name, arg1, arg2);	\
127 }
128 
129 #define _syscall3(type,name,type1,arg1,type2,arg2,type3,arg3)	\
130 static type name (type1 arg1,type2 arg2,type3 arg3)		\
131 {								\
132 	return syscall(__NR_##name, arg1, arg2, arg3);		\
133 }
134 
135 #define _syscall4(type,name,type1,arg1,type2,arg2,type3,arg3,type4,arg4)	\
136 static type name (type1 arg1,type2 arg2,type3 arg3,type4 arg4)			\
137 {										\
138 	return syscall(__NR_##name, arg1, arg2, arg3, arg4);			\
139 }
140 
141 #define _syscall5(type,name,type1,arg1,type2,arg2,type3,arg3,type4,arg4,	\
142 		  type5,arg5)							\
143 static type name (type1 arg1,type2 arg2,type3 arg3,type4 arg4,type5 arg5)	\
144 {										\
145 	return syscall(__NR_##name, arg1, arg2, arg3, arg4, arg5);		\
146 }
147 
148 
149 #define _syscall6(type,name,type1,arg1,type2,arg2,type3,arg3,type4,arg4,	\
150 		  type5,arg5,type6,arg6)					\
151 static type name (type1 arg1,type2 arg2,type3 arg3,type4 arg4,type5 arg5,	\
152                   type6 arg6)							\
153 {										\
154 	return syscall(__NR_##name, arg1, arg2, arg3, arg4, arg5, arg6);	\
155 }
156 
157 
158 #define __NR_sys_uname __NR_uname
159 #define __NR_sys_faccessat __NR_faccessat
160 #define __NR_sys_fchmodat __NR_fchmodat
161 #define __NR_sys_fchownat __NR_fchownat
162 #define __NR_sys_fstatat64 __NR_fstatat64
163 #define __NR_sys_futimesat __NR_futimesat
164 #define __NR_sys_getcwd1 __NR_getcwd
165 #define __NR_sys_getdents __NR_getdents
166 #define __NR_sys_getdents64 __NR_getdents64
167 #define __NR_sys_getpriority __NR_getpriority
168 #define __NR_sys_linkat __NR_linkat
169 #define __NR_sys_mkdirat __NR_mkdirat
170 #define __NR_sys_mknodat __NR_mknodat
171 #define __NR_sys_newfstatat __NR_newfstatat
172 #define __NR_sys_openat __NR_openat
173 #define __NR_sys_readlinkat __NR_readlinkat
174 #define __NR_sys_renameat __NR_renameat
175 #define __NR_sys_rt_sigqueueinfo __NR_rt_sigqueueinfo
176 #define __NR_sys_symlinkat __NR_symlinkat
177 #define __NR_sys_syslog __NR_syslog
178 #define __NR_sys_tgkill __NR_tgkill
179 #define __NR_sys_tkill __NR_tkill
180 #define __NR_sys_unlinkat __NR_unlinkat
181 #define __NR_sys_utimensat __NR_utimensat
182 #define __NR_sys_futex __NR_futex
183 #define __NR_sys_inotify_init __NR_inotify_init
184 #define __NR_sys_inotify_add_watch __NR_inotify_add_watch
185 #define __NR_sys_inotify_rm_watch __NR_inotify_rm_watch
186 
187 #if defined(__alpha__) || defined (__ia64__) || defined(__x86_64__)
188 #define __NR__llseek __NR_lseek
189 #endif
190 
191 #ifdef __NR_gettid
192 _syscall0(int, gettid)
193 #else
194 /* This is a replacement for the host gettid() and must return a host
195    errno. */
196 static int gettid(void) {
197     return -ENOSYS;
198 }
199 #endif
200 #if TARGET_ABI_BITS == 32
201 _syscall3(int, sys_getdents, uint, fd, struct linux_dirent *, dirp, uint, count);
202 #endif
203 #if defined(TARGET_NR_getdents64) && defined(__NR_getdents64)
204 _syscall3(int, sys_getdents64, uint, fd, struct linux_dirent64 *, dirp, uint, count);
205 #endif
206 _syscall2(int, sys_getpriority, int, which, int, who);
207 #if defined(TARGET_NR__llseek) && !defined (__x86_64__)
208 _syscall5(int, _llseek,  uint,  fd, ulong, hi, ulong, lo,
209           loff_t *, res, uint, wh);
210 #endif
211 _syscall3(int,sys_rt_sigqueueinfo,int,pid,int,sig,siginfo_t *,uinfo)
212 _syscall3(int,sys_syslog,int,type,char*,bufp,int,len)
213 #if defined(TARGET_NR_tgkill) && defined(__NR_tgkill)
214 _syscall3(int,sys_tgkill,int,tgid,int,pid,int,sig)
215 #endif
216 #if defined(TARGET_NR_tkill) && defined(__NR_tkill)
217 _syscall2(int,sys_tkill,int,tid,int,sig)
218 #endif
219 #ifdef __NR_exit_group
220 _syscall1(int,exit_group,int,error_code)
221 #endif
222 #if defined(TARGET_NR_set_tid_address) && defined(__NR_set_tid_address)
223 _syscall1(int,set_tid_address,int *,tidptr)
224 #endif
225 #if defined(USE_NPTL)
226 #if defined(TARGET_NR_futex) && defined(__NR_futex)
227 _syscall6(int,sys_futex,int *,uaddr,int,op,int,val,
228           const struct timespec *,timeout,int *,uaddr2,int,val3)
229 #endif
230 #endif
231 
232 static bitmask_transtbl fcntl_flags_tbl[] = {
233   { TARGET_O_ACCMODE,   TARGET_O_WRONLY,    O_ACCMODE,   O_WRONLY,    },
234   { TARGET_O_ACCMODE,   TARGET_O_RDWR,      O_ACCMODE,   O_RDWR,      },
235   { TARGET_O_CREAT,     TARGET_O_CREAT,     O_CREAT,     O_CREAT,     },
236   { TARGET_O_EXCL,      TARGET_O_EXCL,      O_EXCL,      O_EXCL,      },
237   { TARGET_O_NOCTTY,    TARGET_O_NOCTTY,    O_NOCTTY,    O_NOCTTY,    },
238   { TARGET_O_TRUNC,     TARGET_O_TRUNC,     O_TRUNC,     O_TRUNC,     },
239   { TARGET_O_APPEND,    TARGET_O_APPEND,    O_APPEND,    O_APPEND,    },
240   { TARGET_O_NONBLOCK,  TARGET_O_NONBLOCK,  O_NONBLOCK,  O_NONBLOCK,  },
241   { TARGET_O_SYNC,      TARGET_O_SYNC,      O_SYNC,      O_SYNC,      },
242   { TARGET_FASYNC,      TARGET_FASYNC,      FASYNC,      FASYNC,      },
243   { TARGET_O_DIRECTORY, TARGET_O_DIRECTORY, O_DIRECTORY, O_DIRECTORY, },
244   { TARGET_O_NOFOLLOW,  TARGET_O_NOFOLLOW,  O_NOFOLLOW,  O_NOFOLLOW,  },
245   { TARGET_O_LARGEFILE, TARGET_O_LARGEFILE, O_LARGEFILE, O_LARGEFILE, },
246 #if defined(O_DIRECT)
247   { TARGET_O_DIRECT,    TARGET_O_DIRECT,    O_DIRECT,    O_DIRECT,    },
248 #endif
249   { 0, 0, 0, 0 }
250 };
251 
252 #define COPY_UTSNAME_FIELD(dest, src) \
253   do { \
254       /* __NEW_UTS_LEN doesn't include terminating null */ \
255       (void) strncpy((dest), (src), __NEW_UTS_LEN); \
256       (dest)[__NEW_UTS_LEN] = '\0'; \
257   } while (0)
258 
259 static int sys_uname(struct new_utsname *buf)
260 {
261   struct utsname uts_buf;
262 
263   if (uname(&uts_buf) < 0)
264       return (-1);
265 
266   /*
267    * Just in case these have some differences, we
268    * translate utsname to new_utsname (which is the
269    * struct linux kernel uses).
270    */
271 
272   bzero(buf, sizeof (*buf));
273   COPY_UTSNAME_FIELD(buf->sysname, uts_buf.sysname);
274   COPY_UTSNAME_FIELD(buf->nodename, uts_buf.nodename);
275   COPY_UTSNAME_FIELD(buf->release, uts_buf.release);
276   COPY_UTSNAME_FIELD(buf->version, uts_buf.version);
277   COPY_UTSNAME_FIELD(buf->machine, uts_buf.machine);
278 #ifdef _GNU_SOURCE
279   COPY_UTSNAME_FIELD(buf->domainname, uts_buf.domainname);
280 #endif
281   return (0);
282 
283 #undef COPY_UTSNAME_FIELD
284 }
285 
286 static int sys_getcwd1(char *buf, size_t size)
287 {
288   if (getcwd(buf, size) == NULL) {
289       /* getcwd() sets errno */
290       return (-1);
291   }
292   return strlen(buf)+1;
293 }
294 
295 #ifdef CONFIG_ATFILE
296 /*
297  * Host system seems to have atfile syscall stubs available.  We
298  * now enable them one by one as specified by target syscall_nr.h.
299  */
300 
301 #ifdef TARGET_NR_faccessat
302 static int sys_faccessat(int dirfd, const char *pathname, int mode)
303 {
304   return (faccessat(dirfd, pathname, mode, 0));
305 }
306 #endif
307 #ifdef TARGET_NR_fchmodat
308 static int sys_fchmodat(int dirfd, const char *pathname, mode_t mode)
309 {
310   return (fchmodat(dirfd, pathname, mode, 0));
311 }
312 #endif
313 #if defined(TARGET_NR_fchownat) && defined(USE_UID16)
314 static int sys_fchownat(int dirfd, const char *pathname, uid_t owner,
315     gid_t group, int flags)
316 {
317   return (fchownat(dirfd, pathname, owner, group, flags));
318 }
319 #endif
320 #ifdef __NR_fstatat64
321 static int sys_fstatat64(int dirfd, const char *pathname, struct stat *buf,
322     int flags)
323 {
324   return (fstatat(dirfd, pathname, buf, flags));
325 }
326 #endif
327 #ifdef __NR_newfstatat
328 static int sys_newfstatat(int dirfd, const char *pathname, struct stat *buf,
329     int flags)
330 {
331   return (fstatat(dirfd, pathname, buf, flags));
332 }
333 #endif
334 #ifdef TARGET_NR_futimesat
335 static int sys_futimesat(int dirfd, const char *pathname,
336     const struct timeval times[2])
337 {
338   return (futimesat(dirfd, pathname, times));
339 }
340 #endif
341 #ifdef TARGET_NR_linkat
342 static int sys_linkat(int olddirfd, const char *oldpath,
343     int newdirfd, const char *newpath, int flags)
344 {
345   return (linkat(olddirfd, oldpath, newdirfd, newpath, flags));
346 }
347 #endif
348 #ifdef TARGET_NR_mkdirat
349 static int sys_mkdirat(int dirfd, const char *pathname, mode_t mode)
350 {
351   return (mkdirat(dirfd, pathname, mode));
352 }
353 #endif
354 #ifdef TARGET_NR_mknodat
355 static int sys_mknodat(int dirfd, const char *pathname, mode_t mode,
356     dev_t dev)
357 {
358   return (mknodat(dirfd, pathname, mode, dev));
359 }
360 #endif
361 #ifdef TARGET_NR_openat
362 static int sys_openat(int dirfd, const char *pathname, int flags, ...)
363 {
364   /*
365    * open(2) has extra parameter 'mode' when called with
366    * flag O_CREAT.
367    */
368   if ((flags & O_CREAT) != 0) {
369       va_list ap;
370       mode_t mode;
371 
372       /*
373        * Get the 'mode' parameter and translate it to
374        * host bits.
375        */
376       va_start(ap, flags);
377       mode = va_arg(ap, mode_t);
378       mode = target_to_host_bitmask(mode, fcntl_flags_tbl);
379       va_end(ap);
380 
381       return (openat(dirfd, pathname, flags, mode));
382   }
383   return (openat(dirfd, pathname, flags));
384 }
385 #endif
386 #ifdef TARGET_NR_readlinkat
387 static int sys_readlinkat(int dirfd, const char *pathname, char *buf, size_t bufsiz)
388 {
389   return (readlinkat(dirfd, pathname, buf, bufsiz));
390 }
391 #endif
392 #ifdef TARGET_NR_renameat
393 static int sys_renameat(int olddirfd, const char *oldpath,
394     int newdirfd, const char *newpath)
395 {
396   return (renameat(olddirfd, oldpath, newdirfd, newpath));
397 }
398 #endif
399 #ifdef TARGET_NR_symlinkat
400 static int sys_symlinkat(const char *oldpath, int newdirfd, const char *newpath)
401 {
402   return (symlinkat(oldpath, newdirfd, newpath));
403 }
404 #endif
405 #ifdef TARGET_NR_unlinkat
406 static int sys_unlinkat(int dirfd, const char *pathname, int flags)
407 {
408   return (unlinkat(dirfd, pathname, flags));
409 }
410 #endif
411 #else /* !CONFIG_ATFILE */
412 
413 /*
414  * Try direct syscalls instead
415  */
416 #if defined(TARGET_NR_faccessat) && defined(__NR_faccessat)
417 _syscall3(int,sys_faccessat,int,dirfd,const char *,pathname,int,mode)
418 #endif
419 #if defined(TARGET_NR_fchmodat) && defined(__NR_fchmodat)
420 _syscall3(int,sys_fchmodat,int,dirfd,const char *,pathname, mode_t,mode)
421 #endif
422 #if defined(TARGET_NR_fchownat) && defined(__NR_fchownat) && defined(USE_UID16)
423 _syscall5(int,sys_fchownat,int,dirfd,const char *,pathname,
424           uid_t,owner,gid_t,group,int,flags)
425 #endif
426 #if (defined(TARGET_NR_fstatat64) || defined(TARGET_NR_newfstatat)) && \
427         defined(__NR_fstatat64)
428 _syscall4(int,sys_fstatat64,int,dirfd,const char *,pathname,
429           struct stat *,buf,int,flags)
430 #endif
431 #if defined(TARGET_NR_futimesat) && defined(__NR_futimesat)
432 _syscall3(int,sys_futimesat,int,dirfd,const char *,pathname,
433          const struct timeval *,times)
434 #endif
435 #if (defined(TARGET_NR_newfstatat) || defined(TARGET_NR_fstatat64) ) && \
436         defined(__NR_newfstatat)
437 _syscall4(int,sys_newfstatat,int,dirfd,const char *,pathname,
438           struct stat *,buf,int,flags)
439 #endif
440 #if defined(TARGET_NR_linkat) && defined(__NR_linkat)
441 _syscall5(int,sys_linkat,int,olddirfd,const char *,oldpath,
442       int,newdirfd,const char *,newpath,int,flags)
443 #endif
444 #if defined(TARGET_NR_mkdirat) && defined(__NR_mkdirat)
445 _syscall3(int,sys_mkdirat,int,dirfd,const char *,pathname,mode_t,mode)
446 #endif
447 #if defined(TARGET_NR_mknodat) && defined(__NR_mknodat)
448 _syscall4(int,sys_mknodat,int,dirfd,const char *,pathname,
449           mode_t,mode,dev_t,dev)
450 #endif
451 #if defined(TARGET_NR_openat) && defined(__NR_openat)
452 _syscall4(int,sys_openat,int,dirfd,const char *,pathname,int,flags,mode_t,mode)
453 #endif
454 #if defined(TARGET_NR_readlinkat) && defined(__NR_readlinkat)
455 _syscall4(int,sys_readlinkat,int,dirfd,const char *,pathname,
456           char *,buf,size_t,bufsize)
457 #endif
458 #if defined(TARGET_NR_renameat) && defined(__NR_renameat)
459 _syscall4(int,sys_renameat,int,olddirfd,const char *,oldpath,
460           int,newdirfd,const char *,newpath)
461 #endif
462 #if defined(TARGET_NR_symlinkat) && defined(__NR_symlinkat)
463 _syscall3(int,sys_symlinkat,const char *,oldpath,
464           int,newdirfd,const char *,newpath)
465 #endif
466 #if defined(TARGET_NR_unlinkat) && defined(__NR_unlinkat)
467 _syscall3(int,sys_unlinkat,int,dirfd,const char *,pathname,int,flags)
468 #endif
469 
470 #endif /* CONFIG_ATFILE */
471 
472 #ifdef CONFIG_UTIMENSAT
473 static int sys_utimensat(int dirfd, const char *pathname,
474     const struct timespec times[2], int flags)
475 {
476     if (pathname == NULL)
477         return futimens(dirfd, times);
478     else
479         return utimensat(dirfd, pathname, times, flags);
480 }
481 #else
482 #if defined(TARGET_NR_utimensat) && defined(__NR_utimensat)
483 _syscall4(int,sys_utimensat,int,dirfd,const char *,pathname,
484           const struct timespec *,tsp,int,flags)
485 #endif
486 #endif /* CONFIG_UTIMENSAT  */
487 
488 #ifdef CONFIG_INOTIFY
489 #include <sys/inotify.h>
490 
491 #if defined(TARGET_NR_inotify_init) && defined(__NR_inotify_init)
492 static int sys_inotify_init(void)
493 {
494   return (inotify_init());
495 }
496 #endif
497 #if defined(TARGET_NR_inotify_add_watch) && defined(__NR_inotify_add_watch)
498 static int sys_inotify_add_watch(int fd,const char *pathname, int32_t mask)
499 {
500   return (inotify_add_watch(fd, pathname, mask));
501 }
502 #endif
503 #if defined(TARGET_NR_inotify_rm_watch) && defined(__NR_inotify_rm_watch)
504 static int sys_inotify_rm_watch(int fd, int32_t wd)
505 {
506   return (inotify_rm_watch(fd, wd));
507 }
508 #endif
509 #else
510 /* Userspace can usually survive runtime without inotify */
511 #undef TARGET_NR_inotify_init
512 #undef TARGET_NR_inotify_add_watch
513 #undef TARGET_NR_inotify_rm_watch
514 #endif /* CONFIG_INOTIFY  */
515 
516 
517 extern int personality(int);
518 extern int flock(int, int);
519 extern int setfsuid(int);
520 extern int setfsgid(int);
521 extern int setgroups(int, gid_t *);
522 
523 #define ERRNO_TABLE_SIZE 1200
524 
525 /* target_to_host_errno_table[] is initialized from
526  * host_to_target_errno_table[] in syscall_init(). */
527 static uint16_t target_to_host_errno_table[ERRNO_TABLE_SIZE] = {
528 };
529 
530 /*
531  * This list is the union of errno values overridden in asm-<arch>/errno.h
532  * minus the errnos that are not actually generic to all archs.
533  */
534 static uint16_t host_to_target_errno_table[ERRNO_TABLE_SIZE] = {
535     [EIDRM]		= TARGET_EIDRM,
536     [ECHRNG]		= TARGET_ECHRNG,
537     [EL2NSYNC]		= TARGET_EL2NSYNC,
538     [EL3HLT]		= TARGET_EL3HLT,
539     [EL3RST]		= TARGET_EL3RST,
540     [ELNRNG]		= TARGET_ELNRNG,
541     [EUNATCH]		= TARGET_EUNATCH,
542     [ENOCSI]		= TARGET_ENOCSI,
543     [EL2HLT]		= TARGET_EL2HLT,
544     [EDEADLK]		= TARGET_EDEADLK,
545     [ENOLCK]		= TARGET_ENOLCK,
546     [EBADE]		= TARGET_EBADE,
547     [EBADR]		= TARGET_EBADR,
548     [EXFULL]		= TARGET_EXFULL,
549     [ENOANO]		= TARGET_ENOANO,
550     [EBADRQC]		= TARGET_EBADRQC,
551     [EBADSLT]		= TARGET_EBADSLT,
552     [EBFONT]		= TARGET_EBFONT,
553     [ENOSTR]		= TARGET_ENOSTR,
554     [ENODATA]		= TARGET_ENODATA,
555     [ETIME]		= TARGET_ETIME,
556     [ENOSR]		= TARGET_ENOSR,
557     [ENONET]		= TARGET_ENONET,
558     [ENOPKG]		= TARGET_ENOPKG,
559     [EREMOTE]		= TARGET_EREMOTE,
560     [ENOLINK]		= TARGET_ENOLINK,
561     [EADV]		= TARGET_EADV,
562     [ESRMNT]		= TARGET_ESRMNT,
563     [ECOMM]		= TARGET_ECOMM,
564     [EPROTO]		= TARGET_EPROTO,
565     [EDOTDOT]		= TARGET_EDOTDOT,
566     [EMULTIHOP]		= TARGET_EMULTIHOP,
567     [EBADMSG]		= TARGET_EBADMSG,
568     [ENAMETOOLONG]	= TARGET_ENAMETOOLONG,
569     [EOVERFLOW]		= TARGET_EOVERFLOW,
570     [ENOTUNIQ]		= TARGET_ENOTUNIQ,
571     [EBADFD]		= TARGET_EBADFD,
572     [EREMCHG]		= TARGET_EREMCHG,
573     [ELIBACC]		= TARGET_ELIBACC,
574     [ELIBBAD]		= TARGET_ELIBBAD,
575     [ELIBSCN]		= TARGET_ELIBSCN,
576     [ELIBMAX]		= TARGET_ELIBMAX,
577     [ELIBEXEC]		= TARGET_ELIBEXEC,
578     [EILSEQ]		= TARGET_EILSEQ,
579     [ENOSYS]		= TARGET_ENOSYS,
580     [ELOOP]		= TARGET_ELOOP,
581     [ERESTART]		= TARGET_ERESTART,
582     [ESTRPIPE]		= TARGET_ESTRPIPE,
583     [ENOTEMPTY]		= TARGET_ENOTEMPTY,
584     [EUSERS]		= TARGET_EUSERS,
585     [ENOTSOCK]		= TARGET_ENOTSOCK,
586     [EDESTADDRREQ]	= TARGET_EDESTADDRREQ,
587     [EMSGSIZE]		= TARGET_EMSGSIZE,
588     [EPROTOTYPE]	= TARGET_EPROTOTYPE,
589     [ENOPROTOOPT]	= TARGET_ENOPROTOOPT,
590     [EPROTONOSUPPORT]	= TARGET_EPROTONOSUPPORT,
591     [ESOCKTNOSUPPORT]	= TARGET_ESOCKTNOSUPPORT,
592     [EOPNOTSUPP]	= TARGET_EOPNOTSUPP,
593     [EPFNOSUPPORT]	= TARGET_EPFNOSUPPORT,
594     [EAFNOSUPPORT]	= TARGET_EAFNOSUPPORT,
595     [EADDRINUSE]	= TARGET_EADDRINUSE,
596     [EADDRNOTAVAIL]	= TARGET_EADDRNOTAVAIL,
597     [ENETDOWN]		= TARGET_ENETDOWN,
598     [ENETUNREACH]	= TARGET_ENETUNREACH,
599     [ENETRESET]		= TARGET_ENETRESET,
600     [ECONNABORTED]	= TARGET_ECONNABORTED,
601     [ECONNRESET]	= TARGET_ECONNRESET,
602     [ENOBUFS]		= TARGET_ENOBUFS,
603     [EISCONN]		= TARGET_EISCONN,
604     [ENOTCONN]		= TARGET_ENOTCONN,
605     [EUCLEAN]		= TARGET_EUCLEAN,
606     [ENOTNAM]		= TARGET_ENOTNAM,
607     [ENAVAIL]		= TARGET_ENAVAIL,
608     [EISNAM]		= TARGET_EISNAM,
609     [EREMOTEIO]		= TARGET_EREMOTEIO,
610     [ESHUTDOWN]		= TARGET_ESHUTDOWN,
611     [ETOOMANYREFS]	= TARGET_ETOOMANYREFS,
612     [ETIMEDOUT]		= TARGET_ETIMEDOUT,
613     [ECONNREFUSED]	= TARGET_ECONNREFUSED,
614     [EHOSTDOWN]		= TARGET_EHOSTDOWN,
615     [EHOSTUNREACH]	= TARGET_EHOSTUNREACH,
616     [EALREADY]		= TARGET_EALREADY,
617     [EINPROGRESS]	= TARGET_EINPROGRESS,
618     [ESTALE]		= TARGET_ESTALE,
619     [ECANCELED]		= TARGET_ECANCELED,
620     [ENOMEDIUM]		= TARGET_ENOMEDIUM,
621     [EMEDIUMTYPE]	= TARGET_EMEDIUMTYPE,
622 #ifdef ENOKEY
623     [ENOKEY]		= TARGET_ENOKEY,
624 #endif
625 #ifdef EKEYEXPIRED
626     [EKEYEXPIRED]	= TARGET_EKEYEXPIRED,
627 #endif
628 #ifdef EKEYREVOKED
629     [EKEYREVOKED]	= TARGET_EKEYREVOKED,
630 #endif
631 #ifdef EKEYREJECTED
632     [EKEYREJECTED]	= TARGET_EKEYREJECTED,
633 #endif
634 #ifdef EOWNERDEAD
635     [EOWNERDEAD]	= TARGET_EOWNERDEAD,
636 #endif
637 #ifdef ENOTRECOVERABLE
638     [ENOTRECOVERABLE]	= TARGET_ENOTRECOVERABLE,
639 #endif
640 };
641 
642 static inline int host_to_target_errno(int err)
643 {
644     if(host_to_target_errno_table[err])
645         return host_to_target_errno_table[err];
646     return err;
647 }
648 
649 static inline int target_to_host_errno(int err)
650 {
651     if (target_to_host_errno_table[err])
652         return target_to_host_errno_table[err];
653     return err;
654 }
655 
656 static inline abi_long get_errno(abi_long ret)
657 {
658     if (ret == -1)
659         return -host_to_target_errno(errno);
660     else
661         return ret;
662 }
663 
664 static inline int is_error(abi_long ret)
665 {
666     return (abi_ulong)ret >= (abi_ulong)(-4096);
667 }
668 
669 char *target_strerror(int err)
670 {
671     return strerror(target_to_host_errno(err));
672 }
673 
674 static abi_ulong target_brk;
675 static abi_ulong target_original_brk;
676 
677 void target_set_brk(abi_ulong new_brk)
678 {
679     target_original_brk = target_brk = HOST_PAGE_ALIGN(new_brk);
680 }
681 
682 /* do_brk() must return target values and target errnos. */
683 abi_long do_brk(abi_ulong new_brk)
684 {
685     abi_ulong brk_page;
686     abi_long mapped_addr;
687     int	new_alloc_size;
688 
689     if (!new_brk)
690         return target_brk;
691     if (new_brk < target_original_brk)
692         return target_brk;
693 
694     brk_page = HOST_PAGE_ALIGN(target_brk);
695 
696     /* If the new brk is less than this, set it and we're done... */
697     if (new_brk < brk_page) {
698 	target_brk = new_brk;
699     	return target_brk;
700     }
701 
702     /* We need to allocate more memory after the brk... */
703     new_alloc_size = HOST_PAGE_ALIGN(new_brk - brk_page + 1);
704     mapped_addr = get_errno(target_mmap(brk_page, new_alloc_size,
705                                         PROT_READ|PROT_WRITE,
706                                         MAP_ANON|MAP_FIXED|MAP_PRIVATE, 0, 0));
707 
708     if (!is_error(mapped_addr))
709 	target_brk = new_brk;
710 
711     return target_brk;
712 }
713 
714 static inline abi_long copy_from_user_fdset(fd_set *fds,
715                                             abi_ulong target_fds_addr,
716                                             int n)
717 {
718     int i, nw, j, k;
719     abi_ulong b, *target_fds;
720 
721     nw = (n + TARGET_ABI_BITS - 1) / TARGET_ABI_BITS;
722     if (!(target_fds = lock_user(VERIFY_READ,
723                                  target_fds_addr,
724                                  sizeof(abi_ulong) * nw,
725                                  1)))
726         return -TARGET_EFAULT;
727 
728     FD_ZERO(fds);
729     k = 0;
730     for (i = 0; i < nw; i++) {
731         /* grab the abi_ulong */
732         __get_user(b, &target_fds[i]);
733         for (j = 0; j < TARGET_ABI_BITS; j++) {
734             /* check the bit inside the abi_ulong */
735             if ((b >> j) & 1)
736                 FD_SET(k, fds);
737             k++;
738         }
739     }
740 
741     unlock_user(target_fds, target_fds_addr, 0);
742 
743     return 0;
744 }
745 
746 static inline abi_long copy_to_user_fdset(abi_ulong target_fds_addr,
747                                           const fd_set *fds,
748                                           int n)
749 {
750     int i, nw, j, k;
751     abi_long v;
752     abi_ulong *target_fds;
753 
754     nw = (n + TARGET_ABI_BITS - 1) / TARGET_ABI_BITS;
755     if (!(target_fds = lock_user(VERIFY_WRITE,
756                                  target_fds_addr,
757                                  sizeof(abi_ulong) * nw,
758                                  0)))
759         return -TARGET_EFAULT;
760 
761     k = 0;
762     for (i = 0; i < nw; i++) {
763         v = 0;
764         for (j = 0; j < TARGET_ABI_BITS; j++) {
765             v |= ((FD_ISSET(k, fds) != 0) << j);
766             k++;
767         }
768         __put_user(v, &target_fds[i]);
769     }
770 
771     unlock_user(target_fds, target_fds_addr, sizeof(abi_ulong) * nw);
772 
773     return 0;
774 }
775 
776 #if defined(__alpha__)
777 #define HOST_HZ 1024
778 #else
779 #define HOST_HZ 100
780 #endif
781 
782 static inline abi_long host_to_target_clock_t(long ticks)
783 {
784 #if HOST_HZ == TARGET_HZ
785     return ticks;
786 #else
787     return ((int64_t)ticks * TARGET_HZ) / HOST_HZ;
788 #endif
789 }
790 
791 static inline abi_long host_to_target_rusage(abi_ulong target_addr,
792                                              const struct rusage *rusage)
793 {
794     struct target_rusage *target_rusage;
795 
796     if (!lock_user_struct(VERIFY_WRITE, target_rusage, target_addr, 0))
797         return -TARGET_EFAULT;
798     target_rusage->ru_utime.tv_sec = tswapl(rusage->ru_utime.tv_sec);
799     target_rusage->ru_utime.tv_usec = tswapl(rusage->ru_utime.tv_usec);
800     target_rusage->ru_stime.tv_sec = tswapl(rusage->ru_stime.tv_sec);
801     target_rusage->ru_stime.tv_usec = tswapl(rusage->ru_stime.tv_usec);
802     target_rusage->ru_maxrss = tswapl(rusage->ru_maxrss);
803     target_rusage->ru_ixrss = tswapl(rusage->ru_ixrss);
804     target_rusage->ru_idrss = tswapl(rusage->ru_idrss);
805     target_rusage->ru_isrss = tswapl(rusage->ru_isrss);
806     target_rusage->ru_minflt = tswapl(rusage->ru_minflt);
807     target_rusage->ru_majflt = tswapl(rusage->ru_majflt);
808     target_rusage->ru_nswap = tswapl(rusage->ru_nswap);
809     target_rusage->ru_inblock = tswapl(rusage->ru_inblock);
810     target_rusage->ru_oublock = tswapl(rusage->ru_oublock);
811     target_rusage->ru_msgsnd = tswapl(rusage->ru_msgsnd);
812     target_rusage->ru_msgrcv = tswapl(rusage->ru_msgrcv);
813     target_rusage->ru_nsignals = tswapl(rusage->ru_nsignals);
814     target_rusage->ru_nvcsw = tswapl(rusage->ru_nvcsw);
815     target_rusage->ru_nivcsw = tswapl(rusage->ru_nivcsw);
816     unlock_user_struct(target_rusage, target_addr, 1);
817 
818     return 0;
819 }
820 
821 static inline abi_long copy_from_user_timeval(struct timeval *tv,
822                                               abi_ulong target_tv_addr)
823 {
824     struct target_timeval *target_tv;
825 
826     if (!lock_user_struct(VERIFY_READ, target_tv, target_tv_addr, 1))
827         return -TARGET_EFAULT;
828 
829     __get_user(tv->tv_sec, &target_tv->tv_sec);
830     __get_user(tv->tv_usec, &target_tv->tv_usec);
831 
832     unlock_user_struct(target_tv, target_tv_addr, 0);
833 
834     return 0;
835 }
836 
837 static inline abi_long copy_to_user_timeval(abi_ulong target_tv_addr,
838                                             const struct timeval *tv)
839 {
840     struct target_timeval *target_tv;
841 
842     if (!lock_user_struct(VERIFY_WRITE, target_tv, target_tv_addr, 0))
843         return -TARGET_EFAULT;
844 
845     __put_user(tv->tv_sec, &target_tv->tv_sec);
846     __put_user(tv->tv_usec, &target_tv->tv_usec);
847 
848     unlock_user_struct(target_tv, target_tv_addr, 1);
849 
850     return 0;
851 }
852 
853 static inline abi_long copy_from_user_mq_attr(struct mq_attr *attr,
854                                               abi_ulong target_mq_attr_addr)
855 {
856     struct target_mq_attr *target_mq_attr;
857 
858     if (!lock_user_struct(VERIFY_READ, target_mq_attr,
859                           target_mq_attr_addr, 1))
860         return -TARGET_EFAULT;
861 
862     __get_user(attr->mq_flags, &target_mq_attr->mq_flags);
863     __get_user(attr->mq_maxmsg, &target_mq_attr->mq_maxmsg);
864     __get_user(attr->mq_msgsize, &target_mq_attr->mq_msgsize);
865     __get_user(attr->mq_curmsgs, &target_mq_attr->mq_curmsgs);
866 
867     unlock_user_struct(target_mq_attr, target_mq_attr_addr, 0);
868 
869     return 0;
870 }
871 
872 static inline abi_long copy_to_user_mq_attr(abi_ulong target_mq_attr_addr,
873                                             const struct mq_attr *attr)
874 {
875     struct target_mq_attr *target_mq_attr;
876 
877     if (!lock_user_struct(VERIFY_WRITE, target_mq_attr,
878                           target_mq_attr_addr, 0))
879         return -TARGET_EFAULT;
880 
881     __put_user(attr->mq_flags, &target_mq_attr->mq_flags);
882     __put_user(attr->mq_maxmsg, &target_mq_attr->mq_maxmsg);
883     __put_user(attr->mq_msgsize, &target_mq_attr->mq_msgsize);
884     __put_user(attr->mq_curmsgs, &target_mq_attr->mq_curmsgs);
885 
886     unlock_user_struct(target_mq_attr, target_mq_attr_addr, 1);
887 
888     return 0;
889 }
890 
891 /* do_select() must return target values and target errnos. */
892 static abi_long do_select(int n,
893                           abi_ulong rfd_addr, abi_ulong wfd_addr,
894                           abi_ulong efd_addr, abi_ulong target_tv_addr)
895 {
896     fd_set rfds, wfds, efds;
897     fd_set *rfds_ptr, *wfds_ptr, *efds_ptr;
898     struct timeval tv, *tv_ptr;
899     abi_long ret;
900 
901     if (rfd_addr) {
902         if (copy_from_user_fdset(&rfds, rfd_addr, n))
903             return -TARGET_EFAULT;
904         rfds_ptr = &rfds;
905     } else {
906         rfds_ptr = NULL;
907     }
908     if (wfd_addr) {
909         if (copy_from_user_fdset(&wfds, wfd_addr, n))
910             return -TARGET_EFAULT;
911         wfds_ptr = &wfds;
912     } else {
913         wfds_ptr = NULL;
914     }
915     if (efd_addr) {
916         if (copy_from_user_fdset(&efds, efd_addr, n))
917             return -TARGET_EFAULT;
918         efds_ptr = &efds;
919     } else {
920         efds_ptr = NULL;
921     }
922 
923     if (target_tv_addr) {
924         if (copy_from_user_timeval(&tv, target_tv_addr))
925             return -TARGET_EFAULT;
926         tv_ptr = &tv;
927     } else {
928         tv_ptr = NULL;
929     }
930 
931     ret = get_errno(select(n, rfds_ptr, wfds_ptr, efds_ptr, tv_ptr));
932 
933     if (!is_error(ret)) {
934         if (rfd_addr && copy_to_user_fdset(rfd_addr, &rfds, n))
935             return -TARGET_EFAULT;
936         if (wfd_addr && copy_to_user_fdset(wfd_addr, &wfds, n))
937             return -TARGET_EFAULT;
938         if (efd_addr && copy_to_user_fdset(efd_addr, &efds, n))
939             return -TARGET_EFAULT;
940 
941         if (target_tv_addr && copy_to_user_timeval(target_tv_addr, &tv))
942             return -TARGET_EFAULT;
943     }
944 
945     return ret;
946 }
947 
948 static abi_long do_pipe2(int host_pipe[], int flags)
949 {
950 #ifdef CONFIG_PIPE2
951     return pipe2(host_pipe, flags);
952 #else
953     return -ENOSYS;
954 #endif
955 }
956 
957 static abi_long do_pipe(void *cpu_env, int pipedes, int flags)
958 {
959     int host_pipe[2];
960     abi_long ret;
961     ret = flags ? do_pipe2(host_pipe, flags) : pipe(host_pipe);
962 
963     if (is_error(ret))
964         return get_errno(ret);
965 #if defined(TARGET_MIPS)
966     ((CPUMIPSState*)cpu_env)->active_tc.gpr[3] = host_pipe[1];
967     ret = host_pipe[0];
968 #elif defined(TARGET_SH4)
969     ((CPUSH4State*)cpu_env)->gregs[1] = host_pipe[1];
970     ret = host_pipe[0];
971 #else
972     if (put_user_s32(host_pipe[0], pipedes)
973         || put_user_s32(host_pipe[1], pipedes + sizeof(host_pipe[0])))
974         return -TARGET_EFAULT;
975 #endif
976     return get_errno(ret);
977 }
978 
979 static inline abi_long target_to_host_ip_mreq(struct ip_mreqn *mreqn,
980                                               abi_ulong target_addr,
981                                               socklen_t len)
982 {
983     struct target_ip_mreqn *target_smreqn;
984 
985     target_smreqn = lock_user(VERIFY_READ, target_addr, len, 1);
986     if (!target_smreqn)
987         return -TARGET_EFAULT;
988     mreqn->imr_multiaddr.s_addr = target_smreqn->imr_multiaddr.s_addr;
989     mreqn->imr_address.s_addr = target_smreqn->imr_address.s_addr;
990     if (len == sizeof(struct target_ip_mreqn))
991         mreqn->imr_ifindex = tswapl(target_smreqn->imr_ifindex);
992     unlock_user(target_smreqn, target_addr, 0);
993 
994     return 0;
995 }
996 
997 static inline abi_long target_to_host_sockaddr(struct sockaddr *addr,
998                                                abi_ulong target_addr,
999                                                socklen_t len)
1000 {
1001     const socklen_t unix_maxlen = sizeof (struct sockaddr_un);
1002     sa_family_t sa_family;
1003     struct target_sockaddr *target_saddr;
1004 
1005     target_saddr = lock_user(VERIFY_READ, target_addr, len, 1);
1006     if (!target_saddr)
1007         return -TARGET_EFAULT;
1008 
1009     sa_family = tswap16(target_saddr->sa_family);
1010 
1011     /* Oops. The caller might send a incomplete sun_path; sun_path
1012      * must be terminated by \0 (see the manual page), but
1013      * unfortunately it is quite common to specify sockaddr_un
1014      * length as "strlen(x->sun_path)" while it should be
1015      * "strlen(...) + 1". We'll fix that here if needed.
1016      * Linux kernel has a similar feature.
1017      */
1018 
1019     if (sa_family == AF_UNIX) {
1020         if (len < unix_maxlen && len > 0) {
1021             char *cp = (char*)target_saddr;
1022 
1023             if ( cp[len-1] && !cp[len] )
1024                 len++;
1025         }
1026         if (len > unix_maxlen)
1027             len = unix_maxlen;
1028     }
1029 
1030     memcpy(addr, target_saddr, len);
1031     addr->sa_family = sa_family;
1032     unlock_user(target_saddr, target_addr, 0);
1033 
1034     return 0;
1035 }
1036 
1037 static inline abi_long host_to_target_sockaddr(abi_ulong target_addr,
1038                                                struct sockaddr *addr,
1039                                                socklen_t len)
1040 {
1041     struct target_sockaddr *target_saddr;
1042 
1043     target_saddr = lock_user(VERIFY_WRITE, target_addr, len, 0);
1044     if (!target_saddr)
1045         return -TARGET_EFAULT;
1046     memcpy(target_saddr, addr, len);
1047     target_saddr->sa_family = tswap16(addr->sa_family);
1048     unlock_user(target_saddr, target_addr, len);
1049 
1050     return 0;
1051 }
1052 
1053 /* ??? Should this also swap msgh->name?  */
1054 static inline abi_long target_to_host_cmsg(struct msghdr *msgh,
1055                                            struct target_msghdr *target_msgh)
1056 {
1057     struct cmsghdr *cmsg = CMSG_FIRSTHDR(msgh);
1058     abi_long msg_controllen;
1059     abi_ulong target_cmsg_addr;
1060     struct target_cmsghdr *target_cmsg;
1061     socklen_t space = 0;
1062 
1063     msg_controllen = tswapl(target_msgh->msg_controllen);
1064     if (msg_controllen < sizeof (struct target_cmsghdr))
1065         goto the_end;
1066     target_cmsg_addr = tswapl(target_msgh->msg_control);
1067     target_cmsg = lock_user(VERIFY_READ, target_cmsg_addr, msg_controllen, 1);
1068     if (!target_cmsg)
1069         return -TARGET_EFAULT;
1070 
1071     while (cmsg && target_cmsg) {
1072         void *data = CMSG_DATA(cmsg);
1073         void *target_data = TARGET_CMSG_DATA(target_cmsg);
1074 
1075         int len = tswapl(target_cmsg->cmsg_len)
1076                   - TARGET_CMSG_ALIGN(sizeof (struct target_cmsghdr));
1077 
1078         space += CMSG_SPACE(len);
1079         if (space > msgh->msg_controllen) {
1080             space -= CMSG_SPACE(len);
1081             gemu_log("Host cmsg overflow\n");
1082             break;
1083         }
1084 
1085         cmsg->cmsg_level = tswap32(target_cmsg->cmsg_level);
1086         cmsg->cmsg_type = tswap32(target_cmsg->cmsg_type);
1087         cmsg->cmsg_len = CMSG_LEN(len);
1088 
1089         if (cmsg->cmsg_level != TARGET_SOL_SOCKET || cmsg->cmsg_type != SCM_RIGHTS) {
1090             gemu_log("Unsupported ancillary data: %d/%d\n", cmsg->cmsg_level, cmsg->cmsg_type);
1091             memcpy(data, target_data, len);
1092         } else {
1093             int *fd = (int *)data;
1094             int *target_fd = (int *)target_data;
1095             int i, numfds = len / sizeof(int);
1096 
1097             for (i = 0; i < numfds; i++)
1098                 fd[i] = tswap32(target_fd[i]);
1099         }
1100 
1101         cmsg = CMSG_NXTHDR(msgh, cmsg);
1102         target_cmsg = TARGET_CMSG_NXTHDR(target_msgh, target_cmsg);
1103     }
1104     unlock_user(target_cmsg, target_cmsg_addr, 0);
1105  the_end:
1106     msgh->msg_controllen = space;
1107     return 0;
1108 }
1109 
1110 /* ??? Should this also swap msgh->name?  */
1111 static inline abi_long host_to_target_cmsg(struct target_msghdr *target_msgh,
1112                                            struct msghdr *msgh)
1113 {
1114     struct cmsghdr *cmsg = CMSG_FIRSTHDR(msgh);
1115     abi_long msg_controllen;
1116     abi_ulong target_cmsg_addr;
1117     struct target_cmsghdr *target_cmsg;
1118     socklen_t space = 0;
1119 
1120     msg_controllen = tswapl(target_msgh->msg_controllen);
1121     if (msg_controllen < sizeof (struct target_cmsghdr))
1122         goto the_end;
1123     target_cmsg_addr = tswapl(target_msgh->msg_control);
1124     target_cmsg = lock_user(VERIFY_WRITE, target_cmsg_addr, msg_controllen, 0);
1125     if (!target_cmsg)
1126         return -TARGET_EFAULT;
1127 
1128     while (cmsg && target_cmsg) {
1129         void *data = CMSG_DATA(cmsg);
1130         void *target_data = TARGET_CMSG_DATA(target_cmsg);
1131 
1132         int len = cmsg->cmsg_len - CMSG_ALIGN(sizeof (struct cmsghdr));
1133 
1134         space += TARGET_CMSG_SPACE(len);
1135         if (space > msg_controllen) {
1136             space -= TARGET_CMSG_SPACE(len);
1137             gemu_log("Target cmsg overflow\n");
1138             break;
1139         }
1140 
1141         target_cmsg->cmsg_level = tswap32(cmsg->cmsg_level);
1142         target_cmsg->cmsg_type = tswap32(cmsg->cmsg_type);
1143         target_cmsg->cmsg_len = tswapl(TARGET_CMSG_LEN(len));
1144 
1145         if (cmsg->cmsg_level != TARGET_SOL_SOCKET || cmsg->cmsg_type != SCM_RIGHTS) {
1146             gemu_log("Unsupported ancillary data: %d/%d\n", cmsg->cmsg_level, cmsg->cmsg_type);
1147             memcpy(target_data, data, len);
1148         } else {
1149             int *fd = (int *)data;
1150             int *target_fd = (int *)target_data;
1151             int i, numfds = len / sizeof(int);
1152 
1153             for (i = 0; i < numfds; i++)
1154                 target_fd[i] = tswap32(fd[i]);
1155         }
1156 
1157         cmsg = CMSG_NXTHDR(msgh, cmsg);
1158         target_cmsg = TARGET_CMSG_NXTHDR(target_msgh, target_cmsg);
1159     }
1160     unlock_user(target_cmsg, target_cmsg_addr, space);
1161  the_end:
1162     target_msgh->msg_controllen = tswapl(space);
1163     return 0;
1164 }
1165 
1166 /* do_setsockopt() Must return target values and target errnos. */
1167 static abi_long do_setsockopt(int sockfd, int level, int optname,
1168                               abi_ulong optval_addr, socklen_t optlen)
1169 {
1170     abi_long ret;
1171     int val;
1172     struct ip_mreqn *ip_mreq;
1173     struct ip_mreq_source *ip_mreq_source;
1174 
1175     switch(level) {
1176     case SOL_TCP:
1177         /* TCP options all take an 'int' value.  */
1178         if (optlen < sizeof(uint32_t))
1179             return -TARGET_EINVAL;
1180 
1181         if (get_user_u32(val, optval_addr))
1182             return -TARGET_EFAULT;
1183         ret = get_errno(setsockopt(sockfd, level, optname, &val, sizeof(val)));
1184         break;
1185     case SOL_IP:
1186         switch(optname) {
1187         case IP_TOS:
1188         case IP_TTL:
1189         case IP_HDRINCL:
1190         case IP_ROUTER_ALERT:
1191         case IP_RECVOPTS:
1192         case IP_RETOPTS:
1193         case IP_PKTINFO:
1194         case IP_MTU_DISCOVER:
1195         case IP_RECVERR:
1196         case IP_RECVTOS:
1197 #ifdef IP_FREEBIND
1198         case IP_FREEBIND:
1199 #endif
1200         case IP_MULTICAST_TTL:
1201         case IP_MULTICAST_LOOP:
1202             val = 0;
1203             if (optlen >= sizeof(uint32_t)) {
1204                 if (get_user_u32(val, optval_addr))
1205                     return -TARGET_EFAULT;
1206             } else if (optlen >= 1) {
1207                 if (get_user_u8(val, optval_addr))
1208                     return -TARGET_EFAULT;
1209             }
1210             ret = get_errno(setsockopt(sockfd, level, optname, &val, sizeof(val)));
1211             break;
1212         case IP_ADD_MEMBERSHIP:
1213         case IP_DROP_MEMBERSHIP:
1214             if (optlen < sizeof (struct target_ip_mreq) ||
1215                 optlen > sizeof (struct target_ip_mreqn))
1216                 return -TARGET_EINVAL;
1217 
1218             ip_mreq = (struct ip_mreqn *) alloca(optlen);
1219             target_to_host_ip_mreq(ip_mreq, optval_addr, optlen);
1220             ret = get_errno(setsockopt(sockfd, level, optname, ip_mreq, optlen));
1221             break;
1222 
1223         case IP_BLOCK_SOURCE:
1224         case IP_UNBLOCK_SOURCE:
1225         case IP_ADD_SOURCE_MEMBERSHIP:
1226         case IP_DROP_SOURCE_MEMBERSHIP:
1227             if (optlen != sizeof (struct target_ip_mreq_source))
1228                 return -TARGET_EINVAL;
1229 
1230             ip_mreq_source = lock_user(VERIFY_READ, optval_addr, optlen, 1);
1231             ret = get_errno(setsockopt(sockfd, level, optname, ip_mreq_source, optlen));
1232             unlock_user (ip_mreq_source, optval_addr, 0);
1233             break;
1234 
1235         default:
1236             goto unimplemented;
1237         }
1238         break;
1239     case TARGET_SOL_SOCKET:
1240         switch (optname) {
1241             /* Options with 'int' argument.  */
1242         case TARGET_SO_DEBUG:
1243 		optname = SO_DEBUG;
1244 		break;
1245         case TARGET_SO_REUSEADDR:
1246 		optname = SO_REUSEADDR;
1247 		break;
1248         case TARGET_SO_TYPE:
1249 		optname = SO_TYPE;
1250 		break;
1251         case TARGET_SO_ERROR:
1252 		optname = SO_ERROR;
1253 		break;
1254         case TARGET_SO_DONTROUTE:
1255 		optname = SO_DONTROUTE;
1256 		break;
1257         case TARGET_SO_BROADCAST:
1258 		optname = SO_BROADCAST;
1259 		break;
1260         case TARGET_SO_SNDBUF:
1261 		optname = SO_SNDBUF;
1262 		break;
1263         case TARGET_SO_RCVBUF:
1264 		optname = SO_RCVBUF;
1265 		break;
1266         case TARGET_SO_KEEPALIVE:
1267 		optname = SO_KEEPALIVE;
1268 		break;
1269         case TARGET_SO_OOBINLINE:
1270 		optname = SO_OOBINLINE;
1271 		break;
1272         case TARGET_SO_NO_CHECK:
1273 		optname = SO_NO_CHECK;
1274 		break;
1275         case TARGET_SO_PRIORITY:
1276 		optname = SO_PRIORITY;
1277 		break;
1278 #ifdef SO_BSDCOMPAT
1279         case TARGET_SO_BSDCOMPAT:
1280 		optname = SO_BSDCOMPAT;
1281 		break;
1282 #endif
1283         case TARGET_SO_PASSCRED:
1284 		optname = SO_PASSCRED;
1285 		break;
1286         case TARGET_SO_TIMESTAMP:
1287 		optname = SO_TIMESTAMP;
1288 		break;
1289         case TARGET_SO_RCVLOWAT:
1290 		optname = SO_RCVLOWAT;
1291 		break;
1292         case TARGET_SO_RCVTIMEO:
1293 		optname = SO_RCVTIMEO;
1294 		break;
1295         case TARGET_SO_SNDTIMEO:
1296 		optname = SO_SNDTIMEO;
1297 		break;
1298             break;
1299         default:
1300             goto unimplemented;
1301         }
1302 	if (optlen < sizeof(uint32_t))
1303             return -TARGET_EINVAL;
1304 
1305 	if (get_user_u32(val, optval_addr))
1306             return -TARGET_EFAULT;
1307 	ret = get_errno(setsockopt(sockfd, SOL_SOCKET, optname, &val, sizeof(val)));
1308         break;
1309     default:
1310     unimplemented:
1311         gemu_log("Unsupported setsockopt level=%d optname=%d \n", level, optname);
1312         ret = -TARGET_ENOPROTOOPT;
1313     }
1314     return ret;
1315 }
1316 
1317 /* do_getsockopt() Must return target values and target errnos. */
1318 static abi_long do_getsockopt(int sockfd, int level, int optname,
1319                               abi_ulong optval_addr, abi_ulong optlen)
1320 {
1321     abi_long ret;
1322     int len, val;
1323     socklen_t lv;
1324 
1325     switch(level) {
1326     case TARGET_SOL_SOCKET:
1327     	level = SOL_SOCKET;
1328 	switch (optname) {
1329 	case TARGET_SO_LINGER:
1330 	case TARGET_SO_RCVTIMEO:
1331 	case TARGET_SO_SNDTIMEO:
1332 	case TARGET_SO_PEERCRED:
1333 	case TARGET_SO_PEERNAME:
1334 	    /* These don't just return a single integer */
1335 	    goto unimplemented;
1336         default:
1337             goto int_case;
1338         }
1339         break;
1340     case SOL_TCP:
1341         /* TCP options all take an 'int' value.  */
1342     int_case:
1343         if (get_user_u32(len, optlen))
1344             return -TARGET_EFAULT;
1345         if (len < 0)
1346             return -TARGET_EINVAL;
1347         lv = sizeof(int);
1348         ret = get_errno(getsockopt(sockfd, level, optname, &val, &lv));
1349         if (ret < 0)
1350             return ret;
1351         if (len > lv)
1352             len = lv;
1353         if (len == 4) {
1354             if (put_user_u32(val, optval_addr))
1355                 return -TARGET_EFAULT;
1356         } else {
1357             if (put_user_u8(val, optval_addr))
1358                 return -TARGET_EFAULT;
1359 	}
1360         if (put_user_u32(len, optlen))
1361             return -TARGET_EFAULT;
1362         break;
1363     case SOL_IP:
1364         switch(optname) {
1365         case IP_TOS:
1366         case IP_TTL:
1367         case IP_HDRINCL:
1368         case IP_ROUTER_ALERT:
1369         case IP_RECVOPTS:
1370         case IP_RETOPTS:
1371         case IP_PKTINFO:
1372         case IP_MTU_DISCOVER:
1373         case IP_RECVERR:
1374         case IP_RECVTOS:
1375 #ifdef IP_FREEBIND
1376         case IP_FREEBIND:
1377 #endif
1378         case IP_MULTICAST_TTL:
1379         case IP_MULTICAST_LOOP:
1380             if (get_user_u32(len, optlen))
1381                 return -TARGET_EFAULT;
1382             if (len < 0)
1383                 return -TARGET_EINVAL;
1384             lv = sizeof(int);
1385             ret = get_errno(getsockopt(sockfd, level, optname, &val, &lv));
1386             if (ret < 0)
1387                 return ret;
1388             if (len < sizeof(int) && len > 0 && val >= 0 && val < 255) {
1389                 len = 1;
1390                 if (put_user_u32(len, optlen)
1391                     || put_user_u8(val, optval_addr))
1392                     return -TARGET_EFAULT;
1393             } else {
1394                 if (len > sizeof(int))
1395                     len = sizeof(int);
1396                 if (put_user_u32(len, optlen)
1397                     || put_user_u32(val, optval_addr))
1398                     return -TARGET_EFAULT;
1399             }
1400             break;
1401         default:
1402             ret = -TARGET_ENOPROTOOPT;
1403             break;
1404         }
1405         break;
1406     default:
1407     unimplemented:
1408         gemu_log("getsockopt level=%d optname=%d not yet supported\n",
1409                  level, optname);
1410         ret = -TARGET_EOPNOTSUPP;
1411         break;
1412     }
1413     return ret;
1414 }
1415 
1416 /* FIXME
1417  * lock_iovec()/unlock_iovec() have a return code of 0 for success where
1418  * other lock functions have a return code of 0 for failure.
1419  */
1420 static abi_long lock_iovec(int type, struct iovec *vec, abi_ulong target_addr,
1421                            int count, int copy)
1422 {
1423     struct target_iovec *target_vec;
1424     abi_ulong base;
1425     int i;
1426 
1427     target_vec = lock_user(VERIFY_READ, target_addr, count * sizeof(struct target_iovec), 1);
1428     if (!target_vec)
1429         return -TARGET_EFAULT;
1430     for(i = 0;i < count; i++) {
1431         base = tswapl(target_vec[i].iov_base);
1432         vec[i].iov_len = tswapl(target_vec[i].iov_len);
1433         if (vec[i].iov_len != 0) {
1434             vec[i].iov_base = lock_user(type, base, vec[i].iov_len, copy);
1435             /* Don't check lock_user return value. We must call writev even
1436                if a element has invalid base address. */
1437         } else {
1438             /* zero length pointer is ignored */
1439             vec[i].iov_base = NULL;
1440         }
1441     }
1442     unlock_user (target_vec, target_addr, 0);
1443     return 0;
1444 }
1445 
1446 static abi_long unlock_iovec(struct iovec *vec, abi_ulong target_addr,
1447                              int count, int copy)
1448 {
1449     struct target_iovec *target_vec;
1450     abi_ulong base;
1451     int i;
1452 
1453     target_vec = lock_user(VERIFY_READ, target_addr, count * sizeof(struct target_iovec), 1);
1454     if (!target_vec)
1455         return -TARGET_EFAULT;
1456     for(i = 0;i < count; i++) {
1457         if (target_vec[i].iov_base) {
1458             base = tswapl(target_vec[i].iov_base);
1459             unlock_user(vec[i].iov_base, base, copy ? vec[i].iov_len : 0);
1460         }
1461     }
1462     unlock_user (target_vec, target_addr, 0);
1463 
1464     return 0;
1465 }
1466 
1467 /* do_socket() Must return target values and target errnos. */
1468 static abi_long do_socket(int domain, int type, int protocol)
1469 {
1470 #if defined(TARGET_MIPS)
1471     switch(type) {
1472     case TARGET_SOCK_DGRAM:
1473         type = SOCK_DGRAM;
1474         break;
1475     case TARGET_SOCK_STREAM:
1476         type = SOCK_STREAM;
1477         break;
1478     case TARGET_SOCK_RAW:
1479         type = SOCK_RAW;
1480         break;
1481     case TARGET_SOCK_RDM:
1482         type = SOCK_RDM;
1483         break;
1484     case TARGET_SOCK_SEQPACKET:
1485         type = SOCK_SEQPACKET;
1486         break;
1487     case TARGET_SOCK_PACKET:
1488         type = SOCK_PACKET;
1489         break;
1490     }
1491 #endif
1492     if (domain == PF_NETLINK)
1493         return -EAFNOSUPPORT; /* do not NETLINK socket connections possible */
1494     return get_errno(socket(domain, type, protocol));
1495 }
1496 
1497 /* do_bind() Must return target values and target errnos. */
1498 static abi_long do_bind(int sockfd, abi_ulong target_addr,
1499                         socklen_t addrlen)
1500 {
1501     void *addr;
1502 
1503     if (addrlen < 0)
1504         return -TARGET_EINVAL;
1505 
1506     addr = alloca(addrlen+1);
1507 
1508     target_to_host_sockaddr(addr, target_addr, addrlen);
1509     return get_errno(bind(sockfd, addr, addrlen));
1510 }
1511 
1512 /* do_connect() Must return target values and target errnos. */
1513 static abi_long do_connect(int sockfd, abi_ulong target_addr,
1514                            socklen_t addrlen)
1515 {
1516     void *addr;
1517 
1518     if (addrlen < 0)
1519         return -TARGET_EINVAL;
1520 
1521     addr = alloca(addrlen);
1522 
1523     target_to_host_sockaddr(addr, target_addr, addrlen);
1524     return get_errno(connect(sockfd, addr, addrlen));
1525 }
1526 
1527 /* do_sendrecvmsg() Must return target values and target errnos. */
1528 static abi_long do_sendrecvmsg(int fd, abi_ulong target_msg,
1529                                int flags, int send)
1530 {
1531     abi_long ret, len;
1532     struct target_msghdr *msgp;
1533     struct msghdr msg;
1534     int count;
1535     struct iovec *vec;
1536     abi_ulong target_vec;
1537 
1538     /* FIXME */
1539     if (!lock_user_struct(send ? VERIFY_READ : VERIFY_WRITE,
1540                           msgp,
1541                           target_msg,
1542                           send ? 1 : 0))
1543         return -TARGET_EFAULT;
1544     if (msgp->msg_name) {
1545         msg.msg_namelen = tswap32(msgp->msg_namelen);
1546         msg.msg_name = alloca(msg.msg_namelen);
1547         target_to_host_sockaddr(msg.msg_name, tswapl(msgp->msg_name),
1548                                 msg.msg_namelen);
1549     } else {
1550         msg.msg_name = NULL;
1551         msg.msg_namelen = 0;
1552     }
1553     msg.msg_controllen = 2 * tswapl(msgp->msg_controllen);
1554     msg.msg_control = alloca(msg.msg_controllen);
1555     msg.msg_flags = tswap32(msgp->msg_flags);
1556 
1557     count = tswapl(msgp->msg_iovlen);
1558     vec = alloca(count * sizeof(struct iovec));
1559     target_vec = tswapl(msgp->msg_iov);
1560     lock_iovec(send ? VERIFY_READ : VERIFY_WRITE, vec, target_vec, count, send);
1561     msg.msg_iovlen = count;
1562     msg.msg_iov = vec;
1563 
1564     if (send) {
1565         ret = target_to_host_cmsg(&msg, msgp);
1566         if (ret == 0)
1567             ret = get_errno(sendmsg(fd, &msg, flags));
1568     } else {
1569         ret = get_errno(recvmsg(fd, &msg, flags));
1570         if (!is_error(ret)) {
1571             len = ret;
1572             ret = host_to_target_cmsg(msgp, &msg);
1573             if (!is_error(ret))
1574                 ret = len;
1575         }
1576     }
1577     unlock_iovec(vec, target_vec, count, !send);
1578     unlock_user_struct(msgp, target_msg, send ? 0 : 1);
1579     return ret;
1580 }
1581 
1582 /* do_accept() Must return target values and target errnos. */
1583 static abi_long do_accept(int fd, abi_ulong target_addr,
1584                           abi_ulong target_addrlen_addr)
1585 {
1586     socklen_t addrlen;
1587     void *addr;
1588     abi_long ret;
1589 
1590     if (get_user_u32(addrlen, target_addrlen_addr))
1591         return -TARGET_EFAULT;
1592 
1593     if (addrlen < 0)
1594         return -TARGET_EINVAL;
1595 
1596     addr = alloca(addrlen);
1597 
1598     ret = get_errno(accept(fd, addr, &addrlen));
1599     if (!is_error(ret)) {
1600         host_to_target_sockaddr(target_addr, addr, addrlen);
1601         if (put_user_u32(addrlen, target_addrlen_addr))
1602             ret = -TARGET_EFAULT;
1603     }
1604     return ret;
1605 }
1606 
1607 /* do_getpeername() Must return target values and target errnos. */
1608 static abi_long do_getpeername(int fd, abi_ulong target_addr,
1609                                abi_ulong target_addrlen_addr)
1610 {
1611     socklen_t addrlen;
1612     void *addr;
1613     abi_long ret;
1614 
1615     if (get_user_u32(addrlen, target_addrlen_addr))
1616         return -TARGET_EFAULT;
1617 
1618     if (addrlen < 0)
1619         return -TARGET_EINVAL;
1620 
1621     addr = alloca(addrlen);
1622 
1623     ret = get_errno(getpeername(fd, addr, &addrlen));
1624     if (!is_error(ret)) {
1625         host_to_target_sockaddr(target_addr, addr, addrlen);
1626         if (put_user_u32(addrlen, target_addrlen_addr))
1627             ret = -TARGET_EFAULT;
1628     }
1629     return ret;
1630 }
1631 
1632 /* do_getsockname() Must return target values and target errnos. */
1633 static abi_long do_getsockname(int fd, abi_ulong target_addr,
1634                                abi_ulong target_addrlen_addr)
1635 {
1636     socklen_t addrlen;
1637     void *addr;
1638     abi_long ret;
1639 
1640     if (target_addr == 0)
1641        return get_errno(accept(fd, NULL, NULL));
1642 
1643     if (get_user_u32(addrlen, target_addrlen_addr))
1644         return -TARGET_EFAULT;
1645 
1646     if (addrlen < 0)
1647         return -TARGET_EINVAL;
1648 
1649     addr = alloca(addrlen);
1650 
1651     ret = get_errno(getsockname(fd, addr, &addrlen));
1652     if (!is_error(ret)) {
1653         host_to_target_sockaddr(target_addr, addr, addrlen);
1654         if (put_user_u32(addrlen, target_addrlen_addr))
1655             ret = -TARGET_EFAULT;
1656     }
1657     return ret;
1658 }
1659 
1660 /* do_socketpair() Must return target values and target errnos. */
1661 static abi_long do_socketpair(int domain, int type, int protocol,
1662                               abi_ulong target_tab_addr)
1663 {
1664     int tab[2];
1665     abi_long ret;
1666 
1667     ret = get_errno(socketpair(domain, type, protocol, tab));
1668     if (!is_error(ret)) {
1669         if (put_user_s32(tab[0], target_tab_addr)
1670             || put_user_s32(tab[1], target_tab_addr + sizeof(tab[0])))
1671             ret = -TARGET_EFAULT;
1672     }
1673     return ret;
1674 }
1675 
1676 /* do_sendto() Must return target values and target errnos. */
1677 static abi_long do_sendto(int fd, abi_ulong msg, size_t len, int flags,
1678                           abi_ulong target_addr, socklen_t addrlen)
1679 {
1680     void *addr;
1681     void *host_msg;
1682     abi_long ret;
1683 
1684     if (addrlen < 0)
1685         return -TARGET_EINVAL;
1686 
1687     host_msg = lock_user(VERIFY_READ, msg, len, 1);
1688     if (!host_msg)
1689         return -TARGET_EFAULT;
1690     if (target_addr) {
1691         addr = alloca(addrlen);
1692         target_to_host_sockaddr(addr, target_addr, addrlen);
1693         ret = get_errno(sendto(fd, host_msg, len, flags, addr, addrlen));
1694     } else {
1695         ret = get_errno(send(fd, host_msg, len, flags));
1696     }
1697     unlock_user(host_msg, msg, 0);
1698     return ret;
1699 }
1700 
1701 /* do_recvfrom() Must return target values and target errnos. */
1702 static abi_long do_recvfrom(int fd, abi_ulong msg, size_t len, int flags,
1703                             abi_ulong target_addr,
1704                             abi_ulong target_addrlen)
1705 {
1706     socklen_t addrlen;
1707     void *addr;
1708     void *host_msg;
1709     abi_long ret;
1710 
1711     host_msg = lock_user(VERIFY_WRITE, msg, len, 0);
1712     if (!host_msg)
1713         return -TARGET_EFAULT;
1714     if (target_addr) {
1715         if (get_user_u32(addrlen, target_addrlen)) {
1716             ret = -TARGET_EFAULT;
1717             goto fail;
1718         }
1719         if (addrlen < 0) {
1720             ret = -TARGET_EINVAL;
1721             goto fail;
1722         }
1723         addr = alloca(addrlen);
1724         ret = get_errno(recvfrom(fd, host_msg, len, flags, addr, &addrlen));
1725     } else {
1726         addr = NULL; /* To keep compiler quiet.  */
1727         ret = get_errno(recv(fd, host_msg, len, flags));
1728     }
1729     if (!is_error(ret)) {
1730         if (target_addr) {
1731             host_to_target_sockaddr(target_addr, addr, addrlen);
1732             if (put_user_u32(addrlen, target_addrlen)) {
1733                 ret = -TARGET_EFAULT;
1734                 goto fail;
1735             }
1736         }
1737         unlock_user(host_msg, msg, len);
1738     } else {
1739 fail:
1740         unlock_user(host_msg, msg, 0);
1741     }
1742     return ret;
1743 }
1744 
1745 #ifdef TARGET_NR_socketcall
1746 /* do_socketcall() Must return target values and target errnos. */
1747 static abi_long do_socketcall(int num, abi_ulong vptr)
1748 {
1749     abi_long ret;
1750     const int n = sizeof(abi_ulong);
1751 
1752     switch(num) {
1753     case SOCKOP_socket:
1754 	{
1755             int domain, type, protocol;
1756 
1757             if (get_user_s32(domain, vptr)
1758                 || get_user_s32(type, vptr + n)
1759                 || get_user_s32(protocol, vptr + 2 * n))
1760                 return -TARGET_EFAULT;
1761 
1762             ret = do_socket(domain, type, protocol);
1763 	}
1764         break;
1765     case SOCKOP_bind:
1766 	{
1767             int sockfd;
1768             abi_ulong target_addr;
1769             socklen_t addrlen;
1770 
1771             if (get_user_s32(sockfd, vptr)
1772                 || get_user_ual(target_addr, vptr + n)
1773                 || get_user_u32(addrlen, vptr + 2 * n))
1774                 return -TARGET_EFAULT;
1775 
1776             ret = do_bind(sockfd, target_addr, addrlen);
1777         }
1778         break;
1779     case SOCKOP_connect:
1780         {
1781             int sockfd;
1782             abi_ulong target_addr;
1783             socklen_t addrlen;
1784 
1785             if (get_user_s32(sockfd, vptr)
1786                 || get_user_ual(target_addr, vptr + n)
1787                 || get_user_u32(addrlen, vptr + 2 * n))
1788                 return -TARGET_EFAULT;
1789 
1790             ret = do_connect(sockfd, target_addr, addrlen);
1791         }
1792         break;
1793     case SOCKOP_listen:
1794         {
1795             int sockfd, backlog;
1796 
1797             if (get_user_s32(sockfd, vptr)
1798                 || get_user_s32(backlog, vptr + n))
1799                 return -TARGET_EFAULT;
1800 
1801             ret = get_errno(listen(sockfd, backlog));
1802         }
1803         break;
1804     case SOCKOP_accept:
1805         {
1806             int sockfd;
1807             abi_ulong target_addr, target_addrlen;
1808 
1809             if (get_user_s32(sockfd, vptr)
1810                 || get_user_ual(target_addr, vptr + n)
1811                 || get_user_u32(target_addrlen, vptr + 2 * n))
1812                 return -TARGET_EFAULT;
1813 
1814             ret = do_accept(sockfd, target_addr, target_addrlen);
1815         }
1816         break;
1817     case SOCKOP_getsockname:
1818         {
1819             int sockfd;
1820             abi_ulong target_addr, target_addrlen;
1821 
1822             if (get_user_s32(sockfd, vptr)
1823                 || get_user_ual(target_addr, vptr + n)
1824                 || get_user_u32(target_addrlen, vptr + 2 * n))
1825                 return -TARGET_EFAULT;
1826 
1827             ret = do_getsockname(sockfd, target_addr, target_addrlen);
1828         }
1829         break;
1830     case SOCKOP_getpeername:
1831         {
1832             int sockfd;
1833             abi_ulong target_addr, target_addrlen;
1834 
1835             if (get_user_s32(sockfd, vptr)
1836                 || get_user_ual(target_addr, vptr + n)
1837                 || get_user_u32(target_addrlen, vptr + 2 * n))
1838                 return -TARGET_EFAULT;
1839 
1840             ret = do_getpeername(sockfd, target_addr, target_addrlen);
1841         }
1842         break;
1843     case SOCKOP_socketpair:
1844         {
1845             int domain, type, protocol;
1846             abi_ulong tab;
1847 
1848             if (get_user_s32(domain, vptr)
1849                 || get_user_s32(type, vptr + n)
1850                 || get_user_s32(protocol, vptr + 2 * n)
1851                 || get_user_ual(tab, vptr + 3 * n))
1852                 return -TARGET_EFAULT;
1853 
1854             ret = do_socketpair(domain, type, protocol, tab);
1855         }
1856         break;
1857     case SOCKOP_send:
1858         {
1859             int sockfd;
1860             abi_ulong msg;
1861             size_t len;
1862             int flags;
1863 
1864             if (get_user_s32(sockfd, vptr)
1865                 || get_user_ual(msg, vptr + n)
1866                 || get_user_ual(len, vptr + 2 * n)
1867                 || get_user_s32(flags, vptr + 3 * n))
1868                 return -TARGET_EFAULT;
1869 
1870             ret = do_sendto(sockfd, msg, len, flags, 0, 0);
1871         }
1872         break;
1873     case SOCKOP_recv:
1874         {
1875             int sockfd;
1876             abi_ulong msg;
1877             size_t len;
1878             int flags;
1879 
1880             if (get_user_s32(sockfd, vptr)
1881                 || get_user_ual(msg, vptr + n)
1882                 || get_user_ual(len, vptr + 2 * n)
1883                 || get_user_s32(flags, vptr + 3 * n))
1884                 return -TARGET_EFAULT;
1885 
1886             ret = do_recvfrom(sockfd, msg, len, flags, 0, 0);
1887         }
1888         break;
1889     case SOCKOP_sendto:
1890         {
1891             int sockfd;
1892             abi_ulong msg;
1893             size_t len;
1894             int flags;
1895             abi_ulong addr;
1896             socklen_t addrlen;
1897 
1898             if (get_user_s32(sockfd, vptr)
1899                 || get_user_ual(msg, vptr + n)
1900                 || get_user_ual(len, vptr + 2 * n)
1901                 || get_user_s32(flags, vptr + 3 * n)
1902                 || get_user_ual(addr, vptr + 4 * n)
1903                 || get_user_u32(addrlen, vptr + 5 * n))
1904                 return -TARGET_EFAULT;
1905 
1906             ret = do_sendto(sockfd, msg, len, flags, addr, addrlen);
1907         }
1908         break;
1909     case SOCKOP_recvfrom:
1910         {
1911             int sockfd;
1912             abi_ulong msg;
1913             size_t len;
1914             int flags;
1915             abi_ulong addr;
1916             socklen_t addrlen;
1917 
1918             if (get_user_s32(sockfd, vptr)
1919                 || get_user_ual(msg, vptr + n)
1920                 || get_user_ual(len, vptr + 2 * n)
1921                 || get_user_s32(flags, vptr + 3 * n)
1922                 || get_user_ual(addr, vptr + 4 * n)
1923                 || get_user_u32(addrlen, vptr + 5 * n))
1924                 return -TARGET_EFAULT;
1925 
1926             ret = do_recvfrom(sockfd, msg, len, flags, addr, addrlen);
1927         }
1928         break;
1929     case SOCKOP_shutdown:
1930         {
1931             int sockfd, how;
1932 
1933             if (get_user_s32(sockfd, vptr)
1934                 || get_user_s32(how, vptr + n))
1935                 return -TARGET_EFAULT;
1936 
1937             ret = get_errno(shutdown(sockfd, how));
1938         }
1939         break;
1940     case SOCKOP_sendmsg:
1941     case SOCKOP_recvmsg:
1942         {
1943             int fd;
1944             abi_ulong target_msg;
1945             int flags;
1946 
1947             if (get_user_s32(fd, vptr)
1948                 || get_user_ual(target_msg, vptr + n)
1949                 || get_user_s32(flags, vptr + 2 * n))
1950                 return -TARGET_EFAULT;
1951 
1952             ret = do_sendrecvmsg(fd, target_msg, flags,
1953                                  (num == SOCKOP_sendmsg));
1954         }
1955         break;
1956     case SOCKOP_setsockopt:
1957         {
1958             int sockfd;
1959             int level;
1960             int optname;
1961             abi_ulong optval;
1962             socklen_t optlen;
1963 
1964             if (get_user_s32(sockfd, vptr)
1965                 || get_user_s32(level, vptr + n)
1966                 || get_user_s32(optname, vptr + 2 * n)
1967                 || get_user_ual(optval, vptr + 3 * n)
1968                 || get_user_u32(optlen, vptr + 4 * n))
1969                 return -TARGET_EFAULT;
1970 
1971             ret = do_setsockopt(sockfd, level, optname, optval, optlen);
1972         }
1973         break;
1974     case SOCKOP_getsockopt:
1975         {
1976             int sockfd;
1977             int level;
1978             int optname;
1979             abi_ulong optval;
1980             socklen_t optlen;
1981 
1982             if (get_user_s32(sockfd, vptr)
1983                 || get_user_s32(level, vptr + n)
1984                 || get_user_s32(optname, vptr + 2 * n)
1985                 || get_user_ual(optval, vptr + 3 * n)
1986                 || get_user_u32(optlen, vptr + 4 * n))
1987                 return -TARGET_EFAULT;
1988 
1989             ret = do_getsockopt(sockfd, level, optname, optval, optlen);
1990         }
1991         break;
1992     default:
1993         gemu_log("Unsupported socketcall: %d\n", num);
1994         ret = -TARGET_ENOSYS;
1995         break;
1996     }
1997     return ret;
1998 }
1999 #endif
2000 
2001 #define N_SHM_REGIONS	32
2002 
2003 static struct shm_region {
2004     abi_ulong	start;
2005     abi_ulong	size;
2006 } shm_regions[N_SHM_REGIONS];
2007 
2008 struct target_ipc_perm
2009 {
2010     abi_long __key;
2011     abi_ulong uid;
2012     abi_ulong gid;
2013     abi_ulong cuid;
2014     abi_ulong cgid;
2015     unsigned short int mode;
2016     unsigned short int __pad1;
2017     unsigned short int __seq;
2018     unsigned short int __pad2;
2019     abi_ulong __unused1;
2020     abi_ulong __unused2;
2021 };
2022 
2023 struct target_semid_ds
2024 {
2025   struct target_ipc_perm sem_perm;
2026   abi_ulong sem_otime;
2027   abi_ulong __unused1;
2028   abi_ulong sem_ctime;
2029   abi_ulong __unused2;
2030   abi_ulong sem_nsems;
2031   abi_ulong __unused3;
2032   abi_ulong __unused4;
2033 };
2034 
2035 static inline abi_long target_to_host_ipc_perm(struct ipc_perm *host_ip,
2036                                                abi_ulong target_addr)
2037 {
2038     struct target_ipc_perm *target_ip;
2039     struct target_semid_ds *target_sd;
2040 
2041     if (!lock_user_struct(VERIFY_READ, target_sd, target_addr, 1))
2042         return -TARGET_EFAULT;
2043     target_ip=&(target_sd->sem_perm);
2044     host_ip->__key = tswapl(target_ip->__key);
2045     host_ip->uid = tswapl(target_ip->uid);
2046     host_ip->gid = tswapl(target_ip->gid);
2047     host_ip->cuid = tswapl(target_ip->cuid);
2048     host_ip->cgid = tswapl(target_ip->cgid);
2049     host_ip->mode = tswapl(target_ip->mode);
2050     unlock_user_struct(target_sd, target_addr, 0);
2051     return 0;
2052 }
2053 
2054 static inline abi_long host_to_target_ipc_perm(abi_ulong target_addr,
2055                                                struct ipc_perm *host_ip)
2056 {
2057     struct target_ipc_perm *target_ip;
2058     struct target_semid_ds *target_sd;
2059 
2060     if (!lock_user_struct(VERIFY_WRITE, target_sd, target_addr, 0))
2061         return -TARGET_EFAULT;
2062     target_ip = &(target_sd->sem_perm);
2063     target_ip->__key = tswapl(host_ip->__key);
2064     target_ip->uid = tswapl(host_ip->uid);
2065     target_ip->gid = tswapl(host_ip->gid);
2066     target_ip->cuid = tswapl(host_ip->cuid);
2067     target_ip->cgid = tswapl(host_ip->cgid);
2068     target_ip->mode = tswapl(host_ip->mode);
2069     unlock_user_struct(target_sd, target_addr, 1);
2070     return 0;
2071 }
2072 
2073 static inline abi_long target_to_host_semid_ds(struct semid_ds *host_sd,
2074                                                abi_ulong target_addr)
2075 {
2076     struct target_semid_ds *target_sd;
2077 
2078     if (!lock_user_struct(VERIFY_READ, target_sd, target_addr, 1))
2079         return -TARGET_EFAULT;
2080     if (target_to_host_ipc_perm(&(host_sd->sem_perm),target_addr))
2081         return -TARGET_EFAULT;
2082     host_sd->sem_nsems = tswapl(target_sd->sem_nsems);
2083     host_sd->sem_otime = tswapl(target_sd->sem_otime);
2084     host_sd->sem_ctime = tswapl(target_sd->sem_ctime);
2085     unlock_user_struct(target_sd, target_addr, 0);
2086     return 0;
2087 }
2088 
2089 static inline abi_long host_to_target_semid_ds(abi_ulong target_addr,
2090                                                struct semid_ds *host_sd)
2091 {
2092     struct target_semid_ds *target_sd;
2093 
2094     if (!lock_user_struct(VERIFY_WRITE, target_sd, target_addr, 0))
2095         return -TARGET_EFAULT;
2096     if (host_to_target_ipc_perm(target_addr,&(host_sd->sem_perm)))
2097         return -TARGET_EFAULT;;
2098     target_sd->sem_nsems = tswapl(host_sd->sem_nsems);
2099     target_sd->sem_otime = tswapl(host_sd->sem_otime);
2100     target_sd->sem_ctime = tswapl(host_sd->sem_ctime);
2101     unlock_user_struct(target_sd, target_addr, 1);
2102     return 0;
2103 }
2104 
2105 struct target_seminfo {
2106     int semmap;
2107     int semmni;
2108     int semmns;
2109     int semmnu;
2110     int semmsl;
2111     int semopm;
2112     int semume;
2113     int semusz;
2114     int semvmx;
2115     int semaem;
2116 };
2117 
2118 static inline abi_long host_to_target_seminfo(abi_ulong target_addr,
2119                                               struct seminfo *host_seminfo)
2120 {
2121     struct target_seminfo *target_seminfo;
2122     if (!lock_user_struct(VERIFY_WRITE, target_seminfo, target_addr, 0))
2123         return -TARGET_EFAULT;
2124     __put_user(host_seminfo->semmap, &target_seminfo->semmap);
2125     __put_user(host_seminfo->semmni, &target_seminfo->semmni);
2126     __put_user(host_seminfo->semmns, &target_seminfo->semmns);
2127     __put_user(host_seminfo->semmnu, &target_seminfo->semmnu);
2128     __put_user(host_seminfo->semmsl, &target_seminfo->semmsl);
2129     __put_user(host_seminfo->semopm, &target_seminfo->semopm);
2130     __put_user(host_seminfo->semume, &target_seminfo->semume);
2131     __put_user(host_seminfo->semusz, &target_seminfo->semusz);
2132     __put_user(host_seminfo->semvmx, &target_seminfo->semvmx);
2133     __put_user(host_seminfo->semaem, &target_seminfo->semaem);
2134     unlock_user_struct(target_seminfo, target_addr, 1);
2135     return 0;
2136 }
2137 
2138 union semun {
2139 	int val;
2140 	struct semid_ds *buf;
2141 	unsigned short *array;
2142 	struct seminfo *__buf;
2143 };
2144 
2145 union target_semun {
2146 	int val;
2147 	abi_ulong buf;
2148 	abi_ulong array;
2149 	abi_ulong __buf;
2150 };
2151 
2152 static inline abi_long target_to_host_semarray(int semid, unsigned short **host_array,
2153                                                abi_ulong target_addr)
2154 {
2155     int nsems;
2156     unsigned short *array;
2157     union semun semun;
2158     struct semid_ds semid_ds;
2159     int i, ret;
2160 
2161     semun.buf = &semid_ds;
2162 
2163     ret = semctl(semid, 0, IPC_STAT, semun);
2164     if (ret == -1)
2165         return get_errno(ret);
2166 
2167     nsems = semid_ds.sem_nsems;
2168 
2169     *host_array = malloc(nsems*sizeof(unsigned short));
2170     array = lock_user(VERIFY_READ, target_addr,
2171                       nsems*sizeof(unsigned short), 1);
2172     if (!array)
2173         return -TARGET_EFAULT;
2174 
2175     for(i=0; i<nsems; i++) {
2176         __get_user((*host_array)[i], &array[i]);
2177     }
2178     unlock_user(array, target_addr, 0);
2179 
2180     return 0;
2181 }
2182 
2183 static inline abi_long host_to_target_semarray(int semid, abi_ulong target_addr,
2184                                                unsigned short **host_array)
2185 {
2186     int nsems;
2187     unsigned short *array;
2188     union semun semun;
2189     struct semid_ds semid_ds;
2190     int i, ret;
2191 
2192     semun.buf = &semid_ds;
2193 
2194     ret = semctl(semid, 0, IPC_STAT, semun);
2195     if (ret == -1)
2196         return get_errno(ret);
2197 
2198     nsems = semid_ds.sem_nsems;
2199 
2200     array = lock_user(VERIFY_WRITE, target_addr,
2201                       nsems*sizeof(unsigned short), 0);
2202     if (!array)
2203         return -TARGET_EFAULT;
2204 
2205     for(i=0; i<nsems; i++) {
2206         __put_user((*host_array)[i], &array[i]);
2207     }
2208     free(*host_array);
2209     unlock_user(array, target_addr, 1);
2210 
2211     return 0;
2212 }
2213 
2214 static inline abi_long do_semctl(int semid, int semnum, int cmd,
2215                                  union target_semun target_su)
2216 {
2217     union semun arg;
2218     struct semid_ds dsarg;
2219     unsigned short *array;
2220     struct seminfo seminfo;
2221     abi_long ret = -TARGET_EINVAL;
2222     abi_long err;
2223     cmd &= 0xff;
2224 
2225     switch( cmd ) {
2226 	case GETVAL:
2227 	case SETVAL:
2228             arg.val = tswapl(target_su.val);
2229             ret = get_errno(semctl(semid, semnum, cmd, arg));
2230             target_su.val = tswapl(arg.val);
2231             break;
2232 	case GETALL:
2233 	case SETALL:
2234             err = target_to_host_semarray(semid, &array, target_su.array);
2235             if (err)
2236                 return err;
2237             arg.array = array;
2238             ret = get_errno(semctl(semid, semnum, cmd, arg));
2239             err = host_to_target_semarray(semid, target_su.array, &array);
2240             if (err)
2241                 return err;
2242             break;
2243 	case IPC_STAT:
2244 	case IPC_SET:
2245 	case SEM_STAT:
2246             err = target_to_host_semid_ds(&dsarg, target_su.buf);
2247             if (err)
2248                 return err;
2249             arg.buf = &dsarg;
2250             ret = get_errno(semctl(semid, semnum, cmd, arg));
2251             err = host_to_target_semid_ds(target_su.buf, &dsarg);
2252             if (err)
2253                 return err;
2254             break;
2255 	case IPC_INFO:
2256 	case SEM_INFO:
2257             arg.__buf = &seminfo;
2258             ret = get_errno(semctl(semid, semnum, cmd, arg));
2259             err = host_to_target_seminfo(target_su.__buf, &seminfo);
2260             if (err)
2261                 return err;
2262             break;
2263 	case IPC_RMID:
2264 	case GETPID:
2265 	case GETNCNT:
2266 	case GETZCNT:
2267             ret = get_errno(semctl(semid, semnum, cmd, NULL));
2268             break;
2269     }
2270 
2271     return ret;
2272 }
2273 
2274 struct target_sembuf {
2275     unsigned short sem_num;
2276     short sem_op;
2277     short sem_flg;
2278 };
2279 
2280 static inline abi_long target_to_host_sembuf(struct sembuf *host_sembuf,
2281                                              abi_ulong target_addr,
2282                                              unsigned nsops)
2283 {
2284     struct target_sembuf *target_sembuf;
2285     int i;
2286 
2287     target_sembuf = lock_user(VERIFY_READ, target_addr,
2288                               nsops*sizeof(struct target_sembuf), 1);
2289     if (!target_sembuf)
2290         return -TARGET_EFAULT;
2291 
2292     for(i=0; i<nsops; i++) {
2293         __get_user(host_sembuf[i].sem_num, &target_sembuf[i].sem_num);
2294         __get_user(host_sembuf[i].sem_op, &target_sembuf[i].sem_op);
2295         __get_user(host_sembuf[i].sem_flg, &target_sembuf[i].sem_flg);
2296     }
2297 
2298     unlock_user(target_sembuf, target_addr, 0);
2299 
2300     return 0;
2301 }
2302 
2303 static inline abi_long do_semop(int semid, abi_long ptr, unsigned nsops)
2304 {
2305     struct sembuf sops[nsops];
2306 
2307     if (target_to_host_sembuf(sops, ptr, nsops))
2308         return -TARGET_EFAULT;
2309 
2310     return semop(semid, sops, nsops);
2311 }
2312 
2313 struct target_msqid_ds
2314 {
2315     struct target_ipc_perm msg_perm;
2316     abi_ulong msg_stime;
2317 #if TARGET_ABI_BITS == 32
2318     abi_ulong __unused1;
2319 #endif
2320     abi_ulong msg_rtime;
2321 #if TARGET_ABI_BITS == 32
2322     abi_ulong __unused2;
2323 #endif
2324     abi_ulong msg_ctime;
2325 #if TARGET_ABI_BITS == 32
2326     abi_ulong __unused3;
2327 #endif
2328     abi_ulong __msg_cbytes;
2329     abi_ulong msg_qnum;
2330     abi_ulong msg_qbytes;
2331     abi_ulong msg_lspid;
2332     abi_ulong msg_lrpid;
2333     abi_ulong __unused4;
2334     abi_ulong __unused5;
2335 };
2336 
2337 static inline abi_long target_to_host_msqid_ds(struct msqid_ds *host_md,
2338                                                abi_ulong target_addr)
2339 {
2340     struct target_msqid_ds *target_md;
2341 
2342     if (!lock_user_struct(VERIFY_READ, target_md, target_addr, 1))
2343         return -TARGET_EFAULT;
2344     if (target_to_host_ipc_perm(&(host_md->msg_perm),target_addr))
2345         return -TARGET_EFAULT;
2346     host_md->msg_stime = tswapl(target_md->msg_stime);
2347     host_md->msg_rtime = tswapl(target_md->msg_rtime);
2348     host_md->msg_ctime = tswapl(target_md->msg_ctime);
2349     host_md->__msg_cbytes = tswapl(target_md->__msg_cbytes);
2350     host_md->msg_qnum = tswapl(target_md->msg_qnum);
2351     host_md->msg_qbytes = tswapl(target_md->msg_qbytes);
2352     host_md->msg_lspid = tswapl(target_md->msg_lspid);
2353     host_md->msg_lrpid = tswapl(target_md->msg_lrpid);
2354     unlock_user_struct(target_md, target_addr, 0);
2355     return 0;
2356 }
2357 
2358 static inline abi_long host_to_target_msqid_ds(abi_ulong target_addr,
2359                                                struct msqid_ds *host_md)
2360 {
2361     struct target_msqid_ds *target_md;
2362 
2363     if (!lock_user_struct(VERIFY_WRITE, target_md, target_addr, 0))
2364         return -TARGET_EFAULT;
2365     if (host_to_target_ipc_perm(target_addr,&(host_md->msg_perm)))
2366         return -TARGET_EFAULT;
2367     target_md->msg_stime = tswapl(host_md->msg_stime);
2368     target_md->msg_rtime = tswapl(host_md->msg_rtime);
2369     target_md->msg_ctime = tswapl(host_md->msg_ctime);
2370     target_md->__msg_cbytes = tswapl(host_md->__msg_cbytes);
2371     target_md->msg_qnum = tswapl(host_md->msg_qnum);
2372     target_md->msg_qbytes = tswapl(host_md->msg_qbytes);
2373     target_md->msg_lspid = tswapl(host_md->msg_lspid);
2374     target_md->msg_lrpid = tswapl(host_md->msg_lrpid);
2375     unlock_user_struct(target_md, target_addr, 1);
2376     return 0;
2377 }
2378 
2379 struct target_msginfo {
2380     int msgpool;
2381     int msgmap;
2382     int msgmax;
2383     int msgmnb;
2384     int msgmni;
2385     int msgssz;
2386     int msgtql;
2387     unsigned short int msgseg;
2388 };
2389 
2390 static inline abi_long host_to_target_msginfo(abi_ulong target_addr,
2391                                               struct msginfo *host_msginfo)
2392 {
2393     struct target_msginfo *target_msginfo;
2394     if (!lock_user_struct(VERIFY_WRITE, target_msginfo, target_addr, 0))
2395         return -TARGET_EFAULT;
2396     __put_user(host_msginfo->msgpool, &target_msginfo->msgpool);
2397     __put_user(host_msginfo->msgmap, &target_msginfo->msgmap);
2398     __put_user(host_msginfo->msgmax, &target_msginfo->msgmax);
2399     __put_user(host_msginfo->msgmnb, &target_msginfo->msgmnb);
2400     __put_user(host_msginfo->msgmni, &target_msginfo->msgmni);
2401     __put_user(host_msginfo->msgssz, &target_msginfo->msgssz);
2402     __put_user(host_msginfo->msgtql, &target_msginfo->msgtql);
2403     __put_user(host_msginfo->msgseg, &target_msginfo->msgseg);
2404     unlock_user_struct(target_msginfo, target_addr, 1);
2405     return 0;
2406 }
2407 
2408 static inline abi_long do_msgctl(int msgid, int cmd, abi_long ptr)
2409 {
2410     struct msqid_ds dsarg;
2411     struct msginfo msginfo;
2412     abi_long ret = -TARGET_EINVAL;
2413 
2414     cmd &= 0xff;
2415 
2416     switch (cmd) {
2417     case IPC_STAT:
2418     case IPC_SET:
2419     case MSG_STAT:
2420         if (target_to_host_msqid_ds(&dsarg,ptr))
2421             return -TARGET_EFAULT;
2422         ret = get_errno(msgctl(msgid, cmd, &dsarg));
2423         if (host_to_target_msqid_ds(ptr,&dsarg))
2424             return -TARGET_EFAULT;
2425         break;
2426     case IPC_RMID:
2427         ret = get_errno(msgctl(msgid, cmd, NULL));
2428         break;
2429     case IPC_INFO:
2430     case MSG_INFO:
2431         ret = get_errno(msgctl(msgid, cmd, (struct msqid_ds *)&msginfo));
2432         if (host_to_target_msginfo(ptr, &msginfo))
2433             return -TARGET_EFAULT;
2434         break;
2435     }
2436 
2437     return ret;
2438 }
2439 
2440 struct target_msgbuf {
2441     abi_long mtype;
2442     char	mtext[1];
2443 };
2444 
2445 static inline abi_long do_msgsnd(int msqid, abi_long msgp,
2446                                  unsigned int msgsz, int msgflg)
2447 {
2448     struct target_msgbuf *target_mb;
2449     struct msgbuf *host_mb;
2450     abi_long ret = 0;
2451 
2452     if (!lock_user_struct(VERIFY_READ, target_mb, msgp, 0))
2453         return -TARGET_EFAULT;
2454     host_mb = malloc(msgsz+sizeof(long));
2455     host_mb->mtype = (abi_long) tswapl(target_mb->mtype);
2456     memcpy(host_mb->mtext, target_mb->mtext, msgsz);
2457     ret = get_errno(msgsnd(msqid, host_mb, msgsz, msgflg));
2458     free(host_mb);
2459     unlock_user_struct(target_mb, msgp, 0);
2460 
2461     return ret;
2462 }
2463 
2464 static inline abi_long do_msgrcv(int msqid, abi_long msgp,
2465                                  unsigned int msgsz, abi_long msgtyp,
2466                                  int msgflg)
2467 {
2468     struct target_msgbuf *target_mb;
2469     char *target_mtext;
2470     struct msgbuf *host_mb;
2471     abi_long ret = 0;
2472 
2473     if (!lock_user_struct(VERIFY_WRITE, target_mb, msgp, 0))
2474         return -TARGET_EFAULT;
2475 
2476     host_mb = malloc(msgsz+sizeof(long));
2477     ret = get_errno(msgrcv(msqid, host_mb, msgsz, tswapl(msgtyp), msgflg));
2478 
2479     if (ret > 0) {
2480         abi_ulong target_mtext_addr = msgp + sizeof(abi_ulong);
2481         target_mtext = lock_user(VERIFY_WRITE, target_mtext_addr, ret, 0);
2482         if (!target_mtext) {
2483             ret = -TARGET_EFAULT;
2484             goto end;
2485         }
2486         memcpy(target_mb->mtext, host_mb->mtext, ret);
2487         unlock_user(target_mtext, target_mtext_addr, ret);
2488     }
2489 
2490     target_mb->mtype = tswapl(host_mb->mtype);
2491     free(host_mb);
2492 
2493 end:
2494     if (target_mb)
2495         unlock_user_struct(target_mb, msgp, 1);
2496     return ret;
2497 }
2498 
2499 struct target_shmid_ds
2500 {
2501     struct target_ipc_perm shm_perm;
2502     abi_ulong shm_segsz;
2503     abi_ulong shm_atime;
2504 #if TARGET_ABI_BITS == 32
2505     abi_ulong __unused1;
2506 #endif
2507     abi_ulong shm_dtime;
2508 #if TARGET_ABI_BITS == 32
2509     abi_ulong __unused2;
2510 #endif
2511     abi_ulong shm_ctime;
2512 #if TARGET_ABI_BITS == 32
2513     abi_ulong __unused3;
2514 #endif
2515     int shm_cpid;
2516     int shm_lpid;
2517     abi_ulong shm_nattch;
2518     unsigned long int __unused4;
2519     unsigned long int __unused5;
2520 };
2521 
2522 static inline abi_long target_to_host_shmid_ds(struct shmid_ds *host_sd,
2523                                                abi_ulong target_addr)
2524 {
2525     struct target_shmid_ds *target_sd;
2526 
2527     if (!lock_user_struct(VERIFY_READ, target_sd, target_addr, 1))
2528         return -TARGET_EFAULT;
2529     if (target_to_host_ipc_perm(&(host_sd->shm_perm), target_addr))
2530         return -TARGET_EFAULT;
2531     __get_user(host_sd->shm_segsz, &target_sd->shm_segsz);
2532     __get_user(host_sd->shm_atime, &target_sd->shm_atime);
2533     __get_user(host_sd->shm_dtime, &target_sd->shm_dtime);
2534     __get_user(host_sd->shm_ctime, &target_sd->shm_ctime);
2535     __get_user(host_sd->shm_cpid, &target_sd->shm_cpid);
2536     __get_user(host_sd->shm_lpid, &target_sd->shm_lpid);
2537     __get_user(host_sd->shm_nattch, &target_sd->shm_nattch);
2538     unlock_user_struct(target_sd, target_addr, 0);
2539     return 0;
2540 }
2541 
2542 static inline abi_long host_to_target_shmid_ds(abi_ulong target_addr,
2543                                                struct shmid_ds *host_sd)
2544 {
2545     struct target_shmid_ds *target_sd;
2546 
2547     if (!lock_user_struct(VERIFY_WRITE, target_sd, target_addr, 0))
2548         return -TARGET_EFAULT;
2549     if (host_to_target_ipc_perm(target_addr, &(host_sd->shm_perm)))
2550         return -TARGET_EFAULT;
2551     __put_user(host_sd->shm_segsz, &target_sd->shm_segsz);
2552     __put_user(host_sd->shm_atime, &target_sd->shm_atime);
2553     __put_user(host_sd->shm_dtime, &target_sd->shm_dtime);
2554     __put_user(host_sd->shm_ctime, &target_sd->shm_ctime);
2555     __put_user(host_sd->shm_cpid, &target_sd->shm_cpid);
2556     __put_user(host_sd->shm_lpid, &target_sd->shm_lpid);
2557     __put_user(host_sd->shm_nattch, &target_sd->shm_nattch);
2558     unlock_user_struct(target_sd, target_addr, 1);
2559     return 0;
2560 }
2561 
2562 struct  target_shminfo {
2563     abi_ulong shmmax;
2564     abi_ulong shmmin;
2565     abi_ulong shmmni;
2566     abi_ulong shmseg;
2567     abi_ulong shmall;
2568 };
2569 
2570 static inline abi_long host_to_target_shminfo(abi_ulong target_addr,
2571                                               struct shminfo *host_shminfo)
2572 {
2573     struct target_shminfo *target_shminfo;
2574     if (!lock_user_struct(VERIFY_WRITE, target_shminfo, target_addr, 0))
2575         return -TARGET_EFAULT;
2576     __put_user(host_shminfo->shmmax, &target_shminfo->shmmax);
2577     __put_user(host_shminfo->shmmin, &target_shminfo->shmmin);
2578     __put_user(host_shminfo->shmmni, &target_shminfo->shmmni);
2579     __put_user(host_shminfo->shmseg, &target_shminfo->shmseg);
2580     __put_user(host_shminfo->shmall, &target_shminfo->shmall);
2581     unlock_user_struct(target_shminfo, target_addr, 1);
2582     return 0;
2583 }
2584 
2585 struct target_shm_info {
2586     int used_ids;
2587     abi_ulong shm_tot;
2588     abi_ulong shm_rss;
2589     abi_ulong shm_swp;
2590     abi_ulong swap_attempts;
2591     abi_ulong swap_successes;
2592 };
2593 
2594 static inline abi_long host_to_target_shm_info(abi_ulong target_addr,
2595                                                struct shm_info *host_shm_info)
2596 {
2597     struct target_shm_info *target_shm_info;
2598     if (!lock_user_struct(VERIFY_WRITE, target_shm_info, target_addr, 0))
2599         return -TARGET_EFAULT;
2600     __put_user(host_shm_info->used_ids, &target_shm_info->used_ids);
2601     __put_user(host_shm_info->shm_tot, &target_shm_info->shm_tot);
2602     __put_user(host_shm_info->shm_rss, &target_shm_info->shm_rss);
2603     __put_user(host_shm_info->shm_swp, &target_shm_info->shm_swp);
2604     __put_user(host_shm_info->swap_attempts, &target_shm_info->swap_attempts);
2605     __put_user(host_shm_info->swap_successes, &target_shm_info->swap_successes);
2606     unlock_user_struct(target_shm_info, target_addr, 1);
2607     return 0;
2608 }
2609 
2610 static inline abi_long do_shmctl(int shmid, int cmd, abi_long buf)
2611 {
2612     struct shmid_ds dsarg;
2613     struct shminfo shminfo;
2614     struct shm_info shm_info;
2615     abi_long ret = -TARGET_EINVAL;
2616 
2617     cmd &= 0xff;
2618 
2619     switch(cmd) {
2620     case IPC_STAT:
2621     case IPC_SET:
2622     case SHM_STAT:
2623         if (target_to_host_shmid_ds(&dsarg, buf))
2624             return -TARGET_EFAULT;
2625         ret = get_errno(shmctl(shmid, cmd, &dsarg));
2626         if (host_to_target_shmid_ds(buf, &dsarg))
2627             return -TARGET_EFAULT;
2628         break;
2629     case IPC_INFO:
2630         ret = get_errno(shmctl(shmid, cmd, (struct shmid_ds *)&shminfo));
2631         if (host_to_target_shminfo(buf, &shminfo))
2632             return -TARGET_EFAULT;
2633         break;
2634     case SHM_INFO:
2635         ret = get_errno(shmctl(shmid, cmd, (struct shmid_ds *)&shm_info));
2636         if (host_to_target_shm_info(buf, &shm_info))
2637             return -TARGET_EFAULT;
2638         break;
2639     case IPC_RMID:
2640     case SHM_LOCK:
2641     case SHM_UNLOCK:
2642         ret = get_errno(shmctl(shmid, cmd, NULL));
2643         break;
2644     }
2645 
2646     return ret;
2647 }
2648 
2649 static inline abi_ulong do_shmat(int shmid, abi_ulong shmaddr, int shmflg)
2650 {
2651     abi_long raddr;
2652     void *host_raddr;
2653     struct shmid_ds shm_info;
2654     int i,ret;
2655 
2656     /* find out the length of the shared memory segment */
2657     ret = get_errno(shmctl(shmid, IPC_STAT, &shm_info));
2658     if (is_error(ret)) {
2659         /* can't get length, bail out */
2660         return ret;
2661     }
2662 
2663     mmap_lock();
2664 
2665     if (shmaddr)
2666         host_raddr = shmat(shmid, (void *)g2h(shmaddr), shmflg);
2667     else {
2668         abi_ulong mmap_start;
2669 
2670         mmap_start = mmap_find_vma(0, shm_info.shm_segsz);
2671 
2672         if (mmap_start == -1) {
2673             errno = ENOMEM;
2674             host_raddr = (void *)-1;
2675         } else
2676             host_raddr = shmat(shmid, g2h(mmap_start), shmflg | SHM_REMAP);
2677     }
2678 
2679     if (host_raddr == (void *)-1) {
2680         mmap_unlock();
2681         return get_errno((long)host_raddr);
2682     }
2683     raddr=h2g((unsigned long)host_raddr);
2684 
2685     page_set_flags(raddr, raddr + shm_info.shm_segsz,
2686                    PAGE_VALID | PAGE_READ |
2687                    ((shmflg & SHM_RDONLY)? 0 : PAGE_WRITE));
2688 
2689     for (i = 0; i < N_SHM_REGIONS; i++) {
2690         if (shm_regions[i].start == 0) {
2691             shm_regions[i].start = raddr;
2692             shm_regions[i].size = shm_info.shm_segsz;
2693             break;
2694         }
2695     }
2696 
2697     mmap_unlock();
2698     return raddr;
2699 
2700 }
2701 
2702 static inline abi_long do_shmdt(abi_ulong shmaddr)
2703 {
2704     int i;
2705 
2706     for (i = 0; i < N_SHM_REGIONS; ++i) {
2707         if (shm_regions[i].start == shmaddr) {
2708             shm_regions[i].start = 0;
2709             page_set_flags(shmaddr, shm_regions[i].size, 0);
2710             break;
2711         }
2712     }
2713 
2714     return get_errno(shmdt(g2h(shmaddr)));
2715 }
2716 
2717 #ifdef TARGET_NR_ipc
2718 /* ??? This only works with linear mappings.  */
2719 /* do_ipc() must return target values and target errnos. */
2720 static abi_long do_ipc(unsigned int call, int first,
2721                        int second, int third,
2722                        abi_long ptr, abi_long fifth)
2723 {
2724     int version;
2725     abi_long ret = 0;
2726 
2727     version = call >> 16;
2728     call &= 0xffff;
2729 
2730     switch (call) {
2731     case IPCOP_semop:
2732         ret = do_semop(first, ptr, second);
2733         break;
2734 
2735     case IPCOP_semget:
2736         ret = get_errno(semget(first, second, third));
2737         break;
2738 
2739     case IPCOP_semctl:
2740         ret = do_semctl(first, second, third, (union target_semun)(abi_ulong) ptr);
2741         break;
2742 
2743     case IPCOP_msgget:
2744         ret = get_errno(msgget(first, second));
2745         break;
2746 
2747     case IPCOP_msgsnd:
2748         ret = do_msgsnd(first, ptr, second, third);
2749         break;
2750 
2751     case IPCOP_msgctl:
2752         ret = do_msgctl(first, second, ptr);
2753         break;
2754 
2755     case IPCOP_msgrcv:
2756         switch (version) {
2757         case 0:
2758             {
2759                 struct target_ipc_kludge {
2760                     abi_long msgp;
2761                     abi_long msgtyp;
2762                 } *tmp;
2763 
2764                 if (!lock_user_struct(VERIFY_READ, tmp, ptr, 1)) {
2765                     ret = -TARGET_EFAULT;
2766                     break;
2767                 }
2768 
2769                 ret = do_msgrcv(first, tmp->msgp, second, tmp->msgtyp, third);
2770 
2771                 unlock_user_struct(tmp, ptr, 0);
2772                 break;
2773             }
2774         default:
2775             ret = do_msgrcv(first, ptr, second, fifth, third);
2776         }
2777         break;
2778 
2779     case IPCOP_shmat:
2780         switch (version) {
2781         default:
2782         {
2783             abi_ulong raddr;
2784             raddr = do_shmat(first, ptr, second);
2785             if (is_error(raddr))
2786                 return get_errno(raddr);
2787             if (put_user_ual(raddr, third))
2788                 return -TARGET_EFAULT;
2789             break;
2790         }
2791         case 1:
2792             ret = -TARGET_EINVAL;
2793             break;
2794         }
2795 	break;
2796     case IPCOP_shmdt:
2797         ret = do_shmdt(ptr);
2798 	break;
2799 
2800     case IPCOP_shmget:
2801 	/* IPC_* flag values are the same on all linux platforms */
2802 	ret = get_errno(shmget(first, second, third));
2803 	break;
2804 
2805 	/* IPC_* and SHM_* command values are the same on all linux platforms */
2806     case IPCOP_shmctl:
2807         ret = do_shmctl(first, second, third);
2808         break;
2809     default:
2810 	gemu_log("Unsupported ipc call: %d (version %d)\n", call, version);
2811 	ret = -TARGET_ENOSYS;
2812 	break;
2813     }
2814     return ret;
2815 }
2816 #endif
2817 
2818 /* kernel structure types definitions */
2819 #define IFNAMSIZ        16
2820 
2821 #define STRUCT(name, ...) STRUCT_ ## name,
2822 #define STRUCT_SPECIAL(name) STRUCT_ ## name,
2823 enum {
2824 #include "syscall_types.h"
2825 };
2826 #undef STRUCT
2827 #undef STRUCT_SPECIAL
2828 
2829 #define STRUCT(name, ...) static const argtype struct_ ## name ## _def[] = {  __VA_ARGS__, TYPE_NULL };
2830 #define STRUCT_SPECIAL(name)
2831 #include "syscall_types.h"
2832 #undef STRUCT
2833 #undef STRUCT_SPECIAL
2834 
2835 typedef struct IOCTLEntry {
2836     unsigned int target_cmd;
2837     unsigned int host_cmd;
2838     const char *name;
2839     int access;
2840     const argtype arg_type[5];
2841 } IOCTLEntry;
2842 
2843 #define IOC_R 0x0001
2844 #define IOC_W 0x0002
2845 #define IOC_RW (IOC_R | IOC_W)
2846 
2847 #define MAX_STRUCT_SIZE 4096
2848 
2849 static IOCTLEntry ioctl_entries[] = {
2850 #define IOCTL(cmd, access, ...) \
2851     { TARGET_ ## cmd, cmd, #cmd, access, {  __VA_ARGS__ } },
2852 #include "ioctls.h"
2853     { 0, 0, },
2854 };
2855 
2856 /* ??? Implement proper locking for ioctls.  */
2857 /* do_ioctl() Must return target values and target errnos. */
2858 static abi_long do_ioctl(int fd, abi_long cmd, abi_long arg)
2859 {
2860     const IOCTLEntry *ie;
2861     const argtype *arg_type;
2862     abi_long ret;
2863     uint8_t buf_temp[MAX_STRUCT_SIZE];
2864     int target_size;
2865     void *argptr;
2866 
2867     ie = ioctl_entries;
2868     for(;;) {
2869         if (ie->target_cmd == 0) {
2870             gemu_log("Unsupported ioctl: cmd=0x%04lx\n", (long)cmd);
2871             return -TARGET_ENOSYS;
2872         }
2873         if (ie->target_cmd == cmd)
2874             break;
2875         ie++;
2876     }
2877     arg_type = ie->arg_type;
2878 #if defined(DEBUG)
2879     gemu_log("ioctl: cmd=0x%04lx (%s)\n", (long)cmd, ie->name);
2880 #endif
2881     switch(arg_type[0]) {
2882     case TYPE_NULL:
2883         /* no argument */
2884         ret = get_errno(ioctl(fd, ie->host_cmd));
2885         break;
2886     case TYPE_PTRVOID:
2887     case TYPE_INT:
2888         /* int argment */
2889         ret = get_errno(ioctl(fd, ie->host_cmd, arg));
2890         break;
2891     case TYPE_PTR:
2892         arg_type++;
2893         target_size = thunk_type_size(arg_type, 0);
2894         switch(ie->access) {
2895         case IOC_R:
2896             ret = get_errno(ioctl(fd, ie->host_cmd, buf_temp));
2897             if (!is_error(ret)) {
2898                 argptr = lock_user(VERIFY_WRITE, arg, target_size, 0);
2899                 if (!argptr)
2900                     return -TARGET_EFAULT;
2901                 thunk_convert(argptr, buf_temp, arg_type, THUNK_TARGET);
2902                 unlock_user(argptr, arg, target_size);
2903             }
2904             break;
2905         case IOC_W:
2906             argptr = lock_user(VERIFY_READ, arg, target_size, 1);
2907             if (!argptr)
2908                 return -TARGET_EFAULT;
2909             thunk_convert(buf_temp, argptr, arg_type, THUNK_HOST);
2910             unlock_user(argptr, arg, 0);
2911             ret = get_errno(ioctl(fd, ie->host_cmd, buf_temp));
2912             break;
2913         default:
2914         case IOC_RW:
2915             argptr = lock_user(VERIFY_READ, arg, target_size, 1);
2916             if (!argptr)
2917                 return -TARGET_EFAULT;
2918             thunk_convert(buf_temp, argptr, arg_type, THUNK_HOST);
2919             unlock_user(argptr, arg, 0);
2920             ret = get_errno(ioctl(fd, ie->host_cmd, buf_temp));
2921             if (!is_error(ret)) {
2922                 argptr = lock_user(VERIFY_WRITE, arg, target_size, 0);
2923                 if (!argptr)
2924                     return -TARGET_EFAULT;
2925                 thunk_convert(argptr, buf_temp, arg_type, THUNK_TARGET);
2926                 unlock_user(argptr, arg, target_size);
2927             }
2928             break;
2929         }
2930         break;
2931     default:
2932         gemu_log("Unsupported ioctl type: cmd=0x%04lx type=%d\n",
2933                  (long)cmd, arg_type[0]);
2934         ret = -TARGET_ENOSYS;
2935         break;
2936     }
2937     return ret;
2938 }
2939 
2940 static const bitmask_transtbl iflag_tbl[] = {
2941         { TARGET_IGNBRK, TARGET_IGNBRK, IGNBRK, IGNBRK },
2942         { TARGET_BRKINT, TARGET_BRKINT, BRKINT, BRKINT },
2943         { TARGET_IGNPAR, TARGET_IGNPAR, IGNPAR, IGNPAR },
2944         { TARGET_PARMRK, TARGET_PARMRK, PARMRK, PARMRK },
2945         { TARGET_INPCK, TARGET_INPCK, INPCK, INPCK },
2946         { TARGET_ISTRIP, TARGET_ISTRIP, ISTRIP, ISTRIP },
2947         { TARGET_INLCR, TARGET_INLCR, INLCR, INLCR },
2948         { TARGET_IGNCR, TARGET_IGNCR, IGNCR, IGNCR },
2949         { TARGET_ICRNL, TARGET_ICRNL, ICRNL, ICRNL },
2950         { TARGET_IUCLC, TARGET_IUCLC, IUCLC, IUCLC },
2951         { TARGET_IXON, TARGET_IXON, IXON, IXON },
2952         { TARGET_IXANY, TARGET_IXANY, IXANY, IXANY },
2953         { TARGET_IXOFF, TARGET_IXOFF, IXOFF, IXOFF },
2954         { TARGET_IMAXBEL, TARGET_IMAXBEL, IMAXBEL, IMAXBEL },
2955         { 0, 0, 0, 0 }
2956 };
2957 
2958 static const bitmask_transtbl oflag_tbl[] = {
2959 	{ TARGET_OPOST, TARGET_OPOST, OPOST, OPOST },
2960 	{ TARGET_OLCUC, TARGET_OLCUC, OLCUC, OLCUC },
2961 	{ TARGET_ONLCR, TARGET_ONLCR, ONLCR, ONLCR },
2962 	{ TARGET_OCRNL, TARGET_OCRNL, OCRNL, OCRNL },
2963 	{ TARGET_ONOCR, TARGET_ONOCR, ONOCR, ONOCR },
2964 	{ TARGET_ONLRET, TARGET_ONLRET, ONLRET, ONLRET },
2965 	{ TARGET_OFILL, TARGET_OFILL, OFILL, OFILL },
2966 	{ TARGET_OFDEL, TARGET_OFDEL, OFDEL, OFDEL },
2967 	{ TARGET_NLDLY, TARGET_NL0, NLDLY, NL0 },
2968 	{ TARGET_NLDLY, TARGET_NL1, NLDLY, NL1 },
2969 	{ TARGET_CRDLY, TARGET_CR0, CRDLY, CR0 },
2970 	{ TARGET_CRDLY, TARGET_CR1, CRDLY, CR1 },
2971 	{ TARGET_CRDLY, TARGET_CR2, CRDLY, CR2 },
2972 	{ TARGET_CRDLY, TARGET_CR3, CRDLY, CR3 },
2973 	{ TARGET_TABDLY, TARGET_TAB0, TABDLY, TAB0 },
2974 	{ TARGET_TABDLY, TARGET_TAB1, TABDLY, TAB1 },
2975 	{ TARGET_TABDLY, TARGET_TAB2, TABDLY, TAB2 },
2976 	{ TARGET_TABDLY, TARGET_TAB3, TABDLY, TAB3 },
2977 	{ TARGET_BSDLY, TARGET_BS0, BSDLY, BS0 },
2978 	{ TARGET_BSDLY, TARGET_BS1, BSDLY, BS1 },
2979 	{ TARGET_VTDLY, TARGET_VT0, VTDLY, VT0 },
2980 	{ TARGET_VTDLY, TARGET_VT1, VTDLY, VT1 },
2981 	{ TARGET_FFDLY, TARGET_FF0, FFDLY, FF0 },
2982 	{ TARGET_FFDLY, TARGET_FF1, FFDLY, FF1 },
2983 	{ 0, 0, 0, 0 }
2984 };
2985 
2986 static const bitmask_transtbl cflag_tbl[] = {
2987 	{ TARGET_CBAUD, TARGET_B0, CBAUD, B0 },
2988 	{ TARGET_CBAUD, TARGET_B50, CBAUD, B50 },
2989 	{ TARGET_CBAUD, TARGET_B75, CBAUD, B75 },
2990 	{ TARGET_CBAUD, TARGET_B110, CBAUD, B110 },
2991 	{ TARGET_CBAUD, TARGET_B134, CBAUD, B134 },
2992 	{ TARGET_CBAUD, TARGET_B150, CBAUD, B150 },
2993 	{ TARGET_CBAUD, TARGET_B200, CBAUD, B200 },
2994 	{ TARGET_CBAUD, TARGET_B300, CBAUD, B300 },
2995 	{ TARGET_CBAUD, TARGET_B600, CBAUD, B600 },
2996 	{ TARGET_CBAUD, TARGET_B1200, CBAUD, B1200 },
2997 	{ TARGET_CBAUD, TARGET_B1800, CBAUD, B1800 },
2998 	{ TARGET_CBAUD, TARGET_B2400, CBAUD, B2400 },
2999 	{ TARGET_CBAUD, TARGET_B4800, CBAUD, B4800 },
3000 	{ TARGET_CBAUD, TARGET_B9600, CBAUD, B9600 },
3001 	{ TARGET_CBAUD, TARGET_B19200, CBAUD, B19200 },
3002 	{ TARGET_CBAUD, TARGET_B38400, CBAUD, B38400 },
3003 	{ TARGET_CBAUD, TARGET_B57600, CBAUD, B57600 },
3004 	{ TARGET_CBAUD, TARGET_B115200, CBAUD, B115200 },
3005 	{ TARGET_CBAUD, TARGET_B230400, CBAUD, B230400 },
3006 	{ TARGET_CBAUD, TARGET_B460800, CBAUD, B460800 },
3007 	{ TARGET_CSIZE, TARGET_CS5, CSIZE, CS5 },
3008 	{ TARGET_CSIZE, TARGET_CS6, CSIZE, CS6 },
3009 	{ TARGET_CSIZE, TARGET_CS7, CSIZE, CS7 },
3010 	{ TARGET_CSIZE, TARGET_CS8, CSIZE, CS8 },
3011 	{ TARGET_CSTOPB, TARGET_CSTOPB, CSTOPB, CSTOPB },
3012 	{ TARGET_CREAD, TARGET_CREAD, CREAD, CREAD },
3013 	{ TARGET_PARENB, TARGET_PARENB, PARENB, PARENB },
3014 	{ TARGET_PARODD, TARGET_PARODD, PARODD, PARODD },
3015 	{ TARGET_HUPCL, TARGET_HUPCL, HUPCL, HUPCL },
3016 	{ TARGET_CLOCAL, TARGET_CLOCAL, CLOCAL, CLOCAL },
3017 	{ TARGET_CRTSCTS, TARGET_CRTSCTS, CRTSCTS, CRTSCTS },
3018 	{ 0, 0, 0, 0 }
3019 };
3020 
3021 static const bitmask_transtbl lflag_tbl[] = {
3022 	{ TARGET_ISIG, TARGET_ISIG, ISIG, ISIG },
3023 	{ TARGET_ICANON, TARGET_ICANON, ICANON, ICANON },
3024 	{ TARGET_XCASE, TARGET_XCASE, XCASE, XCASE },
3025 	{ TARGET_ECHO, TARGET_ECHO, ECHO, ECHO },
3026 	{ TARGET_ECHOE, TARGET_ECHOE, ECHOE, ECHOE },
3027 	{ TARGET_ECHOK, TARGET_ECHOK, ECHOK, ECHOK },
3028 	{ TARGET_ECHONL, TARGET_ECHONL, ECHONL, ECHONL },
3029 	{ TARGET_NOFLSH, TARGET_NOFLSH, NOFLSH, NOFLSH },
3030 	{ TARGET_TOSTOP, TARGET_TOSTOP, TOSTOP, TOSTOP },
3031 	{ TARGET_ECHOCTL, TARGET_ECHOCTL, ECHOCTL, ECHOCTL },
3032 	{ TARGET_ECHOPRT, TARGET_ECHOPRT, ECHOPRT, ECHOPRT },
3033 	{ TARGET_ECHOKE, TARGET_ECHOKE, ECHOKE, ECHOKE },
3034 	{ TARGET_FLUSHO, TARGET_FLUSHO, FLUSHO, FLUSHO },
3035 	{ TARGET_PENDIN, TARGET_PENDIN, PENDIN, PENDIN },
3036 	{ TARGET_IEXTEN, TARGET_IEXTEN, IEXTEN, IEXTEN },
3037 	{ 0, 0, 0, 0 }
3038 };
3039 
3040 static void target_to_host_termios (void *dst, const void *src)
3041 {
3042     struct host_termios *host = dst;
3043     const struct target_termios *target = src;
3044 
3045     host->c_iflag =
3046         target_to_host_bitmask(tswap32(target->c_iflag), iflag_tbl);
3047     host->c_oflag =
3048         target_to_host_bitmask(tswap32(target->c_oflag), oflag_tbl);
3049     host->c_cflag =
3050         target_to_host_bitmask(tswap32(target->c_cflag), cflag_tbl);
3051     host->c_lflag =
3052         target_to_host_bitmask(tswap32(target->c_lflag), lflag_tbl);
3053     host->c_line = target->c_line;
3054 
3055     memset(host->c_cc, 0, sizeof(host->c_cc));
3056     host->c_cc[VINTR] = target->c_cc[TARGET_VINTR];
3057     host->c_cc[VQUIT] = target->c_cc[TARGET_VQUIT];
3058     host->c_cc[VERASE] = target->c_cc[TARGET_VERASE];
3059     host->c_cc[VKILL] = target->c_cc[TARGET_VKILL];
3060     host->c_cc[VEOF] = target->c_cc[TARGET_VEOF];
3061     host->c_cc[VTIME] = target->c_cc[TARGET_VTIME];
3062     host->c_cc[VMIN] = target->c_cc[TARGET_VMIN];
3063     host->c_cc[VSWTC] = target->c_cc[TARGET_VSWTC];
3064     host->c_cc[VSTART] = target->c_cc[TARGET_VSTART];
3065     host->c_cc[VSTOP] = target->c_cc[TARGET_VSTOP];
3066     host->c_cc[VSUSP] = target->c_cc[TARGET_VSUSP];
3067     host->c_cc[VEOL] = target->c_cc[TARGET_VEOL];
3068     host->c_cc[VREPRINT] = target->c_cc[TARGET_VREPRINT];
3069     host->c_cc[VDISCARD] = target->c_cc[TARGET_VDISCARD];
3070     host->c_cc[VWERASE] = target->c_cc[TARGET_VWERASE];
3071     host->c_cc[VLNEXT] = target->c_cc[TARGET_VLNEXT];
3072     host->c_cc[VEOL2] = target->c_cc[TARGET_VEOL2];
3073 }
3074 
3075 static void host_to_target_termios (void *dst, const void *src)
3076 {
3077     struct target_termios *target = dst;
3078     const struct host_termios *host = src;
3079 
3080     target->c_iflag =
3081         tswap32(host_to_target_bitmask(host->c_iflag, iflag_tbl));
3082     target->c_oflag =
3083         tswap32(host_to_target_bitmask(host->c_oflag, oflag_tbl));
3084     target->c_cflag =
3085         tswap32(host_to_target_bitmask(host->c_cflag, cflag_tbl));
3086     target->c_lflag =
3087         tswap32(host_to_target_bitmask(host->c_lflag, lflag_tbl));
3088     target->c_line = host->c_line;
3089 
3090     memset(target->c_cc, 0, sizeof(target->c_cc));
3091     target->c_cc[TARGET_VINTR] = host->c_cc[VINTR];
3092     target->c_cc[TARGET_VQUIT] = host->c_cc[VQUIT];
3093     target->c_cc[TARGET_VERASE] = host->c_cc[VERASE];
3094     target->c_cc[TARGET_VKILL] = host->c_cc[VKILL];
3095     target->c_cc[TARGET_VEOF] = host->c_cc[VEOF];
3096     target->c_cc[TARGET_VTIME] = host->c_cc[VTIME];
3097     target->c_cc[TARGET_VMIN] = host->c_cc[VMIN];
3098     target->c_cc[TARGET_VSWTC] = host->c_cc[VSWTC];
3099     target->c_cc[TARGET_VSTART] = host->c_cc[VSTART];
3100     target->c_cc[TARGET_VSTOP] = host->c_cc[VSTOP];
3101     target->c_cc[TARGET_VSUSP] = host->c_cc[VSUSP];
3102     target->c_cc[TARGET_VEOL] = host->c_cc[VEOL];
3103     target->c_cc[TARGET_VREPRINT] = host->c_cc[VREPRINT];
3104     target->c_cc[TARGET_VDISCARD] = host->c_cc[VDISCARD];
3105     target->c_cc[TARGET_VWERASE] = host->c_cc[VWERASE];
3106     target->c_cc[TARGET_VLNEXT] = host->c_cc[VLNEXT];
3107     target->c_cc[TARGET_VEOL2] = host->c_cc[VEOL2];
3108 }
3109 
3110 static const StructEntry struct_termios_def = {
3111     .convert = { host_to_target_termios, target_to_host_termios },
3112     .size = { sizeof(struct target_termios), sizeof(struct host_termios) },
3113     .align = { __alignof__(struct target_termios), __alignof__(struct host_termios) },
3114 };
3115 
3116 static bitmask_transtbl mmap_flags_tbl[] = {
3117 	{ TARGET_MAP_SHARED, TARGET_MAP_SHARED, MAP_SHARED, MAP_SHARED },
3118 	{ TARGET_MAP_PRIVATE, TARGET_MAP_PRIVATE, MAP_PRIVATE, MAP_PRIVATE },
3119 	{ TARGET_MAP_FIXED, TARGET_MAP_FIXED, MAP_FIXED, MAP_FIXED },
3120 	{ TARGET_MAP_ANONYMOUS, TARGET_MAP_ANONYMOUS, MAP_ANONYMOUS, MAP_ANONYMOUS },
3121 	{ TARGET_MAP_GROWSDOWN, TARGET_MAP_GROWSDOWN, MAP_GROWSDOWN, MAP_GROWSDOWN },
3122 	{ TARGET_MAP_DENYWRITE, TARGET_MAP_DENYWRITE, MAP_DENYWRITE, MAP_DENYWRITE },
3123 	{ TARGET_MAP_EXECUTABLE, TARGET_MAP_EXECUTABLE, MAP_EXECUTABLE, MAP_EXECUTABLE },
3124 	{ TARGET_MAP_LOCKED, TARGET_MAP_LOCKED, MAP_LOCKED, MAP_LOCKED },
3125 	{ 0, 0, 0, 0 }
3126 };
3127 
3128 #if defined(TARGET_I386)
3129 
3130 /* NOTE: there is really one LDT for all the threads */
3131 static uint8_t *ldt_table;
3132 
3133 static abi_long read_ldt(abi_ulong ptr, unsigned long bytecount)
3134 {
3135     int size;
3136     void *p;
3137 
3138     if (!ldt_table)
3139         return 0;
3140     size = TARGET_LDT_ENTRIES * TARGET_LDT_ENTRY_SIZE;
3141     if (size > bytecount)
3142         size = bytecount;
3143     p = lock_user(VERIFY_WRITE, ptr, size, 0);
3144     if (!p)
3145         return -TARGET_EFAULT;
3146     /* ??? Should this by byteswapped?  */
3147     memcpy(p, ldt_table, size);
3148     unlock_user(p, ptr, size);
3149     return size;
3150 }
3151 
3152 /* XXX: add locking support */
3153 static abi_long write_ldt(CPUX86State *env,
3154                           abi_ulong ptr, unsigned long bytecount, int oldmode)
3155 {
3156     struct target_modify_ldt_ldt_s ldt_info;
3157     struct target_modify_ldt_ldt_s *target_ldt_info;
3158     int seg_32bit, contents, read_exec_only, limit_in_pages;
3159     int seg_not_present, useable, lm;
3160     uint32_t *lp, entry_1, entry_2;
3161 
3162     if (bytecount != sizeof(ldt_info))
3163         return -TARGET_EINVAL;
3164     if (!lock_user_struct(VERIFY_READ, target_ldt_info, ptr, 1))
3165         return -TARGET_EFAULT;
3166     ldt_info.entry_number = tswap32(target_ldt_info->entry_number);
3167     ldt_info.base_addr = tswapl(target_ldt_info->base_addr);
3168     ldt_info.limit = tswap32(target_ldt_info->limit);
3169     ldt_info.flags = tswap32(target_ldt_info->flags);
3170     unlock_user_struct(target_ldt_info, ptr, 0);
3171 
3172     if (ldt_info.entry_number >= TARGET_LDT_ENTRIES)
3173         return -TARGET_EINVAL;
3174     seg_32bit = ldt_info.flags & 1;
3175     contents = (ldt_info.flags >> 1) & 3;
3176     read_exec_only = (ldt_info.flags >> 3) & 1;
3177     limit_in_pages = (ldt_info.flags >> 4) & 1;
3178     seg_not_present = (ldt_info.flags >> 5) & 1;
3179     useable = (ldt_info.flags >> 6) & 1;
3180 #ifdef TARGET_ABI32
3181     lm = 0;
3182 #else
3183     lm = (ldt_info.flags >> 7) & 1;
3184 #endif
3185     if (contents == 3) {
3186         if (oldmode)
3187             return -TARGET_EINVAL;
3188         if (seg_not_present == 0)
3189             return -TARGET_EINVAL;
3190     }
3191     /* allocate the LDT */
3192     if (!ldt_table) {
3193         env->ldt.base = target_mmap(0,
3194                                     TARGET_LDT_ENTRIES * TARGET_LDT_ENTRY_SIZE,
3195                                     PROT_READ|PROT_WRITE,
3196                                     MAP_ANONYMOUS|MAP_PRIVATE, -1, 0);
3197         if (env->ldt.base == -1)
3198             return -TARGET_ENOMEM;
3199         memset(g2h(env->ldt.base), 0,
3200                TARGET_LDT_ENTRIES * TARGET_LDT_ENTRY_SIZE);
3201         env->ldt.limit = 0xffff;
3202         ldt_table = g2h(env->ldt.base);
3203     }
3204 
3205     /* NOTE: same code as Linux kernel */
3206     /* Allow LDTs to be cleared by the user. */
3207     if (ldt_info.base_addr == 0 && ldt_info.limit == 0) {
3208         if (oldmode ||
3209             (contents == 0		&&
3210              read_exec_only == 1	&&
3211              seg_32bit == 0		&&
3212              limit_in_pages == 0	&&
3213              seg_not_present == 1	&&
3214              useable == 0 )) {
3215             entry_1 = 0;
3216             entry_2 = 0;
3217             goto install;
3218         }
3219     }
3220 
3221     entry_1 = ((ldt_info.base_addr & 0x0000ffff) << 16) |
3222         (ldt_info.limit & 0x0ffff);
3223     entry_2 = (ldt_info.base_addr & 0xff000000) |
3224         ((ldt_info.base_addr & 0x00ff0000) >> 16) |
3225         (ldt_info.limit & 0xf0000) |
3226         ((read_exec_only ^ 1) << 9) |
3227         (contents << 10) |
3228         ((seg_not_present ^ 1) << 15) |
3229         (seg_32bit << 22) |
3230         (limit_in_pages << 23) |
3231         (lm << 21) |
3232         0x7000;
3233     if (!oldmode)
3234         entry_2 |= (useable << 20);
3235 
3236     /* Install the new entry ...  */
3237 install:
3238     lp = (uint32_t *)(ldt_table + (ldt_info.entry_number << 3));
3239     lp[0] = tswap32(entry_1);
3240     lp[1] = tswap32(entry_2);
3241     return 0;
3242 }
3243 
3244 /* specific and weird i386 syscalls */
3245 static abi_long do_modify_ldt(CPUX86State *env, int func, abi_ulong ptr,
3246                               unsigned long bytecount)
3247 {
3248     abi_long ret;
3249 
3250     switch (func) {
3251     case 0:
3252         ret = read_ldt(ptr, bytecount);
3253         break;
3254     case 1:
3255         ret = write_ldt(env, ptr, bytecount, 1);
3256         break;
3257     case 0x11:
3258         ret = write_ldt(env, ptr, bytecount, 0);
3259         break;
3260     default:
3261         ret = -TARGET_ENOSYS;
3262         break;
3263     }
3264     return ret;
3265 }
3266 
3267 #if defined(TARGET_I386) && defined(TARGET_ABI32)
3268 static abi_long do_set_thread_area(CPUX86State *env, abi_ulong ptr)
3269 {
3270     uint64_t *gdt_table = g2h(env->gdt.base);
3271     struct target_modify_ldt_ldt_s ldt_info;
3272     struct target_modify_ldt_ldt_s *target_ldt_info;
3273     int seg_32bit, contents, read_exec_only, limit_in_pages;
3274     int seg_not_present, useable, lm;
3275     uint32_t *lp, entry_1, entry_2;
3276     int i;
3277 
3278     lock_user_struct(VERIFY_WRITE, target_ldt_info, ptr, 1);
3279     if (!target_ldt_info)
3280         return -TARGET_EFAULT;
3281     ldt_info.entry_number = tswap32(target_ldt_info->entry_number);
3282     ldt_info.base_addr = tswapl(target_ldt_info->base_addr);
3283     ldt_info.limit = tswap32(target_ldt_info->limit);
3284     ldt_info.flags = tswap32(target_ldt_info->flags);
3285     if (ldt_info.entry_number == -1) {
3286         for (i=TARGET_GDT_ENTRY_TLS_MIN; i<=TARGET_GDT_ENTRY_TLS_MAX; i++) {
3287             if (gdt_table[i] == 0) {
3288                 ldt_info.entry_number = i;
3289                 target_ldt_info->entry_number = tswap32(i);
3290                 break;
3291             }
3292         }
3293     }
3294     unlock_user_struct(target_ldt_info, ptr, 1);
3295 
3296     if (ldt_info.entry_number < TARGET_GDT_ENTRY_TLS_MIN ||
3297         ldt_info.entry_number > TARGET_GDT_ENTRY_TLS_MAX)
3298            return -TARGET_EINVAL;
3299     seg_32bit = ldt_info.flags & 1;
3300     contents = (ldt_info.flags >> 1) & 3;
3301     read_exec_only = (ldt_info.flags >> 3) & 1;
3302     limit_in_pages = (ldt_info.flags >> 4) & 1;
3303     seg_not_present = (ldt_info.flags >> 5) & 1;
3304     useable = (ldt_info.flags >> 6) & 1;
3305 #ifdef TARGET_ABI32
3306     lm = 0;
3307 #else
3308     lm = (ldt_info.flags >> 7) & 1;
3309 #endif
3310 
3311     if (contents == 3) {
3312         if (seg_not_present == 0)
3313             return -TARGET_EINVAL;
3314     }
3315 
3316     /* NOTE: same code as Linux kernel */
3317     /* Allow LDTs to be cleared by the user. */
3318     if (ldt_info.base_addr == 0 && ldt_info.limit == 0) {
3319         if ((contents == 0             &&
3320              read_exec_only == 1       &&
3321              seg_32bit == 0            &&
3322              limit_in_pages == 0       &&
3323              seg_not_present == 1      &&
3324              useable == 0 )) {
3325             entry_1 = 0;
3326             entry_2 = 0;
3327             goto install;
3328         }
3329     }
3330 
3331     entry_1 = ((ldt_info.base_addr & 0x0000ffff) << 16) |
3332         (ldt_info.limit & 0x0ffff);
3333     entry_2 = (ldt_info.base_addr & 0xff000000) |
3334         ((ldt_info.base_addr & 0x00ff0000) >> 16) |
3335         (ldt_info.limit & 0xf0000) |
3336         ((read_exec_only ^ 1) << 9) |
3337         (contents << 10) |
3338         ((seg_not_present ^ 1) << 15) |
3339         (seg_32bit << 22) |
3340         (limit_in_pages << 23) |
3341         (useable << 20) |
3342         (lm << 21) |
3343         0x7000;
3344 
3345     /* Install the new entry ...  */
3346 install:
3347     lp = (uint32_t *)(gdt_table + ldt_info.entry_number);
3348     lp[0] = tswap32(entry_1);
3349     lp[1] = tswap32(entry_2);
3350     return 0;
3351 }
3352 
3353 static abi_long do_get_thread_area(CPUX86State *env, abi_ulong ptr)
3354 {
3355     struct target_modify_ldt_ldt_s *target_ldt_info;
3356     uint64_t *gdt_table = g2h(env->gdt.base);
3357     uint32_t base_addr, limit, flags;
3358     int seg_32bit, contents, read_exec_only, limit_in_pages, idx;
3359     int seg_not_present, useable, lm;
3360     uint32_t *lp, entry_1, entry_2;
3361 
3362     lock_user_struct(VERIFY_WRITE, target_ldt_info, ptr, 1);
3363     if (!target_ldt_info)
3364         return -TARGET_EFAULT;
3365     idx = tswap32(target_ldt_info->entry_number);
3366     if (idx < TARGET_GDT_ENTRY_TLS_MIN ||
3367         idx > TARGET_GDT_ENTRY_TLS_MAX) {
3368         unlock_user_struct(target_ldt_info, ptr, 1);
3369         return -TARGET_EINVAL;
3370     }
3371     lp = (uint32_t *)(gdt_table + idx);
3372     entry_1 = tswap32(lp[0]);
3373     entry_2 = tswap32(lp[1]);
3374 
3375     read_exec_only = ((entry_2 >> 9) & 1) ^ 1;
3376     contents = (entry_2 >> 10) & 3;
3377     seg_not_present = ((entry_2 >> 15) & 1) ^ 1;
3378     seg_32bit = (entry_2 >> 22) & 1;
3379     limit_in_pages = (entry_2 >> 23) & 1;
3380     useable = (entry_2 >> 20) & 1;
3381 #ifdef TARGET_ABI32
3382     lm = 0;
3383 #else
3384     lm = (entry_2 >> 21) & 1;
3385 #endif
3386     flags = (seg_32bit << 0) | (contents << 1) |
3387         (read_exec_only << 3) | (limit_in_pages << 4) |
3388         (seg_not_present << 5) | (useable << 6) | (lm << 7);
3389     limit = (entry_1 & 0xffff) | (entry_2  & 0xf0000);
3390     base_addr = (entry_1 >> 16) |
3391         (entry_2 & 0xff000000) |
3392         ((entry_2 & 0xff) << 16);
3393     target_ldt_info->base_addr = tswapl(base_addr);
3394     target_ldt_info->limit = tswap32(limit);
3395     target_ldt_info->flags = tswap32(flags);
3396     unlock_user_struct(target_ldt_info, ptr, 1);
3397     return 0;
3398 }
3399 #endif /* TARGET_I386 && TARGET_ABI32 */
3400 
3401 #ifndef TARGET_ABI32
3402 static abi_long do_arch_prctl(CPUX86State *env, int code, abi_ulong addr)
3403 {
3404     abi_long ret;
3405     abi_ulong val;
3406     int idx;
3407 
3408     switch(code) {
3409     case TARGET_ARCH_SET_GS:
3410     case TARGET_ARCH_SET_FS:
3411         if (code == TARGET_ARCH_SET_GS)
3412             idx = R_GS;
3413         else
3414             idx = R_FS;
3415         cpu_x86_load_seg(env, idx, 0);
3416         env->segs[idx].base = addr;
3417         break;
3418     case TARGET_ARCH_GET_GS:
3419     case TARGET_ARCH_GET_FS:
3420         if (code == TARGET_ARCH_GET_GS)
3421             idx = R_GS;
3422         else
3423             idx = R_FS;
3424         val = env->segs[idx].base;
3425         if (put_user(val, addr, abi_ulong))
3426             return -TARGET_EFAULT;
3427         break;
3428     default:
3429         ret = -TARGET_EINVAL;
3430         break;
3431     }
3432     return 0;
3433 }
3434 #endif
3435 
3436 #endif /* defined(TARGET_I386) */
3437 
3438 #if defined(USE_NPTL)
3439 
3440 #define NEW_STACK_SIZE PTHREAD_STACK_MIN
3441 
3442 static pthread_mutex_t clone_lock = PTHREAD_MUTEX_INITIALIZER;
3443 typedef struct {
3444     CPUState *env;
3445     pthread_mutex_t mutex;
3446     pthread_cond_t cond;
3447     pthread_t thread;
3448     uint32_t tid;
3449     abi_ulong child_tidptr;
3450     abi_ulong parent_tidptr;
3451     sigset_t sigmask;
3452 } new_thread_info;
3453 
3454 static void *clone_func(void *arg)
3455 {
3456     new_thread_info *info = arg;
3457     CPUState *env;
3458     TaskState *ts;
3459 
3460     env = info->env;
3461     thread_env = env;
3462     ts = (TaskState *)thread_env->opaque;
3463     info->tid = gettid();
3464     env->host_tid = info->tid;
3465     task_settid(ts);
3466     if (info->child_tidptr)
3467         put_user_u32(info->tid, info->child_tidptr);
3468     if (info->parent_tidptr)
3469         put_user_u32(info->tid, info->parent_tidptr);
3470     /* Enable signals.  */
3471     sigprocmask(SIG_SETMASK, &info->sigmask, NULL);
3472     /* Signal to the parent that we're ready.  */
3473     pthread_mutex_lock(&info->mutex);
3474     pthread_cond_broadcast(&info->cond);
3475     pthread_mutex_unlock(&info->mutex);
3476     /* Wait until the parent has finshed initializing the tls state.  */
3477     pthread_mutex_lock(&clone_lock);
3478     pthread_mutex_unlock(&clone_lock);
3479     cpu_loop(env);
3480     /* never exits */
3481     return NULL;
3482 }
3483 #else
3484 /* this stack is the equivalent of the kernel stack associated with a
3485    thread/process */
3486 #define NEW_STACK_SIZE 8192
3487 
3488 static int clone_func(void *arg)
3489 {
3490     CPUState *env = arg;
3491     cpu_loop(env);
3492     /* never exits */
3493     return 0;
3494 }
3495 #endif
3496 
3497 /* do_fork() Must return host values and target errnos (unlike most
3498    do_*() functions). */
3499 static int do_fork(CPUState *env, unsigned int flags, abi_ulong newsp,
3500                    abi_ulong parent_tidptr, target_ulong newtls,
3501                    abi_ulong child_tidptr)
3502 {
3503     int ret;
3504     TaskState *ts;
3505     uint8_t *new_stack;
3506     CPUState *new_env;
3507 #if defined(USE_NPTL)
3508     unsigned int nptl_flags;
3509     sigset_t sigmask;
3510 #endif
3511 
3512     /* Emulate vfork() with fork() */
3513     if (flags & CLONE_VFORK)
3514         flags &= ~(CLONE_VFORK | CLONE_VM);
3515 
3516     if (flags & CLONE_VM) {
3517         TaskState *parent_ts = (TaskState *)env->opaque;
3518 #if defined(USE_NPTL)
3519         new_thread_info info;
3520         pthread_attr_t attr;
3521 #endif
3522         ts = qemu_mallocz(sizeof(TaskState) + NEW_STACK_SIZE);
3523         init_task_state(ts);
3524         new_stack = ts->stack;
3525         /* we create a new CPU instance. */
3526         new_env = cpu_copy(env);
3527         /* Init regs that differ from the parent.  */
3528         cpu_clone_regs(new_env, newsp);
3529         new_env->opaque = ts;
3530         ts->bprm = parent_ts->bprm;
3531         ts->info = parent_ts->info;
3532 #if defined(USE_NPTL)
3533         nptl_flags = flags;
3534         flags &= ~CLONE_NPTL_FLAGS2;
3535 
3536         if (nptl_flags & CLONE_CHILD_CLEARTID) {
3537             ts->child_tidptr = child_tidptr;
3538         }
3539 
3540         if (nptl_flags & CLONE_SETTLS)
3541             cpu_set_tls (new_env, newtls);
3542 
3543         /* Grab a mutex so that thread setup appears atomic.  */
3544         pthread_mutex_lock(&clone_lock);
3545 
3546         memset(&info, 0, sizeof(info));
3547         pthread_mutex_init(&info.mutex, NULL);
3548         pthread_mutex_lock(&info.mutex);
3549         pthread_cond_init(&info.cond, NULL);
3550         info.env = new_env;
3551         if (nptl_flags & CLONE_CHILD_SETTID)
3552             info.child_tidptr = child_tidptr;
3553         if (nptl_flags & CLONE_PARENT_SETTID)
3554             info.parent_tidptr = parent_tidptr;
3555 
3556         ret = pthread_attr_init(&attr);
3557         ret = pthread_attr_setstack(&attr, new_stack, NEW_STACK_SIZE);
3558         /* It is not safe to deliver signals until the child has finished
3559            initializing, so temporarily block all signals.  */
3560         sigfillset(&sigmask);
3561         sigprocmask(SIG_BLOCK, &sigmask, &info.sigmask);
3562 
3563         ret = pthread_create(&info.thread, &attr, clone_func, &info);
3564         /* TODO: Free new CPU state if thread creation failed.  */
3565 
3566         sigprocmask(SIG_SETMASK, &info.sigmask, NULL);
3567         pthread_attr_destroy(&attr);
3568         if (ret == 0) {
3569             /* Wait for the child to initialize.  */
3570             pthread_cond_wait(&info.cond, &info.mutex);
3571             ret = info.tid;
3572             if (flags & CLONE_PARENT_SETTID)
3573                 put_user_u32(ret, parent_tidptr);
3574         } else {
3575             ret = -1;
3576         }
3577         pthread_mutex_unlock(&info.mutex);
3578         pthread_cond_destroy(&info.cond);
3579         pthread_mutex_destroy(&info.mutex);
3580         pthread_mutex_unlock(&clone_lock);
3581 #else
3582         if (flags & CLONE_NPTL_FLAGS2)
3583             return -EINVAL;
3584         /* This is probably going to die very quickly, but do it anyway.  */
3585 #ifdef __ia64__
3586         ret = __clone2(clone_func, new_stack + NEW_STACK_SIZE, flags, new_env);
3587 #else
3588 	ret = clone(clone_func, new_stack + NEW_STACK_SIZE, flags, new_env);
3589 #endif
3590 #endif
3591     } else {
3592         /* if no CLONE_VM, we consider it is a fork */
3593         if ((flags & ~(CSIGNAL | CLONE_NPTL_FLAGS2)) != 0)
3594             return -EINVAL;
3595         fork_start();
3596         ret = fork();
3597         if (ret == 0) {
3598             /* Child Process.  */
3599             cpu_clone_regs(env, newsp);
3600             fork_end(1);
3601 #if defined(USE_NPTL)
3602             /* There is a race condition here.  The parent process could
3603                theoretically read the TID in the child process before the child
3604                tid is set.  This would require using either ptrace
3605                (not implemented) or having *_tidptr to point at a shared memory
3606                mapping.  We can't repeat the spinlock hack used above because
3607                the child process gets its own copy of the lock.  */
3608             if (flags & CLONE_CHILD_SETTID)
3609                 put_user_u32(gettid(), child_tidptr);
3610             if (flags & CLONE_PARENT_SETTID)
3611                 put_user_u32(gettid(), parent_tidptr);
3612             ts = (TaskState *)env->opaque;
3613             if (flags & CLONE_SETTLS)
3614                 cpu_set_tls (env, newtls);
3615             if (flags & CLONE_CHILD_CLEARTID)
3616                 ts->child_tidptr = child_tidptr;
3617 #endif
3618         } else {
3619             fork_end(0);
3620         }
3621     }
3622     return ret;
3623 }
3624 
3625 /* warning : doesn't handle linux specific flags... */
3626 static int target_to_host_fcntl_cmd(int cmd)
3627 {
3628     switch(cmd) {
3629 	case TARGET_F_DUPFD:
3630 	case TARGET_F_GETFD:
3631 	case TARGET_F_SETFD:
3632 	case TARGET_F_GETFL:
3633 	case TARGET_F_SETFL:
3634             return cmd;
3635         case TARGET_F_GETLK:
3636 	    return F_GETLK;
3637 	case TARGET_F_SETLK:
3638 	    return F_SETLK;
3639 	case TARGET_F_SETLKW:
3640 	    return F_SETLKW;
3641 	case TARGET_F_GETOWN:
3642 	    return F_GETOWN;
3643 	case TARGET_F_SETOWN:
3644 	    return F_SETOWN;
3645 	case TARGET_F_GETSIG:
3646 	    return F_GETSIG;
3647 	case TARGET_F_SETSIG:
3648 	    return F_SETSIG;
3649 #if TARGET_ABI_BITS == 32
3650         case TARGET_F_GETLK64:
3651 	    return F_GETLK64;
3652 	case TARGET_F_SETLK64:
3653 	    return F_SETLK64;
3654 	case TARGET_F_SETLKW64:
3655 	    return F_SETLKW64;
3656 #endif
3657 	default:
3658             return -TARGET_EINVAL;
3659     }
3660     return -TARGET_EINVAL;
3661 }
3662 
3663 static abi_long do_fcntl(int fd, int cmd, abi_ulong arg)
3664 {
3665     struct flock fl;
3666     struct target_flock *target_fl;
3667     struct flock64 fl64;
3668     struct target_flock64 *target_fl64;
3669     abi_long ret;
3670     int host_cmd = target_to_host_fcntl_cmd(cmd);
3671 
3672     if (host_cmd == -TARGET_EINVAL)
3673 	    return host_cmd;
3674 
3675     switch(cmd) {
3676     case TARGET_F_GETLK:
3677         if (!lock_user_struct(VERIFY_READ, target_fl, arg, 1))
3678             return -TARGET_EFAULT;
3679         fl.l_type = tswap16(target_fl->l_type);
3680         fl.l_whence = tswap16(target_fl->l_whence);
3681         fl.l_start = tswapl(target_fl->l_start);
3682         fl.l_len = tswapl(target_fl->l_len);
3683         fl.l_pid = tswapl(target_fl->l_pid);
3684         unlock_user_struct(target_fl, arg, 0);
3685         ret = get_errno(fcntl(fd, host_cmd, &fl));
3686         if (ret == 0) {
3687             if (!lock_user_struct(VERIFY_WRITE, target_fl, arg, 0))
3688                 return -TARGET_EFAULT;
3689             target_fl->l_type = tswap16(fl.l_type);
3690             target_fl->l_whence = tswap16(fl.l_whence);
3691             target_fl->l_start = tswapl(fl.l_start);
3692             target_fl->l_len = tswapl(fl.l_len);
3693             target_fl->l_pid = tswapl(fl.l_pid);
3694             unlock_user_struct(target_fl, arg, 1);
3695         }
3696         break;
3697 
3698     case TARGET_F_SETLK:
3699     case TARGET_F_SETLKW:
3700         if (!lock_user_struct(VERIFY_READ, target_fl, arg, 1))
3701             return -TARGET_EFAULT;
3702         fl.l_type = tswap16(target_fl->l_type);
3703         fl.l_whence = tswap16(target_fl->l_whence);
3704         fl.l_start = tswapl(target_fl->l_start);
3705         fl.l_len = tswapl(target_fl->l_len);
3706         fl.l_pid = tswapl(target_fl->l_pid);
3707         unlock_user_struct(target_fl, arg, 0);
3708         ret = get_errno(fcntl(fd, host_cmd, &fl));
3709         break;
3710 
3711     case TARGET_F_GETLK64:
3712         if (!lock_user_struct(VERIFY_READ, target_fl64, arg, 1))
3713             return -TARGET_EFAULT;
3714         fl64.l_type = tswap16(target_fl64->l_type) >> 1;
3715         fl64.l_whence = tswap16(target_fl64->l_whence);
3716         fl64.l_start = tswapl(target_fl64->l_start);
3717         fl64.l_len = tswapl(target_fl64->l_len);
3718         fl64.l_pid = tswap16(target_fl64->l_pid);
3719         unlock_user_struct(target_fl64, arg, 0);
3720         ret = get_errno(fcntl(fd, host_cmd, &fl64));
3721         if (ret == 0) {
3722             if (!lock_user_struct(VERIFY_WRITE, target_fl64, arg, 0))
3723                 return -TARGET_EFAULT;
3724             target_fl64->l_type = tswap16(fl64.l_type) >> 1;
3725             target_fl64->l_whence = tswap16(fl64.l_whence);
3726             target_fl64->l_start = tswapl(fl64.l_start);
3727             target_fl64->l_len = tswapl(fl64.l_len);
3728             target_fl64->l_pid = tswapl(fl64.l_pid);
3729             unlock_user_struct(target_fl64, arg, 1);
3730         }
3731         break;
3732     case TARGET_F_SETLK64:
3733     case TARGET_F_SETLKW64:
3734         if (!lock_user_struct(VERIFY_READ, target_fl64, arg, 1))
3735             return -TARGET_EFAULT;
3736         fl64.l_type = tswap16(target_fl64->l_type) >> 1;
3737         fl64.l_whence = tswap16(target_fl64->l_whence);
3738         fl64.l_start = tswapl(target_fl64->l_start);
3739         fl64.l_len = tswapl(target_fl64->l_len);
3740         fl64.l_pid = tswap16(target_fl64->l_pid);
3741         unlock_user_struct(target_fl64, arg, 0);
3742         ret = get_errno(fcntl(fd, host_cmd, &fl64));
3743         break;
3744 
3745     case TARGET_F_GETFL:
3746         ret = get_errno(fcntl(fd, host_cmd, arg));
3747         if (ret >= 0) {
3748             ret = host_to_target_bitmask(ret, fcntl_flags_tbl);
3749         }
3750         break;
3751 
3752     case TARGET_F_SETFL:
3753         ret = get_errno(fcntl(fd, host_cmd, target_to_host_bitmask(arg, fcntl_flags_tbl)));
3754         break;
3755 
3756     case TARGET_F_SETOWN:
3757     case TARGET_F_GETOWN:
3758     case TARGET_F_SETSIG:
3759     case TARGET_F_GETSIG:
3760         ret = get_errno(fcntl(fd, host_cmd, arg));
3761         break;
3762 
3763     default:
3764         ret = get_errno(fcntl(fd, cmd, arg));
3765         break;
3766     }
3767     return ret;
3768 }
3769 
3770 #ifdef USE_UID16
3771 
3772 static inline int high2lowuid(int uid)
3773 {
3774     if (uid > 65535)
3775         return 65534;
3776     else
3777         return uid;
3778 }
3779 
3780 static inline int high2lowgid(int gid)
3781 {
3782     if (gid > 65535)
3783         return 65534;
3784     else
3785         return gid;
3786 }
3787 
3788 static inline int low2highuid(int uid)
3789 {
3790     if ((int16_t)uid == -1)
3791         return -1;
3792     else
3793         return uid;
3794 }
3795 
3796 static inline int low2highgid(int gid)
3797 {
3798     if ((int16_t)gid == -1)
3799         return -1;
3800     else
3801         return gid;
3802 }
3803 
3804 #endif /* USE_UID16 */
3805 
3806 void syscall_init(void)
3807 {
3808     IOCTLEntry *ie;
3809     const argtype *arg_type;
3810     int size;
3811     int i;
3812 
3813 #define STRUCT(name, ...) thunk_register_struct(STRUCT_ ## name, #name, struct_ ## name ## _def);
3814 #define STRUCT_SPECIAL(name) thunk_register_struct_direct(STRUCT_ ## name, #name, &struct_ ## name ## _def);
3815 #include "syscall_types.h"
3816 #undef STRUCT
3817 #undef STRUCT_SPECIAL
3818 
3819     /* we patch the ioctl size if necessary. We rely on the fact that
3820        no ioctl has all the bits at '1' in the size field */
3821     ie = ioctl_entries;
3822     while (ie->target_cmd != 0) {
3823         if (((ie->target_cmd >> TARGET_IOC_SIZESHIFT) & TARGET_IOC_SIZEMASK) ==
3824             TARGET_IOC_SIZEMASK) {
3825             arg_type = ie->arg_type;
3826             if (arg_type[0] != TYPE_PTR) {
3827                 fprintf(stderr, "cannot patch size for ioctl 0x%x\n",
3828                         ie->target_cmd);
3829                 exit(1);
3830             }
3831             arg_type++;
3832             size = thunk_type_size(arg_type, 0);
3833             ie->target_cmd = (ie->target_cmd &
3834                               ~(TARGET_IOC_SIZEMASK << TARGET_IOC_SIZESHIFT)) |
3835                 (size << TARGET_IOC_SIZESHIFT);
3836         }
3837 
3838         /* Build target_to_host_errno_table[] table from
3839          * host_to_target_errno_table[]. */
3840         for (i=0; i < ERRNO_TABLE_SIZE; i++)
3841                 target_to_host_errno_table[host_to_target_errno_table[i]] = i;
3842 
3843         /* automatic consistency check if same arch */
3844 #if (defined(__i386__) && defined(TARGET_I386) && defined(TARGET_ABI32)) || \
3845     (defined(__x86_64__) && defined(TARGET_X86_64))
3846         if (unlikely(ie->target_cmd != ie->host_cmd)) {
3847             fprintf(stderr, "ERROR: ioctl(%s): target=0x%x host=0x%x\n",
3848                     ie->name, ie->target_cmd, ie->host_cmd);
3849         }
3850 #endif
3851         ie++;
3852     }
3853 }
3854 
3855 #if TARGET_ABI_BITS == 32
3856 static inline uint64_t target_offset64(uint32_t word0, uint32_t word1)
3857 {
3858 #ifdef TARGET_WORDS_BIGENDIAN
3859     return ((uint64_t)word0 << 32) | word1;
3860 #else
3861     return ((uint64_t)word1 << 32) | word0;
3862 #endif
3863 }
3864 #else /* TARGET_ABI_BITS == 32 */
3865 static inline uint64_t target_offset64(uint64_t word0, uint64_t word1)
3866 {
3867     return word0;
3868 }
3869 #endif /* TARGET_ABI_BITS != 32 */
3870 
3871 #ifdef TARGET_NR_truncate64
3872 static inline abi_long target_truncate64(void *cpu_env, const char *arg1,
3873                                          abi_long arg2,
3874                                          abi_long arg3,
3875                                          abi_long arg4)
3876 {
3877 #ifdef TARGET_ARM
3878     if (((CPUARMState *)cpu_env)->eabi)
3879       {
3880         arg2 = arg3;
3881         arg3 = arg4;
3882       }
3883 #endif
3884     return get_errno(truncate64(arg1, target_offset64(arg2, arg3)));
3885 }
3886 #endif
3887 
3888 #ifdef TARGET_NR_ftruncate64
3889 static inline abi_long target_ftruncate64(void *cpu_env, abi_long arg1,
3890                                           abi_long arg2,
3891                                           abi_long arg3,
3892                                           abi_long arg4)
3893 {
3894 #ifdef TARGET_ARM
3895     if (((CPUARMState *)cpu_env)->eabi)
3896       {
3897         arg2 = arg3;
3898         arg3 = arg4;
3899       }
3900 #endif
3901     return get_errno(ftruncate64(arg1, target_offset64(arg2, arg3)));
3902 }
3903 #endif
3904 
3905 static inline abi_long target_to_host_timespec(struct timespec *host_ts,
3906                                                abi_ulong target_addr)
3907 {
3908     struct target_timespec *target_ts;
3909 
3910     if (!lock_user_struct(VERIFY_READ, target_ts, target_addr, 1))
3911         return -TARGET_EFAULT;
3912     host_ts->tv_sec = tswapl(target_ts->tv_sec);
3913     host_ts->tv_nsec = tswapl(target_ts->tv_nsec);
3914     unlock_user_struct(target_ts, target_addr, 0);
3915     return 0;
3916 }
3917 
3918 static inline abi_long host_to_target_timespec(abi_ulong target_addr,
3919                                                struct timespec *host_ts)
3920 {
3921     struct target_timespec *target_ts;
3922 
3923     if (!lock_user_struct(VERIFY_WRITE, target_ts, target_addr, 0))
3924         return -TARGET_EFAULT;
3925     target_ts->tv_sec = tswapl(host_ts->tv_sec);
3926     target_ts->tv_nsec = tswapl(host_ts->tv_nsec);
3927     unlock_user_struct(target_ts, target_addr, 1);
3928     return 0;
3929 }
3930 
3931 #if defined(TARGET_NR_stat64) || defined(TARGET_NR_newfstatat)
3932 static inline abi_long host_to_target_stat64(void *cpu_env,
3933                                              abi_ulong target_addr,
3934                                              struct stat *host_st)
3935 {
3936 #ifdef TARGET_ARM
3937     if (((CPUARMState *)cpu_env)->eabi) {
3938         struct target_eabi_stat64 *target_st;
3939 
3940         if (!lock_user_struct(VERIFY_WRITE, target_st, target_addr, 0))
3941             return -TARGET_EFAULT;
3942         memset(target_st, 0, sizeof(struct target_eabi_stat64));
3943         __put_user(host_st->st_dev, &target_st->st_dev);
3944         __put_user(host_st->st_ino, &target_st->st_ino);
3945 #ifdef TARGET_STAT64_HAS_BROKEN_ST_INO
3946         __put_user(host_st->st_ino, &target_st->__st_ino);
3947 #endif
3948         __put_user(host_st->st_mode, &target_st->st_mode);
3949         __put_user(host_st->st_nlink, &target_st->st_nlink);
3950         __put_user(host_st->st_uid, &target_st->st_uid);
3951         __put_user(host_st->st_gid, &target_st->st_gid);
3952         __put_user(host_st->st_rdev, &target_st->st_rdev);
3953         __put_user(host_st->st_size, &target_st->st_size);
3954         __put_user(host_st->st_blksize, &target_st->st_blksize);
3955         __put_user(host_st->st_blocks, &target_st->st_blocks);
3956         __put_user(host_st->st_atime, &target_st->target_st_atime);
3957         __put_user(host_st->st_mtime, &target_st->target_st_mtime);
3958         __put_user(host_st->st_ctime, &target_st->target_st_ctime);
3959         unlock_user_struct(target_st, target_addr, 1);
3960     } else
3961 #endif
3962     {
3963 #if TARGET_LONG_BITS == 64
3964         struct target_stat *target_st;
3965 #else
3966         struct target_stat64 *target_st;
3967 #endif
3968 
3969         if (!lock_user_struct(VERIFY_WRITE, target_st, target_addr, 0))
3970             return -TARGET_EFAULT;
3971         memset(target_st, 0, sizeof(*target_st));
3972         __put_user(host_st->st_dev, &target_st->st_dev);
3973         __put_user(host_st->st_ino, &target_st->st_ino);
3974 #ifdef TARGET_STAT64_HAS_BROKEN_ST_INO
3975         __put_user(host_st->st_ino, &target_st->__st_ino);
3976 #endif
3977         __put_user(host_st->st_mode, &target_st->st_mode);
3978         __put_user(host_st->st_nlink, &target_st->st_nlink);
3979         __put_user(host_st->st_uid, &target_st->st_uid);
3980         __put_user(host_st->st_gid, &target_st->st_gid);
3981         __put_user(host_st->st_rdev, &target_st->st_rdev);
3982         /* XXX: better use of kernel struct */
3983         __put_user(host_st->st_size, &target_st->st_size);
3984         __put_user(host_st->st_blksize, &target_st->st_blksize);
3985         __put_user(host_st->st_blocks, &target_st->st_blocks);
3986         __put_user(host_st->st_atime, &target_st->target_st_atime);
3987         __put_user(host_st->st_mtime, &target_st->target_st_mtime);
3988         __put_user(host_st->st_ctime, &target_st->target_st_ctime);
3989         unlock_user_struct(target_st, target_addr, 1);
3990     }
3991 
3992     return 0;
3993 }
3994 #endif
3995 
3996 #if defined(USE_NPTL)
3997 /* ??? Using host futex calls even when target atomic operations
3998    are not really atomic probably breaks things.  However implementing
3999    futexes locally would make futexes shared between multiple processes
4000    tricky.  However they're probably useless because guest atomic
4001    operations won't work either.  */
4002 static int do_futex(target_ulong uaddr, int op, int val, target_ulong timeout,
4003                     target_ulong uaddr2, int val3)
4004 {
4005     struct timespec ts, *pts;
4006 
4007     /* ??? We assume FUTEX_* constants are the same on both host
4008        and target.  */
4009 #ifdef FUTEX_CMD_MASK
4010     switch ((op&FUTEX_CMD_MASK)) {
4011 #else
4012     switch (op) {
4013 #endif
4014     case FUTEX_WAIT:
4015         if (timeout) {
4016             pts = &ts;
4017             target_to_host_timespec(pts, timeout);
4018         } else {
4019             pts = NULL;
4020         }
4021         return get_errno(sys_futex(g2h(uaddr), op, tswap32(val),
4022                          pts, NULL, 0));
4023     case FUTEX_WAKE:
4024         return get_errno(sys_futex(g2h(uaddr), op, val, NULL, NULL, 0));
4025     case FUTEX_WAKE_OP:
4026         return get_errno(sys_futex(g2h(uaddr), op, val, NULL, g2h(uaddr2), val3 ));
4027     case FUTEX_FD:
4028         return get_errno(sys_futex(g2h(uaddr), op, val, NULL, NULL, 0));
4029     case FUTEX_REQUEUE:
4030         return get_errno(sys_futex(g2h(uaddr), op, val,
4031                          NULL, g2h(uaddr2), 0));
4032     case FUTEX_CMP_REQUEUE:
4033         return get_errno(sys_futex(g2h(uaddr), op, val,
4034                          NULL, g2h(uaddr2), tswap32(val3)));
4035     default:
4036         return -TARGET_ENOSYS;
4037     }
4038 }
4039 #endif
4040 
4041 /* Map host to target signal numbers for the wait family of syscalls.
4042    Assume all other status bits are the same.  */
4043 static int host_to_target_waitstatus(int status)
4044 {
4045     if (WIFSIGNALED(status)) {
4046         return host_to_target_signal(WTERMSIG(status)) | (status & ~0x7f);
4047     }
4048     if (WIFSTOPPED(status)) {
4049         return (host_to_target_signal(WSTOPSIG(status)) << 8)
4050                | (status & 0xff);
4051     }
4052     return status;
4053 }
4054 
4055 int get_osversion(void)
4056 {
4057     static int osversion;
4058     struct new_utsname buf;
4059     const char *s;
4060     int i, n, tmp;
4061     if (osversion)
4062         return osversion;
4063     if (qemu_uname_release && *qemu_uname_release) {
4064         s = qemu_uname_release;
4065     } else {
4066         if (sys_uname(&buf))
4067             return 0;
4068         s = buf.release;
4069     }
4070     tmp = 0;
4071     for (i = 0; i < 3; i++) {
4072         n = 0;
4073         while (*s >= '0' && *s <= '9') {
4074             n *= 10;
4075             n += *s - '0';
4076             s++;
4077         }
4078         tmp = (tmp << 8) + n;
4079         if (*s == '.')
4080             s++;
4081     }
4082     osversion = tmp;
4083     return osversion;
4084 }
4085 
4086 /* do_syscall() should always have a single exit point at the end so
4087    that actions, such as logging of syscall results, can be performed.
4088    All errnos that do_syscall() returns must be -TARGET_<errcode>. */
4089 abi_long do_syscall(void *cpu_env, int num, abi_long arg1,
4090                     abi_long arg2, abi_long arg3, abi_long arg4,
4091                     abi_long arg5, abi_long arg6)
4092 {
4093     abi_long ret;
4094     struct stat st;
4095     struct statfs stfs;
4096     void *p;
4097 
4098 #ifdef DEBUG
4099     gemu_log("syscall %d", num);
4100 #endif
4101     if(do_strace)
4102         print_syscall(num, arg1, arg2, arg3, arg4, arg5, arg6);
4103 
4104     switch(num) {
4105     case TARGET_NR_exit:
4106 #ifdef USE_NPTL
4107       /* In old applications this may be used to implement _exit(2).
4108          However in threaded applictions it is used for thread termination,
4109          and _exit_group is used for application termination.
4110          Do thread termination if we have more then one thread.  */
4111       /* FIXME: This probably breaks if a signal arrives.  We should probably
4112          be disabling signals.  */
4113       if (first_cpu->next_cpu) {
4114           TaskState *ts;
4115           CPUState **lastp;
4116           CPUState *p;
4117 
4118           cpu_list_lock();
4119           lastp = &first_cpu;
4120           p = first_cpu;
4121           while (p && p != (CPUState *)cpu_env) {
4122               lastp = &p->next_cpu;
4123               p = p->next_cpu;
4124           }
4125           /* If we didn't find the CPU for this thread then something is
4126              horribly wrong.  */
4127           if (!p)
4128               abort();
4129           /* Remove the CPU from the list.  */
4130           *lastp = p->next_cpu;
4131           cpu_list_unlock();
4132           ts = ((CPUState *)cpu_env)->opaque;
4133           if (ts->child_tidptr) {
4134               put_user_u32(0, ts->child_tidptr);
4135               sys_futex(g2h(ts->child_tidptr), FUTEX_WAKE, INT_MAX,
4136                         NULL, NULL, 0);
4137           }
4138           /* TODO: Free CPU state.  */
4139           pthread_exit(NULL);
4140       }
4141 #endif
4142 #ifdef HAVE_GPROF
4143         _mcleanup();
4144 #endif
4145         gdb_exit(cpu_env, arg1);
4146         _exit(arg1);
4147         ret = 0; /* avoid warning */
4148         break;
4149     case TARGET_NR_read:
4150         if (arg3 == 0)
4151             ret = 0;
4152         else {
4153             if (!(p = lock_user(VERIFY_WRITE, arg2, arg3, 0)))
4154                 goto efault;
4155             ret = get_errno(read(arg1, p, arg3));
4156             unlock_user(p, arg2, ret);
4157         }
4158         break;
4159     case TARGET_NR_write:
4160         if (!(p = lock_user(VERIFY_READ, arg2, arg3, 1)))
4161             goto efault;
4162         ret = get_errno(write(arg1, p, arg3));
4163         unlock_user(p, arg2, 0);
4164         break;
4165     case TARGET_NR_open:
4166         if (!(p = lock_user_string(arg1)))
4167             goto efault;
4168         ret = get_errno(open(path(p),
4169                              target_to_host_bitmask(arg2, fcntl_flags_tbl),
4170                              arg3));
4171         unlock_user(p, arg1, 0);
4172         break;
4173 #if defined(TARGET_NR_openat) && defined(__NR_openat)
4174     case TARGET_NR_openat:
4175         if (!(p = lock_user_string(arg2)))
4176             goto efault;
4177         ret = get_errno(sys_openat(arg1,
4178                                    path(p),
4179                                    target_to_host_bitmask(arg3, fcntl_flags_tbl),
4180                                    arg4));
4181         unlock_user(p, arg2, 0);
4182         break;
4183 #endif
4184     case TARGET_NR_close:
4185         ret = get_errno(close(arg1));
4186         break;
4187     case TARGET_NR_brk:
4188         ret = do_brk(arg1);
4189         break;
4190     case TARGET_NR_fork:
4191         ret = get_errno(do_fork(cpu_env, SIGCHLD, 0, 0, 0, 0));
4192         break;
4193 #ifdef TARGET_NR_waitpid
4194     case TARGET_NR_waitpid:
4195         {
4196             int status;
4197             ret = get_errno(waitpid(arg1, &status, arg3));
4198             if (!is_error(ret) && arg2
4199                 && put_user_s32(host_to_target_waitstatus(status), arg2))
4200                 goto efault;
4201         }
4202         break;
4203 #endif
4204 #ifdef TARGET_NR_waitid
4205     case TARGET_NR_waitid:
4206         {
4207             siginfo_t info;
4208             info.si_pid = 0;
4209             ret = get_errno(waitid(arg1, arg2, &info, arg4));
4210             if (!is_error(ret) && arg3 && info.si_pid != 0) {
4211                 if (!(p = lock_user(VERIFY_WRITE, arg3, sizeof(target_siginfo_t), 0)))
4212                     goto efault;
4213                 host_to_target_siginfo(p, &info);
4214                 unlock_user(p, arg3, sizeof(target_siginfo_t));
4215             }
4216         }
4217         break;
4218 #endif
4219 #ifdef TARGET_NR_creat /* not on alpha */
4220     case TARGET_NR_creat:
4221         if (!(p = lock_user_string(arg1)))
4222             goto efault;
4223         ret = get_errno(creat(p, arg2));
4224         unlock_user(p, arg1, 0);
4225         break;
4226 #endif
4227     case TARGET_NR_link:
4228         {
4229             void * p2;
4230             p = lock_user_string(arg1);
4231             p2 = lock_user_string(arg2);
4232             if (!p || !p2)
4233                 ret = -TARGET_EFAULT;
4234             else
4235                 ret = get_errno(link(p, p2));
4236             unlock_user(p2, arg2, 0);
4237             unlock_user(p, arg1, 0);
4238         }
4239         break;
4240 #if defined(TARGET_NR_linkat) && defined(__NR_linkat)
4241     case TARGET_NR_linkat:
4242         {
4243             void * p2 = NULL;
4244             if (!arg2 || !arg4)
4245                 goto efault;
4246             p  = lock_user_string(arg2);
4247             p2 = lock_user_string(arg4);
4248             if (!p || !p2)
4249                 ret = -TARGET_EFAULT;
4250             else
4251                 ret = get_errno(sys_linkat(arg1, p, arg3, p2, arg5));
4252             unlock_user(p, arg2, 0);
4253             unlock_user(p2, arg4, 0);
4254         }
4255         break;
4256 #endif
4257     case TARGET_NR_unlink:
4258         if (!(p = lock_user_string(arg1)))
4259             goto efault;
4260         ret = get_errno(unlink(p));
4261         unlock_user(p, arg1, 0);
4262         break;
4263 #if defined(TARGET_NR_unlinkat) && defined(__NR_unlinkat)
4264     case TARGET_NR_unlinkat:
4265         if (!(p = lock_user_string(arg2)))
4266             goto efault;
4267         ret = get_errno(sys_unlinkat(arg1, p, arg3));
4268         unlock_user(p, arg2, 0);
4269         break;
4270 #endif
4271     case TARGET_NR_execve:
4272         {
4273             char **argp, **envp;
4274             int argc, envc;
4275             abi_ulong gp;
4276             abi_ulong guest_argp;
4277             abi_ulong guest_envp;
4278             abi_ulong addr;
4279             char **q;
4280 
4281             argc = 0;
4282             guest_argp = arg2;
4283             for (gp = guest_argp; gp; gp += sizeof(abi_ulong)) {
4284                 if (get_user_ual(addr, gp))
4285                     goto efault;
4286                 if (!addr)
4287                     break;
4288                 argc++;
4289             }
4290             envc = 0;
4291             guest_envp = arg3;
4292             for (gp = guest_envp; gp; gp += sizeof(abi_ulong)) {
4293                 if (get_user_ual(addr, gp))
4294                     goto efault;
4295                 if (!addr)
4296                     break;
4297                 envc++;
4298             }
4299 
4300             argp = alloca((argc + 1) * sizeof(void *));
4301             envp = alloca((envc + 1) * sizeof(void *));
4302 
4303             for (gp = guest_argp, q = argp; gp;
4304                   gp += sizeof(abi_ulong), q++) {
4305                 if (get_user_ual(addr, gp))
4306                     goto execve_efault;
4307                 if (!addr)
4308                     break;
4309                 if (!(*q = lock_user_string(addr)))
4310                     goto execve_efault;
4311             }
4312             *q = NULL;
4313 
4314             for (gp = guest_envp, q = envp; gp;
4315                   gp += sizeof(abi_ulong), q++) {
4316                 if (get_user_ual(addr, gp))
4317                     goto execve_efault;
4318                 if (!addr)
4319                     break;
4320                 if (!(*q = lock_user_string(addr)))
4321                     goto execve_efault;
4322             }
4323             *q = NULL;
4324 
4325             if (!(p = lock_user_string(arg1)))
4326                 goto execve_efault;
4327             ret = get_errno(execve(p, argp, envp));
4328             unlock_user(p, arg1, 0);
4329 
4330             goto execve_end;
4331 
4332         execve_efault:
4333             ret = -TARGET_EFAULT;
4334 
4335         execve_end:
4336             for (gp = guest_argp, q = argp; *q;
4337                   gp += sizeof(abi_ulong), q++) {
4338                 if (get_user_ual(addr, gp)
4339                     || !addr)
4340                     break;
4341                 unlock_user(*q, addr, 0);
4342             }
4343             for (gp = guest_envp, q = envp; *q;
4344                   gp += sizeof(abi_ulong), q++) {
4345                 if (get_user_ual(addr, gp)
4346                     || !addr)
4347                     break;
4348                 unlock_user(*q, addr, 0);
4349             }
4350         }
4351         break;
4352     case TARGET_NR_chdir:
4353         if (!(p = lock_user_string(arg1)))
4354             goto efault;
4355         ret = get_errno(chdir(p));
4356         unlock_user(p, arg1, 0);
4357         break;
4358 #ifdef TARGET_NR_time
4359     case TARGET_NR_time:
4360         {
4361             time_t host_time;
4362             ret = get_errno(time(&host_time));
4363             if (!is_error(ret)
4364                 && arg1
4365                 && put_user_sal(host_time, arg1))
4366                 goto efault;
4367         }
4368         break;
4369 #endif
4370     case TARGET_NR_mknod:
4371         if (!(p = lock_user_string(arg1)))
4372             goto efault;
4373         ret = get_errno(mknod(p, arg2, arg3));
4374         unlock_user(p, arg1, 0);
4375         break;
4376 #if defined(TARGET_NR_mknodat) && defined(__NR_mknodat)
4377     case TARGET_NR_mknodat:
4378         if (!(p = lock_user_string(arg2)))
4379             goto efault;
4380         ret = get_errno(sys_mknodat(arg1, p, arg3, arg4));
4381         unlock_user(p, arg2, 0);
4382         break;
4383 #endif
4384     case TARGET_NR_chmod:
4385         if (!(p = lock_user_string(arg1)))
4386             goto efault;
4387         ret = get_errno(chmod(p, arg2));
4388         unlock_user(p, arg1, 0);
4389         break;
4390 #ifdef TARGET_NR_break
4391     case TARGET_NR_break:
4392         goto unimplemented;
4393 #endif
4394 #ifdef TARGET_NR_oldstat
4395     case TARGET_NR_oldstat:
4396         goto unimplemented;
4397 #endif
4398     case TARGET_NR_lseek:
4399         ret = get_errno(lseek(arg1, arg2, arg3));
4400         break;
4401 #ifdef TARGET_NR_getxpid
4402     case TARGET_NR_getxpid:
4403 #else
4404     case TARGET_NR_getpid:
4405 #endif
4406         ret = get_errno(getpid());
4407         break;
4408     case TARGET_NR_mount:
4409 		{
4410 			/* need to look at the data field */
4411 			void *p2, *p3;
4412 			p = lock_user_string(arg1);
4413 			p2 = lock_user_string(arg2);
4414 			p3 = lock_user_string(arg3);
4415                         if (!p || !p2 || !p3)
4416                             ret = -TARGET_EFAULT;
4417                         else
4418                             /* FIXME - arg5 should be locked, but it isn't clear how to
4419                              * do that since it's not guaranteed to be a NULL-terminated
4420                              * string.
4421                              */
4422                             ret = get_errno(mount(p, p2, p3, (unsigned long)arg4, g2h(arg5)));
4423                         unlock_user(p, arg1, 0);
4424                         unlock_user(p2, arg2, 0);
4425                         unlock_user(p3, arg3, 0);
4426 			break;
4427 		}
4428 #ifdef TARGET_NR_umount
4429     case TARGET_NR_umount:
4430         if (!(p = lock_user_string(arg1)))
4431             goto efault;
4432         ret = get_errno(umount(p));
4433         unlock_user(p, arg1, 0);
4434         break;
4435 #endif
4436 #ifdef TARGET_NR_stime /* not on alpha */
4437     case TARGET_NR_stime:
4438         {
4439             time_t host_time;
4440             if (get_user_sal(host_time, arg1))
4441                 goto efault;
4442             ret = get_errno(stime(&host_time));
4443         }
4444         break;
4445 #endif
4446     case TARGET_NR_ptrace:
4447         goto unimplemented;
4448 #ifdef TARGET_NR_alarm /* not on alpha */
4449     case TARGET_NR_alarm:
4450         ret = alarm(arg1);
4451         break;
4452 #endif
4453 #ifdef TARGET_NR_oldfstat
4454     case TARGET_NR_oldfstat:
4455         goto unimplemented;
4456 #endif
4457 #ifdef TARGET_NR_pause /* not on alpha */
4458     case TARGET_NR_pause:
4459         ret = get_errno(pause());
4460         break;
4461 #endif
4462 #ifdef TARGET_NR_utime
4463     case TARGET_NR_utime:
4464         {
4465             struct utimbuf tbuf, *host_tbuf;
4466             struct target_utimbuf *target_tbuf;
4467             if (arg2) {
4468                 if (!lock_user_struct(VERIFY_READ, target_tbuf, arg2, 1))
4469                     goto efault;
4470                 tbuf.actime = tswapl(target_tbuf->actime);
4471                 tbuf.modtime = tswapl(target_tbuf->modtime);
4472                 unlock_user_struct(target_tbuf, arg2, 0);
4473                 host_tbuf = &tbuf;
4474             } else {
4475                 host_tbuf = NULL;
4476             }
4477             if (!(p = lock_user_string(arg1)))
4478                 goto efault;
4479             ret = get_errno(utime(p, host_tbuf));
4480             unlock_user(p, arg1, 0);
4481         }
4482         break;
4483 #endif
4484     case TARGET_NR_utimes:
4485         {
4486             struct timeval *tvp, tv[2];
4487             if (arg2) {
4488                 if (copy_from_user_timeval(&tv[0], arg2)
4489                     || copy_from_user_timeval(&tv[1],
4490                                               arg2 + sizeof(struct target_timeval)))
4491                     goto efault;
4492                 tvp = tv;
4493             } else {
4494                 tvp = NULL;
4495             }
4496             if (!(p = lock_user_string(arg1)))
4497                 goto efault;
4498             ret = get_errno(utimes(p, tvp));
4499             unlock_user(p, arg1, 0);
4500         }
4501         break;
4502 #if defined(TARGET_NR_futimesat) && defined(__NR_futimesat)
4503     case TARGET_NR_futimesat:
4504         {
4505             struct timeval *tvp, tv[2];
4506             if (arg3) {
4507                 if (copy_from_user_timeval(&tv[0], arg3)
4508                     || copy_from_user_timeval(&tv[1],
4509                                               arg3 + sizeof(struct target_timeval)))
4510                     goto efault;
4511                 tvp = tv;
4512             } else {
4513                 tvp = NULL;
4514             }
4515             if (!(p = lock_user_string(arg2)))
4516                 goto efault;
4517             ret = get_errno(sys_futimesat(arg1, path(p), tvp));
4518             unlock_user(p, arg2, 0);
4519         }
4520         break;
4521 #endif
4522 #ifdef TARGET_NR_stty
4523     case TARGET_NR_stty:
4524         goto unimplemented;
4525 #endif
4526 #ifdef TARGET_NR_gtty
4527     case TARGET_NR_gtty:
4528         goto unimplemented;
4529 #endif
4530     case TARGET_NR_access:
4531         if (!(p = lock_user_string(arg1)))
4532             goto efault;
4533         ret = get_errno(access(p, arg2));
4534         unlock_user(p, arg1, 0);
4535         break;
4536 #if defined(TARGET_NR_faccessat) && defined(__NR_faccessat)
4537     case TARGET_NR_faccessat:
4538         if (!(p = lock_user_string(arg2)))
4539             goto efault;
4540         ret = get_errno(sys_faccessat(arg1, p, arg3));
4541         unlock_user(p, arg2, 0);
4542         break;
4543 #endif
4544 #ifdef TARGET_NR_nice /* not on alpha */
4545     case TARGET_NR_nice:
4546         ret = get_errno(nice(arg1));
4547         break;
4548 #endif
4549 #ifdef TARGET_NR_ftime
4550     case TARGET_NR_ftime:
4551         goto unimplemented;
4552 #endif
4553     case TARGET_NR_sync:
4554         sync();
4555         ret = 0;
4556         break;
4557     case TARGET_NR_kill:
4558         ret = get_errno(kill(arg1, target_to_host_signal(arg2)));
4559         break;
4560     case TARGET_NR_rename:
4561         {
4562             void *p2;
4563             p = lock_user_string(arg1);
4564             p2 = lock_user_string(arg2);
4565             if (!p || !p2)
4566                 ret = -TARGET_EFAULT;
4567             else
4568                 ret = get_errno(rename(p, p2));
4569             unlock_user(p2, arg2, 0);
4570             unlock_user(p, arg1, 0);
4571         }
4572         break;
4573 #if defined(TARGET_NR_renameat) && defined(__NR_renameat)
4574     case TARGET_NR_renameat:
4575         {
4576             void *p2;
4577             p  = lock_user_string(arg2);
4578             p2 = lock_user_string(arg4);
4579             if (!p || !p2)
4580                 ret = -TARGET_EFAULT;
4581             else
4582                 ret = get_errno(sys_renameat(arg1, p, arg3, p2));
4583             unlock_user(p2, arg4, 0);
4584             unlock_user(p, arg2, 0);
4585         }
4586         break;
4587 #endif
4588     case TARGET_NR_mkdir:
4589         if (!(p = lock_user_string(arg1)))
4590             goto efault;
4591         ret = get_errno(mkdir(p, arg2));
4592         unlock_user(p, arg1, 0);
4593         break;
4594 #if defined(TARGET_NR_mkdirat) && defined(__NR_mkdirat)
4595     case TARGET_NR_mkdirat:
4596         if (!(p = lock_user_string(arg2)))
4597             goto efault;
4598         ret = get_errno(sys_mkdirat(arg1, p, arg3));
4599         unlock_user(p, arg2, 0);
4600         break;
4601 #endif
4602     case TARGET_NR_rmdir:
4603         if (!(p = lock_user_string(arg1)))
4604             goto efault;
4605         ret = get_errno(rmdir(p));
4606         unlock_user(p, arg1, 0);
4607         break;
4608     case TARGET_NR_dup:
4609         ret = get_errno(dup(arg1));
4610         break;
4611     case TARGET_NR_pipe:
4612         ret = do_pipe(cpu_env, arg1, 0);
4613         break;
4614 #ifdef TARGET_NR_pipe2
4615     case TARGET_NR_pipe2:
4616         ret = do_pipe(cpu_env, arg1, arg2);
4617         break;
4618 #endif
4619     case TARGET_NR_times:
4620         {
4621             struct target_tms *tmsp;
4622             struct tms tms;
4623             ret = get_errno(times(&tms));
4624             if (arg1) {
4625                 tmsp = lock_user(VERIFY_WRITE, arg1, sizeof(struct target_tms), 0);
4626                 if (!tmsp)
4627                     goto efault;
4628                 tmsp->tms_utime = tswapl(host_to_target_clock_t(tms.tms_utime));
4629                 tmsp->tms_stime = tswapl(host_to_target_clock_t(tms.tms_stime));
4630                 tmsp->tms_cutime = tswapl(host_to_target_clock_t(tms.tms_cutime));
4631                 tmsp->tms_cstime = tswapl(host_to_target_clock_t(tms.tms_cstime));
4632             }
4633             if (!is_error(ret))
4634                 ret = host_to_target_clock_t(ret);
4635         }
4636         break;
4637 #ifdef TARGET_NR_prof
4638     case TARGET_NR_prof:
4639         goto unimplemented;
4640 #endif
4641 #ifdef TARGET_NR_signal
4642     case TARGET_NR_signal:
4643         goto unimplemented;
4644 #endif
4645     case TARGET_NR_acct:
4646         if (arg1 == 0) {
4647             ret = get_errno(acct(NULL));
4648         } else {
4649             if (!(p = lock_user_string(arg1)))
4650                 goto efault;
4651             ret = get_errno(acct(path(p)));
4652             unlock_user(p, arg1, 0);
4653         }
4654         break;
4655 #ifdef TARGET_NR_umount2 /* not on alpha */
4656     case TARGET_NR_umount2:
4657         if (!(p = lock_user_string(arg1)))
4658             goto efault;
4659         ret = get_errno(umount2(p, arg2));
4660         unlock_user(p, arg1, 0);
4661         break;
4662 #endif
4663 #ifdef TARGET_NR_lock
4664     case TARGET_NR_lock:
4665         goto unimplemented;
4666 #endif
4667     case TARGET_NR_ioctl:
4668         ret = do_ioctl(arg1, arg2, arg3);
4669         break;
4670     case TARGET_NR_fcntl:
4671         ret = do_fcntl(arg1, arg2, arg3);
4672         break;
4673 #ifdef TARGET_NR_mpx
4674     case TARGET_NR_mpx:
4675         goto unimplemented;
4676 #endif
4677     case TARGET_NR_setpgid:
4678         ret = get_errno(setpgid(arg1, arg2));
4679         break;
4680 #ifdef TARGET_NR_ulimit
4681     case TARGET_NR_ulimit:
4682         goto unimplemented;
4683 #endif
4684 #ifdef TARGET_NR_oldolduname
4685     case TARGET_NR_oldolduname:
4686         goto unimplemented;
4687 #endif
4688     case TARGET_NR_umask:
4689         ret = get_errno(umask(arg1));
4690         break;
4691     case TARGET_NR_chroot:
4692         if (!(p = lock_user_string(arg1)))
4693             goto efault;
4694         ret = get_errno(chroot(p));
4695         unlock_user(p, arg1, 0);
4696         break;
4697     case TARGET_NR_ustat:
4698         goto unimplemented;
4699     case TARGET_NR_dup2:
4700         ret = get_errno(dup2(arg1, arg2));
4701         break;
4702 #ifdef TARGET_NR_getppid /* not on alpha */
4703     case TARGET_NR_getppid:
4704         ret = get_errno(getppid());
4705         break;
4706 #endif
4707     case TARGET_NR_getpgrp:
4708         ret = get_errno(getpgrp());
4709         break;
4710     case TARGET_NR_setsid:
4711         ret = get_errno(setsid());
4712         break;
4713 #ifdef TARGET_NR_sigaction
4714     case TARGET_NR_sigaction:
4715         {
4716 #if !defined(TARGET_MIPS)
4717             struct target_old_sigaction *old_act;
4718             struct target_sigaction act, oact, *pact;
4719             if (arg2) {
4720                 if (!lock_user_struct(VERIFY_READ, old_act, arg2, 1))
4721                     goto efault;
4722                 act._sa_handler = old_act->_sa_handler;
4723                 target_siginitset(&act.sa_mask, old_act->sa_mask);
4724                 act.sa_flags = old_act->sa_flags;
4725                 act.sa_restorer = old_act->sa_restorer;
4726                 unlock_user_struct(old_act, arg2, 0);
4727                 pact = &act;
4728             } else {
4729                 pact = NULL;
4730             }
4731             ret = get_errno(do_sigaction(arg1, pact, &oact));
4732             if (!is_error(ret) && arg3) {
4733                 if (!lock_user_struct(VERIFY_WRITE, old_act, arg3, 0))
4734                     goto efault;
4735                 old_act->_sa_handler = oact._sa_handler;
4736                 old_act->sa_mask = oact.sa_mask.sig[0];
4737                 old_act->sa_flags = oact.sa_flags;
4738                 old_act->sa_restorer = oact.sa_restorer;
4739                 unlock_user_struct(old_act, arg3, 1);
4740             }
4741 #else
4742 	    struct target_sigaction act, oact, *pact, *old_act;
4743 
4744 	    if (arg2) {
4745                 if (!lock_user_struct(VERIFY_READ, old_act, arg2, 1))
4746                     goto efault;
4747 		act._sa_handler = old_act->_sa_handler;
4748 		target_siginitset(&act.sa_mask, old_act->sa_mask.sig[0]);
4749 		act.sa_flags = old_act->sa_flags;
4750 		unlock_user_struct(old_act, arg2, 0);
4751 		pact = &act;
4752 	    } else {
4753 		pact = NULL;
4754 	    }
4755 
4756 	    ret = get_errno(do_sigaction(arg1, pact, &oact));
4757 
4758 	    if (!is_error(ret) && arg3) {
4759                 if (!lock_user_struct(VERIFY_WRITE, old_act, arg3, 0))
4760                     goto efault;
4761 		old_act->_sa_handler = oact._sa_handler;
4762 		old_act->sa_flags = oact.sa_flags;
4763 		old_act->sa_mask.sig[0] = oact.sa_mask.sig[0];
4764 		old_act->sa_mask.sig[1] = 0;
4765 		old_act->sa_mask.sig[2] = 0;
4766 		old_act->sa_mask.sig[3] = 0;
4767 		unlock_user_struct(old_act, arg3, 1);
4768 	    }
4769 #endif
4770         }
4771         break;
4772 #endif
4773     case TARGET_NR_rt_sigaction:
4774         {
4775             struct target_sigaction *act;
4776             struct target_sigaction *oact;
4777 
4778             if (arg2) {
4779                 if (!lock_user_struct(VERIFY_READ, act, arg2, 1))
4780                     goto efault;
4781             } else
4782                 act = NULL;
4783             if (arg3) {
4784                 if (!lock_user_struct(VERIFY_WRITE, oact, arg3, 0)) {
4785                     ret = -TARGET_EFAULT;
4786                     goto rt_sigaction_fail;
4787                 }
4788             } else
4789                 oact = NULL;
4790             ret = get_errno(do_sigaction(arg1, act, oact));
4791 	rt_sigaction_fail:
4792             if (act)
4793                 unlock_user_struct(act, arg2, 0);
4794             if (oact)
4795                 unlock_user_struct(oact, arg3, 1);
4796         }
4797         break;
4798 #ifdef TARGET_NR_sgetmask /* not on alpha */
4799     case TARGET_NR_sgetmask:
4800         {
4801             sigset_t cur_set;
4802             abi_ulong target_set;
4803             sigprocmask(0, NULL, &cur_set);
4804             host_to_target_old_sigset(&target_set, &cur_set);
4805             ret = target_set;
4806         }
4807         break;
4808 #endif
4809 #ifdef TARGET_NR_ssetmask /* not on alpha */
4810     case TARGET_NR_ssetmask:
4811         {
4812             sigset_t set, oset, cur_set;
4813             abi_ulong target_set = arg1;
4814             sigprocmask(0, NULL, &cur_set);
4815             target_to_host_old_sigset(&set, &target_set);
4816             sigorset(&set, &set, &cur_set);
4817             sigprocmask(SIG_SETMASK, &set, &oset);
4818             host_to_target_old_sigset(&target_set, &oset);
4819             ret = target_set;
4820         }
4821         break;
4822 #endif
4823 #ifdef TARGET_NR_sigprocmask
4824     case TARGET_NR_sigprocmask:
4825         {
4826             int how = arg1;
4827             sigset_t set, oldset, *set_ptr;
4828 
4829             if (arg2) {
4830                 switch(how) {
4831                 case TARGET_SIG_BLOCK:
4832                     how = SIG_BLOCK;
4833                     break;
4834                 case TARGET_SIG_UNBLOCK:
4835                     how = SIG_UNBLOCK;
4836                     break;
4837                 case TARGET_SIG_SETMASK:
4838                     how = SIG_SETMASK;
4839                     break;
4840                 default:
4841                     ret = -TARGET_EINVAL;
4842                     goto fail;
4843                 }
4844                 if (!(p = lock_user(VERIFY_READ, arg2, sizeof(target_sigset_t), 1)))
4845                     goto efault;
4846                 target_to_host_old_sigset(&set, p);
4847                 unlock_user(p, arg2, 0);
4848                 set_ptr = &set;
4849             } else {
4850                 how = 0;
4851                 set_ptr = NULL;
4852             }
4853             ret = get_errno(sigprocmask(arg1, set_ptr, &oldset));
4854             if (!is_error(ret) && arg3) {
4855                 if (!(p = lock_user(VERIFY_WRITE, arg3, sizeof(target_sigset_t), 0)))
4856                     goto efault;
4857                 host_to_target_old_sigset(p, &oldset);
4858                 unlock_user(p, arg3, sizeof(target_sigset_t));
4859             }
4860         }
4861         break;
4862 #endif
4863     case TARGET_NR_rt_sigprocmask:
4864         {
4865             int how = arg1;
4866             sigset_t set, oldset, *set_ptr;
4867 
4868             if (arg2) {
4869                 switch(how) {
4870                 case TARGET_SIG_BLOCK:
4871                     how = SIG_BLOCK;
4872                     break;
4873                 case TARGET_SIG_UNBLOCK:
4874                     how = SIG_UNBLOCK;
4875                     break;
4876                 case TARGET_SIG_SETMASK:
4877                     how = SIG_SETMASK;
4878                     break;
4879                 default:
4880                     ret = -TARGET_EINVAL;
4881                     goto fail;
4882                 }
4883                 if (!(p = lock_user(VERIFY_READ, arg2, sizeof(target_sigset_t), 1)))
4884                     goto efault;
4885                 target_to_host_sigset(&set, p);
4886                 unlock_user(p, arg2, 0);
4887                 set_ptr = &set;
4888             } else {
4889                 how = 0;
4890                 set_ptr = NULL;
4891             }
4892             ret = get_errno(sigprocmask(how, set_ptr, &oldset));
4893             if (!is_error(ret) && arg3) {
4894                 if (!(p = lock_user(VERIFY_WRITE, arg3, sizeof(target_sigset_t), 0)))
4895                     goto efault;
4896                 host_to_target_sigset(p, &oldset);
4897                 unlock_user(p, arg3, sizeof(target_sigset_t));
4898             }
4899         }
4900         break;
4901 #ifdef TARGET_NR_sigpending
4902     case TARGET_NR_sigpending:
4903         {
4904             sigset_t set;
4905             ret = get_errno(sigpending(&set));
4906             if (!is_error(ret)) {
4907                 if (!(p = lock_user(VERIFY_WRITE, arg1, sizeof(target_sigset_t), 0)))
4908                     goto efault;
4909                 host_to_target_old_sigset(p, &set);
4910                 unlock_user(p, arg1, sizeof(target_sigset_t));
4911             }
4912         }
4913         break;
4914 #endif
4915     case TARGET_NR_rt_sigpending:
4916         {
4917             sigset_t set;
4918             ret = get_errno(sigpending(&set));
4919             if (!is_error(ret)) {
4920                 if (!(p = lock_user(VERIFY_WRITE, arg1, sizeof(target_sigset_t), 0)))
4921                     goto efault;
4922                 host_to_target_sigset(p, &set);
4923                 unlock_user(p, arg1, sizeof(target_sigset_t));
4924             }
4925         }
4926         break;
4927 #ifdef TARGET_NR_sigsuspend
4928     case TARGET_NR_sigsuspend:
4929         {
4930             sigset_t set;
4931             if (!(p = lock_user(VERIFY_READ, arg1, sizeof(target_sigset_t), 1)))
4932                 goto efault;
4933             target_to_host_old_sigset(&set, p);
4934             unlock_user(p, arg1, 0);
4935             ret = get_errno(sigsuspend(&set));
4936         }
4937         break;
4938 #endif
4939     case TARGET_NR_rt_sigsuspend:
4940         {
4941             sigset_t set;
4942             if (!(p = lock_user(VERIFY_READ, arg1, sizeof(target_sigset_t), 1)))
4943                 goto efault;
4944             target_to_host_sigset(&set, p);
4945             unlock_user(p, arg1, 0);
4946             ret = get_errno(sigsuspend(&set));
4947         }
4948         break;
4949     case TARGET_NR_rt_sigtimedwait:
4950         {
4951             sigset_t set;
4952             struct timespec uts, *puts;
4953             siginfo_t uinfo;
4954 
4955             if (!(p = lock_user(VERIFY_READ, arg1, sizeof(target_sigset_t), 1)))
4956                 goto efault;
4957             target_to_host_sigset(&set, p);
4958             unlock_user(p, arg1, 0);
4959             if (arg3) {
4960                 puts = &uts;
4961                 target_to_host_timespec(puts, arg3);
4962             } else {
4963                 puts = NULL;
4964             }
4965             ret = get_errno(sigtimedwait(&set, &uinfo, puts));
4966             if (!is_error(ret) && arg2) {
4967                 if (!(p = lock_user(VERIFY_WRITE, arg2, sizeof(target_siginfo_t), 0)))
4968                     goto efault;
4969                 host_to_target_siginfo(p, &uinfo);
4970                 unlock_user(p, arg2, sizeof(target_siginfo_t));
4971             }
4972         }
4973         break;
4974     case TARGET_NR_rt_sigqueueinfo:
4975         {
4976             siginfo_t uinfo;
4977             if (!(p = lock_user(VERIFY_READ, arg3, sizeof(target_sigset_t), 1)))
4978                 goto efault;
4979             target_to_host_siginfo(&uinfo, p);
4980             unlock_user(p, arg1, 0);
4981             ret = get_errno(sys_rt_sigqueueinfo(arg1, arg2, &uinfo));
4982         }
4983         break;
4984 #ifdef TARGET_NR_sigreturn
4985     case TARGET_NR_sigreturn:
4986         /* NOTE: ret is eax, so not transcoding must be done */
4987         ret = do_sigreturn(cpu_env);
4988         break;
4989 #endif
4990     case TARGET_NR_rt_sigreturn:
4991         /* NOTE: ret is eax, so not transcoding must be done */
4992         ret = do_rt_sigreturn(cpu_env);
4993         break;
4994     case TARGET_NR_sethostname:
4995         if (!(p = lock_user_string(arg1)))
4996             goto efault;
4997         ret = get_errno(sethostname(p, arg2));
4998         unlock_user(p, arg1, 0);
4999         break;
5000     case TARGET_NR_setrlimit:
5001         {
5002             /* XXX: convert resource ? */
5003             int resource = arg1;
5004             struct target_rlimit *target_rlim;
5005             struct rlimit rlim;
5006             if (!lock_user_struct(VERIFY_READ, target_rlim, arg2, 1))
5007                 goto efault;
5008             rlim.rlim_cur = tswapl(target_rlim->rlim_cur);
5009             rlim.rlim_max = tswapl(target_rlim->rlim_max);
5010             unlock_user_struct(target_rlim, arg2, 0);
5011             ret = get_errno(setrlimit(resource, &rlim));
5012         }
5013         break;
5014     case TARGET_NR_getrlimit:
5015         {
5016             /* XXX: convert resource ? */
5017             int resource = arg1;
5018             struct target_rlimit *target_rlim;
5019             struct rlimit rlim;
5020 
5021             ret = get_errno(getrlimit(resource, &rlim));
5022             if (!is_error(ret)) {
5023                 if (!lock_user_struct(VERIFY_WRITE, target_rlim, arg2, 0))
5024                     goto efault;
5025                 rlim.rlim_cur = tswapl(target_rlim->rlim_cur);
5026                 rlim.rlim_max = tswapl(target_rlim->rlim_max);
5027                 unlock_user_struct(target_rlim, arg2, 1);
5028             }
5029         }
5030         break;
5031     case TARGET_NR_getrusage:
5032         {
5033             struct rusage rusage;
5034             ret = get_errno(getrusage(arg1, &rusage));
5035             if (!is_error(ret)) {
5036                 host_to_target_rusage(arg2, &rusage);
5037             }
5038         }
5039         break;
5040     case TARGET_NR_gettimeofday:
5041         {
5042             struct timeval tv;
5043             ret = get_errno(gettimeofday(&tv, NULL));
5044             if (!is_error(ret)) {
5045                 if (copy_to_user_timeval(arg1, &tv))
5046                     goto efault;
5047             }
5048         }
5049         break;
5050     case TARGET_NR_settimeofday:
5051         {
5052             struct timeval tv;
5053             if (copy_from_user_timeval(&tv, arg1))
5054                 goto efault;
5055             ret = get_errno(settimeofday(&tv, NULL));
5056         }
5057         break;
5058 #ifdef TARGET_NR_select
5059     case TARGET_NR_select:
5060         {
5061             struct target_sel_arg_struct *sel;
5062             abi_ulong inp, outp, exp, tvp;
5063             long nsel;
5064 
5065             if (!lock_user_struct(VERIFY_READ, sel, arg1, 1))
5066                 goto efault;
5067             nsel = tswapl(sel->n);
5068             inp = tswapl(sel->inp);
5069             outp = tswapl(sel->outp);
5070             exp = tswapl(sel->exp);
5071             tvp = tswapl(sel->tvp);
5072             unlock_user_struct(sel, arg1, 0);
5073             ret = do_select(nsel, inp, outp, exp, tvp);
5074         }
5075         break;
5076 #endif
5077     case TARGET_NR_symlink:
5078         {
5079             void *p2;
5080             p = lock_user_string(arg1);
5081             p2 = lock_user_string(arg2);
5082             if (!p || !p2)
5083                 ret = -TARGET_EFAULT;
5084             else
5085                 ret = get_errno(symlink(p, p2));
5086             unlock_user(p2, arg2, 0);
5087             unlock_user(p, arg1, 0);
5088         }
5089         break;
5090 #if defined(TARGET_NR_symlinkat) && defined(__NR_symlinkat)
5091     case TARGET_NR_symlinkat:
5092         {
5093             void *p2;
5094             p  = lock_user_string(arg1);
5095             p2 = lock_user_string(arg3);
5096             if (!p || !p2)
5097                 ret = -TARGET_EFAULT;
5098             else
5099                 ret = get_errno(sys_symlinkat(p, arg2, p2));
5100             unlock_user(p2, arg3, 0);
5101             unlock_user(p, arg1, 0);
5102         }
5103         break;
5104 #endif
5105 #ifdef TARGET_NR_oldlstat
5106     case TARGET_NR_oldlstat:
5107         goto unimplemented;
5108 #endif
5109     case TARGET_NR_readlink:
5110         {
5111             void *p2, *temp;
5112             p = lock_user_string(arg1);
5113             p2 = lock_user(VERIFY_WRITE, arg2, arg3, 0);
5114             if (!p || !p2)
5115                 ret = -TARGET_EFAULT;
5116             else {
5117                 if (strncmp((const char *)p, "/proc/self/exe", 14) == 0) {
5118                     char real[PATH_MAX];
5119                     temp = realpath(exec_path,real);
5120                     ret = (temp==NULL) ? get_errno(-1) : strlen(real) ;
5121                     snprintf((char *)p2, arg3, "%s", real);
5122                     }
5123                 else
5124                     ret = get_errno(readlink(path(p), p2, arg3));
5125             }
5126             unlock_user(p2, arg2, ret);
5127             unlock_user(p, arg1, 0);
5128         }
5129         break;
5130 #if defined(TARGET_NR_readlinkat) && defined(__NR_readlinkat)
5131     case TARGET_NR_readlinkat:
5132         {
5133             void *p2;
5134             p  = lock_user_string(arg2);
5135             p2 = lock_user(VERIFY_WRITE, arg3, arg4, 0);
5136             if (!p || !p2)
5137         	ret = -TARGET_EFAULT;
5138             else
5139                 ret = get_errno(sys_readlinkat(arg1, path(p), p2, arg4));
5140             unlock_user(p2, arg3, ret);
5141             unlock_user(p, arg2, 0);
5142         }
5143         break;
5144 #endif
5145 #ifdef TARGET_NR_uselib
5146     case TARGET_NR_uselib:
5147         goto unimplemented;
5148 #endif
5149 #ifdef TARGET_NR_swapon
5150     case TARGET_NR_swapon:
5151         if (!(p = lock_user_string(arg1)))
5152             goto efault;
5153         ret = get_errno(swapon(p, arg2));
5154         unlock_user(p, arg1, 0);
5155         break;
5156 #endif
5157     case TARGET_NR_reboot:
5158         goto unimplemented;
5159 #ifdef TARGET_NR_readdir
5160     case TARGET_NR_readdir:
5161         goto unimplemented;
5162 #endif
5163 #ifdef TARGET_NR_mmap
5164     case TARGET_NR_mmap:
5165 #if (defined(TARGET_I386) && defined(TARGET_ABI32)) || defined(TARGET_ARM) || defined(TARGET_M68K) || defined(TARGET_CRIS) || defined(TARGET_MICROBLAZE)
5166         {
5167             abi_ulong *v;
5168             abi_ulong v1, v2, v3, v4, v5, v6;
5169             if (!(v = lock_user(VERIFY_READ, arg1, 6 * sizeof(abi_ulong), 1)))
5170                 goto efault;
5171             v1 = tswapl(v[0]);
5172             v2 = tswapl(v[1]);
5173             v3 = tswapl(v[2]);
5174             v4 = tswapl(v[3]);
5175             v5 = tswapl(v[4]);
5176             v6 = tswapl(v[5]);
5177             unlock_user(v, arg1, 0);
5178             ret = get_errno(target_mmap(v1, v2, v3,
5179                                         target_to_host_bitmask(v4, mmap_flags_tbl),
5180                                         v5, v6));
5181         }
5182 #else
5183         ret = get_errno(target_mmap(arg1, arg2, arg3,
5184                                     target_to_host_bitmask(arg4, mmap_flags_tbl),
5185                                     arg5,
5186                                     arg6));
5187 #endif
5188         break;
5189 #endif
5190 #ifdef TARGET_NR_mmap2
5191     case TARGET_NR_mmap2:
5192 #ifndef MMAP_SHIFT
5193 #define MMAP_SHIFT 12
5194 #endif
5195         ret = get_errno(target_mmap(arg1, arg2, arg3,
5196                                     target_to_host_bitmask(arg4, mmap_flags_tbl),
5197                                     arg5,
5198                                     arg6 << MMAP_SHIFT));
5199         break;
5200 #endif
5201     case TARGET_NR_munmap:
5202         ret = get_errno(target_munmap(arg1, arg2));
5203         break;
5204     case TARGET_NR_mprotect:
5205         ret = get_errno(target_mprotect(arg1, arg2, arg3));
5206         break;
5207 #ifdef TARGET_NR_mremap
5208     case TARGET_NR_mremap:
5209         ret = get_errno(target_mremap(arg1, arg2, arg3, arg4, arg5));
5210         break;
5211 #endif
5212         /* ??? msync/mlock/munlock are broken for softmmu.  */
5213 #ifdef TARGET_NR_msync
5214     case TARGET_NR_msync:
5215         ret = get_errno(msync(g2h(arg1), arg2, arg3));
5216         break;
5217 #endif
5218 #ifdef TARGET_NR_mlock
5219     case TARGET_NR_mlock:
5220         ret = get_errno(mlock(g2h(arg1), arg2));
5221         break;
5222 #endif
5223 #ifdef TARGET_NR_munlock
5224     case TARGET_NR_munlock:
5225         ret = get_errno(munlock(g2h(arg1), arg2));
5226         break;
5227 #endif
5228 #ifdef TARGET_NR_mlockall
5229     case TARGET_NR_mlockall:
5230         ret = get_errno(mlockall(arg1));
5231         break;
5232 #endif
5233 #ifdef TARGET_NR_munlockall
5234     case TARGET_NR_munlockall:
5235         ret = get_errno(munlockall());
5236         break;
5237 #endif
5238     case TARGET_NR_truncate:
5239         if (!(p = lock_user_string(arg1)))
5240             goto efault;
5241         ret = get_errno(truncate(p, arg2));
5242         unlock_user(p, arg1, 0);
5243         break;
5244     case TARGET_NR_ftruncate:
5245         ret = get_errno(ftruncate(arg1, arg2));
5246         break;
5247     case TARGET_NR_fchmod:
5248         ret = get_errno(fchmod(arg1, arg2));
5249         break;
5250 #if defined(TARGET_NR_fchmodat) && defined(__NR_fchmodat)
5251     case TARGET_NR_fchmodat:
5252         if (!(p = lock_user_string(arg2)))
5253             goto efault;
5254         ret = get_errno(sys_fchmodat(arg1, p, arg3));
5255         unlock_user(p, arg2, 0);
5256         break;
5257 #endif
5258     case TARGET_NR_getpriority:
5259         /* libc does special remapping of the return value of
5260          * sys_getpriority() so it's just easiest to call
5261          * sys_getpriority() directly rather than through libc. */
5262         ret = sys_getpriority(arg1, arg2);
5263         break;
5264     case TARGET_NR_setpriority:
5265         ret = get_errno(setpriority(arg1, arg2, arg3));
5266         break;
5267 #ifdef TARGET_NR_profil
5268     case TARGET_NR_profil:
5269         goto unimplemented;
5270 #endif
5271     case TARGET_NR_statfs:
5272         if (!(p = lock_user_string(arg1)))
5273             goto efault;
5274         ret = get_errno(statfs(path(p), &stfs));
5275         unlock_user(p, arg1, 0);
5276     convert_statfs:
5277         if (!is_error(ret)) {
5278             struct target_statfs *target_stfs;
5279 
5280             if (!lock_user_struct(VERIFY_WRITE, target_stfs, arg2, 0))
5281                 goto efault;
5282             __put_user(stfs.f_type, &target_stfs->f_type);
5283             __put_user(stfs.f_bsize, &target_stfs->f_bsize);
5284             __put_user(stfs.f_blocks, &target_stfs->f_blocks);
5285             __put_user(stfs.f_bfree, &target_stfs->f_bfree);
5286             __put_user(stfs.f_bavail, &target_stfs->f_bavail);
5287             __put_user(stfs.f_files, &target_stfs->f_files);
5288             __put_user(stfs.f_ffree, &target_stfs->f_ffree);
5289             __put_user(stfs.f_fsid.__val[0], &target_stfs->f_fsid.val[0]);
5290             __put_user(stfs.f_fsid.__val[1], &target_stfs->f_fsid.val[1]);
5291             __put_user(stfs.f_namelen, &target_stfs->f_namelen);
5292             unlock_user_struct(target_stfs, arg2, 1);
5293         }
5294         break;
5295     case TARGET_NR_fstatfs:
5296         ret = get_errno(fstatfs(arg1, &stfs));
5297         goto convert_statfs;
5298 #ifdef TARGET_NR_statfs64
5299     case TARGET_NR_statfs64:
5300         if (!(p = lock_user_string(arg1)))
5301             goto efault;
5302         ret = get_errno(statfs(path(p), &stfs));
5303         unlock_user(p, arg1, 0);
5304     convert_statfs64:
5305         if (!is_error(ret)) {
5306             struct target_statfs64 *target_stfs;
5307 
5308             if (!lock_user_struct(VERIFY_WRITE, target_stfs, arg3, 0))
5309                 goto efault;
5310             __put_user(stfs.f_type, &target_stfs->f_type);
5311             __put_user(stfs.f_bsize, &target_stfs->f_bsize);
5312             __put_user(stfs.f_blocks, &target_stfs->f_blocks);
5313             __put_user(stfs.f_bfree, &target_stfs->f_bfree);
5314             __put_user(stfs.f_bavail, &target_stfs->f_bavail);
5315             __put_user(stfs.f_files, &target_stfs->f_files);
5316             __put_user(stfs.f_ffree, &target_stfs->f_ffree);
5317             __put_user(stfs.f_fsid.__val[0], &target_stfs->f_fsid.val[0]);
5318             __put_user(stfs.f_fsid.__val[1], &target_stfs->f_fsid.val[1]);
5319             __put_user(stfs.f_namelen, &target_stfs->f_namelen);
5320             unlock_user_struct(target_stfs, arg3, 1);
5321         }
5322         break;
5323     case TARGET_NR_fstatfs64:
5324         ret = get_errno(fstatfs(arg1, &stfs));
5325         goto convert_statfs64;
5326 #endif
5327 #ifdef TARGET_NR_ioperm
5328     case TARGET_NR_ioperm:
5329         goto unimplemented;
5330 #endif
5331 #ifdef TARGET_NR_socketcall
5332     case TARGET_NR_socketcall:
5333         ret = do_socketcall(arg1, arg2);
5334         break;
5335 #endif
5336 #ifdef TARGET_NR_accept
5337     case TARGET_NR_accept:
5338         ret = do_accept(arg1, arg2, arg3);
5339         break;
5340 #endif
5341 #ifdef TARGET_NR_bind
5342     case TARGET_NR_bind:
5343         ret = do_bind(arg1, arg2, arg3);
5344         break;
5345 #endif
5346 #ifdef TARGET_NR_connect
5347     case TARGET_NR_connect:
5348         ret = do_connect(arg1, arg2, arg3);
5349         break;
5350 #endif
5351 #ifdef TARGET_NR_getpeername
5352     case TARGET_NR_getpeername:
5353         ret = do_getpeername(arg1, arg2, arg3);
5354         break;
5355 #endif
5356 #ifdef TARGET_NR_getsockname
5357     case TARGET_NR_getsockname:
5358         ret = do_getsockname(arg1, arg2, arg3);
5359         break;
5360 #endif
5361 #ifdef TARGET_NR_getsockopt
5362     case TARGET_NR_getsockopt:
5363         ret = do_getsockopt(arg1, arg2, arg3, arg4, arg5);
5364         break;
5365 #endif
5366 #ifdef TARGET_NR_listen
5367     case TARGET_NR_listen:
5368         ret = get_errno(listen(arg1, arg2));
5369         break;
5370 #endif
5371 #ifdef TARGET_NR_recv
5372     case TARGET_NR_recv:
5373         ret = do_recvfrom(arg1, arg2, arg3, arg4, 0, 0);
5374         break;
5375 #endif
5376 #ifdef TARGET_NR_recvfrom
5377     case TARGET_NR_recvfrom:
5378         ret = do_recvfrom(arg1, arg2, arg3, arg4, arg5, arg6);
5379         break;
5380 #endif
5381 #ifdef TARGET_NR_recvmsg
5382     case TARGET_NR_recvmsg:
5383         ret = do_sendrecvmsg(arg1, arg2, arg3, 0);
5384         break;
5385 #endif
5386 #ifdef TARGET_NR_send
5387     case TARGET_NR_send:
5388         ret = do_sendto(arg1, arg2, arg3, arg4, 0, 0);
5389         break;
5390 #endif
5391 #ifdef TARGET_NR_sendmsg
5392     case TARGET_NR_sendmsg:
5393         ret = do_sendrecvmsg(arg1, arg2, arg3, 1);
5394         break;
5395 #endif
5396 #ifdef TARGET_NR_sendto
5397     case TARGET_NR_sendto:
5398         ret = do_sendto(arg1, arg2, arg3, arg4, arg5, arg6);
5399         break;
5400 #endif
5401 #ifdef TARGET_NR_shutdown
5402     case TARGET_NR_shutdown:
5403         ret = get_errno(shutdown(arg1, arg2));
5404         break;
5405 #endif
5406 #ifdef TARGET_NR_socket
5407     case TARGET_NR_socket:
5408         ret = do_socket(arg1, arg2, arg3);
5409         break;
5410 #endif
5411 #ifdef TARGET_NR_socketpair
5412     case TARGET_NR_socketpair:
5413         ret = do_socketpair(arg1, arg2, arg3, arg4);
5414         break;
5415 #endif
5416 #ifdef TARGET_NR_setsockopt
5417     case TARGET_NR_setsockopt:
5418         ret = do_setsockopt(arg1, arg2, arg3, arg4, (socklen_t) arg5);
5419         break;
5420 #endif
5421 
5422     case TARGET_NR_syslog:
5423         if (!(p = lock_user_string(arg2)))
5424             goto efault;
5425         ret = get_errno(sys_syslog((int)arg1, p, (int)arg3));
5426         unlock_user(p, arg2, 0);
5427         break;
5428 
5429     case TARGET_NR_setitimer:
5430         {
5431             struct itimerval value, ovalue, *pvalue;
5432 
5433             if (arg2) {
5434                 pvalue = &value;
5435                 if (copy_from_user_timeval(&pvalue->it_interval, arg2)
5436                     || copy_from_user_timeval(&pvalue->it_value,
5437                                               arg2 + sizeof(struct target_timeval)))
5438                     goto efault;
5439             } else {
5440                 pvalue = NULL;
5441             }
5442             ret = get_errno(setitimer(arg1, pvalue, &ovalue));
5443             if (!is_error(ret) && arg3) {
5444                 if (copy_to_user_timeval(arg3,
5445                                          &ovalue.it_interval)
5446                     || copy_to_user_timeval(arg3 + sizeof(struct target_timeval),
5447                                             &ovalue.it_value))
5448                     goto efault;
5449             }
5450         }
5451         break;
5452     case TARGET_NR_getitimer:
5453         {
5454             struct itimerval value;
5455 
5456             ret = get_errno(getitimer(arg1, &value));
5457             if (!is_error(ret) && arg2) {
5458                 if (copy_to_user_timeval(arg2,
5459                                          &value.it_interval)
5460                     || copy_to_user_timeval(arg2 + sizeof(struct target_timeval),
5461                                             &value.it_value))
5462                     goto efault;
5463             }
5464         }
5465         break;
5466     case TARGET_NR_stat:
5467         if (!(p = lock_user_string(arg1)))
5468             goto efault;
5469         ret = get_errno(stat(path(p), &st));
5470         unlock_user(p, arg1, 0);
5471         goto do_stat;
5472     case TARGET_NR_lstat:
5473         if (!(p = lock_user_string(arg1)))
5474             goto efault;
5475         ret = get_errno(lstat(path(p), &st));
5476         unlock_user(p, arg1, 0);
5477         goto do_stat;
5478     case TARGET_NR_fstat:
5479         {
5480             ret = get_errno(fstat(arg1, &st));
5481         do_stat:
5482             if (!is_error(ret)) {
5483                 struct target_stat *target_st;
5484 
5485                 if (!lock_user_struct(VERIFY_WRITE, target_st, arg2, 0))
5486                     goto efault;
5487                 __put_user(st.st_dev, &target_st->st_dev);
5488                 __put_user(st.st_ino, &target_st->st_ino);
5489                 __put_user(st.st_mode, &target_st->st_mode);
5490                 __put_user(st.st_uid, &target_st->st_uid);
5491                 __put_user(st.st_gid, &target_st->st_gid);
5492                 __put_user(st.st_nlink, &target_st->st_nlink);
5493                 __put_user(st.st_rdev, &target_st->st_rdev);
5494                 __put_user(st.st_size, &target_st->st_size);
5495                 __put_user(st.st_blksize, &target_st->st_blksize);
5496                 __put_user(st.st_blocks, &target_st->st_blocks);
5497                 __put_user(st.st_atime, &target_st->target_st_atime);
5498                 __put_user(st.st_mtime, &target_st->target_st_mtime);
5499                 __put_user(st.st_ctime, &target_st->target_st_ctime);
5500                 unlock_user_struct(target_st, arg2, 1);
5501             }
5502         }
5503         break;
5504 #ifdef TARGET_NR_olduname
5505     case TARGET_NR_olduname:
5506         goto unimplemented;
5507 #endif
5508 #ifdef TARGET_NR_iopl
5509     case TARGET_NR_iopl:
5510         goto unimplemented;
5511 #endif
5512     case TARGET_NR_vhangup:
5513         ret = get_errno(vhangup());
5514         break;
5515 #ifdef TARGET_NR_idle
5516     case TARGET_NR_idle:
5517         goto unimplemented;
5518 #endif
5519 #ifdef TARGET_NR_syscall
5520     case TARGET_NR_syscall:
5521     	ret = do_syscall(cpu_env,arg1 & 0xffff,arg2,arg3,arg4,arg5,arg6,0);
5522     	break;
5523 #endif
5524     case TARGET_NR_wait4:
5525         {
5526             int status;
5527             abi_long status_ptr = arg2;
5528             struct rusage rusage, *rusage_ptr;
5529             abi_ulong target_rusage = arg4;
5530             if (target_rusage)
5531                 rusage_ptr = &rusage;
5532             else
5533                 rusage_ptr = NULL;
5534             ret = get_errno(wait4(arg1, &status, arg3, rusage_ptr));
5535             if (!is_error(ret)) {
5536                 if (status_ptr) {
5537                     status = host_to_target_waitstatus(status);
5538                     if (put_user_s32(status, status_ptr))
5539                         goto efault;
5540                 }
5541                 if (target_rusage)
5542                     host_to_target_rusage(target_rusage, &rusage);
5543             }
5544         }
5545         break;
5546 #ifdef TARGET_NR_swapoff
5547     case TARGET_NR_swapoff:
5548         if (!(p = lock_user_string(arg1)))
5549             goto efault;
5550         ret = get_errno(swapoff(p));
5551         unlock_user(p, arg1, 0);
5552         break;
5553 #endif
5554     case TARGET_NR_sysinfo:
5555         {
5556             struct target_sysinfo *target_value;
5557             struct sysinfo value;
5558             ret = get_errno(sysinfo(&value));
5559             if (!is_error(ret) && arg1)
5560             {
5561                 if (!lock_user_struct(VERIFY_WRITE, target_value, arg1, 0))
5562                     goto efault;
5563                 __put_user(value.uptime, &target_value->uptime);
5564                 __put_user(value.loads[0], &target_value->loads[0]);
5565                 __put_user(value.loads[1], &target_value->loads[1]);
5566                 __put_user(value.loads[2], &target_value->loads[2]);
5567                 __put_user(value.totalram, &target_value->totalram);
5568                 __put_user(value.freeram, &target_value->freeram);
5569                 __put_user(value.sharedram, &target_value->sharedram);
5570                 __put_user(value.bufferram, &target_value->bufferram);
5571                 __put_user(value.totalswap, &target_value->totalswap);
5572                 __put_user(value.freeswap, &target_value->freeswap);
5573                 __put_user(value.procs, &target_value->procs);
5574                 __put_user(value.totalhigh, &target_value->totalhigh);
5575                 __put_user(value.freehigh, &target_value->freehigh);
5576                 __put_user(value.mem_unit, &target_value->mem_unit);
5577                 unlock_user_struct(target_value, arg1, 1);
5578             }
5579         }
5580         break;
5581 #ifdef TARGET_NR_ipc
5582     case TARGET_NR_ipc:
5583 	ret = do_ipc(arg1, arg2, arg3, arg4, arg5, arg6);
5584 	break;
5585 #endif
5586 #ifdef TARGET_NR_semget
5587     case TARGET_NR_semget:
5588         ret = get_errno(semget(arg1, arg2, arg3));
5589         break;
5590 #endif
5591 #ifdef TARGET_NR_semop
5592     case TARGET_NR_semop:
5593         ret = get_errno(do_semop(arg1, arg2, arg3));
5594         break;
5595 #endif
5596 #ifdef TARGET_NR_semctl
5597     case TARGET_NR_semctl:
5598         ret = do_semctl(arg1, arg2, arg3, (union target_semun)(abi_ulong)arg4);
5599         break;
5600 #endif
5601 #ifdef TARGET_NR_msgctl
5602     case TARGET_NR_msgctl:
5603         ret = do_msgctl(arg1, arg2, arg3);
5604         break;
5605 #endif
5606 #ifdef TARGET_NR_msgget
5607     case TARGET_NR_msgget:
5608         ret = get_errno(msgget(arg1, arg2));
5609         break;
5610 #endif
5611 #ifdef TARGET_NR_msgrcv
5612     case TARGET_NR_msgrcv:
5613         ret = do_msgrcv(arg1, arg2, arg3, arg4, arg5);
5614         break;
5615 #endif
5616 #ifdef TARGET_NR_msgsnd
5617     case TARGET_NR_msgsnd:
5618         ret = do_msgsnd(arg1, arg2, arg3, arg4);
5619         break;
5620 #endif
5621 #ifdef TARGET_NR_shmget
5622     case TARGET_NR_shmget:
5623         ret = get_errno(shmget(arg1, arg2, arg3));
5624         break;
5625 #endif
5626 #ifdef TARGET_NR_shmctl
5627     case TARGET_NR_shmctl:
5628         ret = do_shmctl(arg1, arg2, arg3);
5629         break;
5630 #endif
5631 #ifdef TARGET_NR_shmat
5632     case TARGET_NR_shmat:
5633         ret = do_shmat(arg1, arg2, arg3);
5634         break;
5635 #endif
5636 #ifdef TARGET_NR_shmdt
5637     case TARGET_NR_shmdt:
5638         ret = do_shmdt(arg1);
5639         break;
5640 #endif
5641     case TARGET_NR_fsync:
5642         ret = get_errno(fsync(arg1));
5643         break;
5644     case TARGET_NR_clone:
5645 #if defined(TARGET_SH4)
5646         ret = get_errno(do_fork(cpu_env, arg1, arg2, arg3, arg5, arg4));
5647 #elif defined(TARGET_CRIS)
5648         ret = get_errno(do_fork(cpu_env, arg2, arg1, arg3, arg4, arg5));
5649 #else
5650         ret = get_errno(do_fork(cpu_env, arg1, arg2, arg3, arg4, arg5));
5651 #endif
5652         break;
5653 #ifdef __NR_exit_group
5654         /* new thread calls */
5655     case TARGET_NR_exit_group:
5656 #ifdef HAVE_GPROF
5657         _mcleanup();
5658 #endif
5659         gdb_exit(cpu_env, arg1);
5660         ret = get_errno(exit_group(arg1));
5661         break;
5662 #endif
5663     case TARGET_NR_setdomainname:
5664         if (!(p = lock_user_string(arg1)))
5665             goto efault;
5666         ret = get_errno(setdomainname(p, arg2));
5667         unlock_user(p, arg1, 0);
5668         break;
5669     case TARGET_NR_uname:
5670         /* no need to transcode because we use the linux syscall */
5671         {
5672             struct new_utsname * buf;
5673 
5674             if (!lock_user_struct(VERIFY_WRITE, buf, arg1, 0))
5675                 goto efault;
5676             ret = get_errno(sys_uname(buf));
5677             if (!is_error(ret)) {
5678                 /* Overrite the native machine name with whatever is being
5679                    emulated. */
5680                 strcpy (buf->machine, UNAME_MACHINE);
5681                 /* Allow the user to override the reported release.  */
5682                 if (qemu_uname_release && *qemu_uname_release)
5683                   strcpy (buf->release, qemu_uname_release);
5684             }
5685             unlock_user_struct(buf, arg1, 1);
5686         }
5687         break;
5688 #ifdef TARGET_I386
5689     case TARGET_NR_modify_ldt:
5690         ret = do_modify_ldt(cpu_env, arg1, arg2, arg3);
5691         break;
5692 #if !defined(TARGET_X86_64)
5693     case TARGET_NR_vm86old:
5694         goto unimplemented;
5695     case TARGET_NR_vm86:
5696         ret = do_vm86(cpu_env, arg1, arg2);
5697         break;
5698 #endif
5699 #endif
5700     case TARGET_NR_adjtimex:
5701         goto unimplemented;
5702 #ifdef TARGET_NR_create_module
5703     case TARGET_NR_create_module:
5704 #endif
5705     case TARGET_NR_init_module:
5706     case TARGET_NR_delete_module:
5707 #ifdef TARGET_NR_get_kernel_syms
5708     case TARGET_NR_get_kernel_syms:
5709 #endif
5710         goto unimplemented;
5711     case TARGET_NR_quotactl:
5712         goto unimplemented;
5713     case TARGET_NR_getpgid:
5714         ret = get_errno(getpgid(arg1));
5715         break;
5716     case TARGET_NR_fchdir:
5717         ret = get_errno(fchdir(arg1));
5718         break;
5719 #ifdef TARGET_NR_bdflush /* not on x86_64 */
5720     case TARGET_NR_bdflush:
5721         goto unimplemented;
5722 #endif
5723 #ifdef TARGET_NR_sysfs
5724     case TARGET_NR_sysfs:
5725         goto unimplemented;
5726 #endif
5727     case TARGET_NR_personality:
5728         ret = get_errno(personality(arg1));
5729         break;
5730 #ifdef TARGET_NR_afs_syscall
5731     case TARGET_NR_afs_syscall:
5732         goto unimplemented;
5733 #endif
5734 #ifdef TARGET_NR__llseek /* Not on alpha */
5735     case TARGET_NR__llseek:
5736         {
5737 #if defined (__x86_64__)
5738             ret = get_errno(lseek(arg1, ((uint64_t )arg2 << 32) | arg3, arg5));
5739             if (put_user_s64(ret, arg4))
5740                 goto efault;
5741 #else
5742             int64_t res;
5743             ret = get_errno(_llseek(arg1, arg2, arg3, &res, arg5));
5744             if (put_user_s64(res, arg4))
5745                 goto efault;
5746 #endif
5747         }
5748         break;
5749 #endif
5750     case TARGET_NR_getdents:
5751 #if TARGET_ABI_BITS != 32
5752         goto unimplemented;
5753 #elif TARGET_ABI_BITS == 32 && HOST_LONG_BITS == 64
5754         {
5755             struct target_dirent *target_dirp;
5756             struct linux_dirent *dirp;
5757             abi_long count = arg3;
5758 
5759 	    dirp = malloc(count);
5760 	    if (!dirp) {
5761                 ret = -TARGET_ENOMEM;
5762                 goto fail;
5763             }
5764 
5765             ret = get_errno(sys_getdents(arg1, dirp, count));
5766             if (!is_error(ret)) {
5767                 struct linux_dirent *de;
5768 		struct target_dirent *tde;
5769                 int len = ret;
5770                 int reclen, treclen;
5771 		int count1, tnamelen;
5772 
5773 		count1 = 0;
5774                 de = dirp;
5775                 if (!(target_dirp = lock_user(VERIFY_WRITE, arg2, count, 0)))
5776                     goto efault;
5777 		tde = target_dirp;
5778                 while (len > 0) {
5779                     reclen = de->d_reclen;
5780 		    treclen = reclen - (2 * (sizeof(long) - sizeof(abi_long)));
5781                     tde->d_reclen = tswap16(treclen);
5782                     tde->d_ino = tswapl(de->d_ino);
5783                     tde->d_off = tswapl(de->d_off);
5784 		    tnamelen = treclen - (2 * sizeof(abi_long) + 2);
5785 		    if (tnamelen > 256)
5786                         tnamelen = 256;
5787                     /* XXX: may not be correct */
5788                     pstrcpy(tde->d_name, tnamelen, de->d_name);
5789                     de = (struct linux_dirent *)((char *)de + reclen);
5790                     len -= reclen;
5791                     tde = (struct target_dirent *)((char *)tde + treclen);
5792 		    count1 += treclen;
5793                 }
5794 		ret = count1;
5795                 unlock_user(target_dirp, arg2, ret);
5796             }
5797 	    free(dirp);
5798         }
5799 #else
5800         {
5801             struct linux_dirent *dirp;
5802             abi_long count = arg3;
5803 
5804             if (!(dirp = lock_user(VERIFY_WRITE, arg2, count, 0)))
5805                 goto efault;
5806             ret = get_errno(sys_getdents(arg1, dirp, count));
5807             if (!is_error(ret)) {
5808                 struct linux_dirent *de;
5809                 int len = ret;
5810                 int reclen;
5811                 de = dirp;
5812                 while (len > 0) {
5813                     reclen = de->d_reclen;
5814                     if (reclen > len)
5815                         break;
5816                     de->d_reclen = tswap16(reclen);
5817                     tswapls(&de->d_ino);
5818                     tswapls(&de->d_off);
5819                     de = (struct linux_dirent *)((char *)de + reclen);
5820                     len -= reclen;
5821                 }
5822             }
5823             unlock_user(dirp, arg2, ret);
5824         }
5825 #endif
5826         break;
5827 #if defined(TARGET_NR_getdents64) && defined(__NR_getdents64)
5828     case TARGET_NR_getdents64:
5829         {
5830             struct linux_dirent64 *dirp;
5831             abi_long count = arg3;
5832             if (!(dirp = lock_user(VERIFY_WRITE, arg2, count, 0)))
5833                 goto efault;
5834             ret = get_errno(sys_getdents64(arg1, dirp, count));
5835             if (!is_error(ret)) {
5836                 struct linux_dirent64 *de;
5837                 int len = ret;
5838                 int reclen;
5839                 de = dirp;
5840                 while (len > 0) {
5841                     reclen = de->d_reclen;
5842                     if (reclen > len)
5843                         break;
5844                     de->d_reclen = tswap16(reclen);
5845                     tswap64s((uint64_t *)&de->d_ino);
5846                     tswap64s((uint64_t *)&de->d_off);
5847                     de = (struct linux_dirent64 *)((char *)de + reclen);
5848                     len -= reclen;
5849                 }
5850             }
5851             unlock_user(dirp, arg2, ret);
5852         }
5853         break;
5854 #endif /* TARGET_NR_getdents64 */
5855 #ifdef TARGET_NR__newselect
5856     case TARGET_NR__newselect:
5857         ret = do_select(arg1, arg2, arg3, arg4, arg5);
5858         break;
5859 #endif
5860 #ifdef TARGET_NR_poll
5861     case TARGET_NR_poll:
5862         {
5863             struct target_pollfd *target_pfd;
5864             unsigned int nfds = arg2;
5865             int timeout = arg3;
5866             struct pollfd *pfd;
5867             unsigned int i;
5868 
5869             target_pfd = lock_user(VERIFY_WRITE, arg1, sizeof(struct target_pollfd) * nfds, 1);
5870             if (!target_pfd)
5871                 goto efault;
5872             pfd = alloca(sizeof(struct pollfd) * nfds);
5873             for(i = 0; i < nfds; i++) {
5874                 pfd[i].fd = tswap32(target_pfd[i].fd);
5875                 pfd[i].events = tswap16(target_pfd[i].events);
5876             }
5877             ret = get_errno(poll(pfd, nfds, timeout));
5878             if (!is_error(ret)) {
5879                 for(i = 0; i < nfds; i++) {
5880                     target_pfd[i].revents = tswap16(pfd[i].revents);
5881                 }
5882                 ret += nfds * (sizeof(struct target_pollfd)
5883                                - sizeof(struct pollfd));
5884             }
5885             unlock_user(target_pfd, arg1, ret);
5886         }
5887         break;
5888 #endif
5889     case TARGET_NR_flock:
5890         /* NOTE: the flock constant seems to be the same for every
5891            Linux platform */
5892         ret = get_errno(flock(arg1, arg2));
5893         break;
5894     case TARGET_NR_readv:
5895         {
5896             int count = arg3;
5897             struct iovec *vec;
5898 
5899             vec = alloca(count * sizeof(struct iovec));
5900             if (lock_iovec(VERIFY_WRITE, vec, arg2, count, 0) < 0)
5901                 goto efault;
5902             ret = get_errno(readv(arg1, vec, count));
5903             unlock_iovec(vec, arg2, count, 1);
5904         }
5905         break;
5906     case TARGET_NR_writev:
5907         {
5908             int count = arg3;
5909             struct iovec *vec;
5910 
5911             vec = alloca(count * sizeof(struct iovec));
5912             if (lock_iovec(VERIFY_READ, vec, arg2, count, 1) < 0)
5913                 goto efault;
5914             ret = get_errno(writev(arg1, vec, count));
5915             unlock_iovec(vec, arg2, count, 0);
5916         }
5917         break;
5918     case TARGET_NR_getsid:
5919         ret = get_errno(getsid(arg1));
5920         break;
5921 #if defined(TARGET_NR_fdatasync) /* Not on alpha (osf_datasync ?) */
5922     case TARGET_NR_fdatasync:
5923         ret = get_errno(fdatasync(arg1));
5924         break;
5925 #endif
5926     case TARGET_NR__sysctl:
5927         /* We don't implement this, but ENOTDIR is always a safe
5928            return value. */
5929         ret = -TARGET_ENOTDIR;
5930         break;
5931     case TARGET_NR_sched_setparam:
5932         {
5933             struct sched_param *target_schp;
5934             struct sched_param schp;
5935 
5936             if (!lock_user_struct(VERIFY_READ, target_schp, arg2, 1))
5937                 goto efault;
5938             schp.sched_priority = tswap32(target_schp->sched_priority);
5939             unlock_user_struct(target_schp, arg2, 0);
5940             ret = get_errno(sched_setparam(arg1, &schp));
5941         }
5942         break;
5943     case TARGET_NR_sched_getparam:
5944         {
5945             struct sched_param *target_schp;
5946             struct sched_param schp;
5947             ret = get_errno(sched_getparam(arg1, &schp));
5948             if (!is_error(ret)) {
5949                 if (!lock_user_struct(VERIFY_WRITE, target_schp, arg2, 0))
5950                     goto efault;
5951                 target_schp->sched_priority = tswap32(schp.sched_priority);
5952                 unlock_user_struct(target_schp, arg2, 1);
5953             }
5954         }
5955         break;
5956     case TARGET_NR_sched_setscheduler:
5957         {
5958             struct sched_param *target_schp;
5959             struct sched_param schp;
5960             if (!lock_user_struct(VERIFY_READ, target_schp, arg3, 1))
5961                 goto efault;
5962             schp.sched_priority = tswap32(target_schp->sched_priority);
5963             unlock_user_struct(target_schp, arg3, 0);
5964             ret = get_errno(sched_setscheduler(arg1, arg2, &schp));
5965         }
5966         break;
5967     case TARGET_NR_sched_getscheduler:
5968         ret = get_errno(sched_getscheduler(arg1));
5969         break;
5970     case TARGET_NR_sched_yield:
5971         ret = get_errno(sched_yield());
5972         break;
5973     case TARGET_NR_sched_get_priority_max:
5974         ret = get_errno(sched_get_priority_max(arg1));
5975         break;
5976     case TARGET_NR_sched_get_priority_min:
5977         ret = get_errno(sched_get_priority_min(arg1));
5978         break;
5979     case TARGET_NR_sched_rr_get_interval:
5980         {
5981             struct timespec ts;
5982             ret = get_errno(sched_rr_get_interval(arg1, &ts));
5983             if (!is_error(ret)) {
5984                 host_to_target_timespec(arg2, &ts);
5985             }
5986         }
5987         break;
5988     case TARGET_NR_nanosleep:
5989         {
5990             struct timespec req, rem;
5991             target_to_host_timespec(&req, arg1);
5992             ret = get_errno(nanosleep(&req, &rem));
5993             if (is_error(ret) && arg2) {
5994                 host_to_target_timespec(arg2, &rem);
5995             }
5996         }
5997         break;
5998 #ifdef TARGET_NR_query_module
5999     case TARGET_NR_query_module:
6000         goto unimplemented;
6001 #endif
6002 #ifdef TARGET_NR_nfsservctl
6003     case TARGET_NR_nfsservctl:
6004         goto unimplemented;
6005 #endif
6006     case TARGET_NR_prctl:
6007         switch (arg1)
6008             {
6009             case PR_GET_PDEATHSIG:
6010                 {
6011                     int deathsig;
6012                     ret = get_errno(prctl(arg1, &deathsig, arg3, arg4, arg5));
6013                     if (!is_error(ret) && arg2
6014                         && put_user_ual(deathsig, arg2))
6015                         goto efault;
6016                 }
6017                 break;
6018             default:
6019                 ret = get_errno(prctl(arg1, arg2, arg3, arg4, arg5));
6020                 break;
6021             }
6022         break;
6023 #ifdef TARGET_NR_arch_prctl
6024     case TARGET_NR_arch_prctl:
6025 #if defined(TARGET_I386) && !defined(TARGET_ABI32)
6026         ret = do_arch_prctl(cpu_env, arg1, arg2);
6027         break;
6028 #else
6029         goto unimplemented;
6030 #endif
6031 #endif
6032 #ifdef TARGET_NR_pread
6033     case TARGET_NR_pread:
6034 #ifdef TARGET_ARM
6035         if (((CPUARMState *)cpu_env)->eabi)
6036             arg4 = arg5;
6037 #endif
6038         if (!(p = lock_user(VERIFY_WRITE, arg2, arg3, 0)))
6039             goto efault;
6040         ret = get_errno(pread(arg1, p, arg3, arg4));
6041         unlock_user(p, arg2, ret);
6042         break;
6043     case TARGET_NR_pwrite:
6044 #ifdef TARGET_ARM
6045         if (((CPUARMState *)cpu_env)->eabi)
6046             arg4 = arg5;
6047 #endif
6048         if (!(p = lock_user(VERIFY_READ, arg2, arg3, 1)))
6049             goto efault;
6050         ret = get_errno(pwrite(arg1, p, arg3, arg4));
6051         unlock_user(p, arg2, 0);
6052         break;
6053 #endif
6054 #ifdef TARGET_NR_pread64
6055     case TARGET_NR_pread64:
6056         if (!(p = lock_user(VERIFY_WRITE, arg2, arg3, 0)))
6057             goto efault;
6058         ret = get_errno(pread64(arg1, p, arg3, target_offset64(arg4, arg5)));
6059         unlock_user(p, arg2, ret);
6060         break;
6061     case TARGET_NR_pwrite64:
6062         if (!(p = lock_user(VERIFY_READ, arg2, arg3, 1)))
6063             goto efault;
6064         ret = get_errno(pwrite64(arg1, p, arg3, target_offset64(arg4, arg5)));
6065         unlock_user(p, arg2, 0);
6066         break;
6067 #endif
6068     case TARGET_NR_getcwd:
6069         if (!(p = lock_user(VERIFY_WRITE, arg1, arg2, 0)))
6070             goto efault;
6071         ret = get_errno(sys_getcwd1(p, arg2));
6072         unlock_user(p, arg1, ret);
6073         break;
6074     case TARGET_NR_capget:
6075         goto unimplemented;
6076     case TARGET_NR_capset:
6077         goto unimplemented;
6078     case TARGET_NR_sigaltstack:
6079 #if defined(TARGET_I386) || defined(TARGET_ARM) || defined(TARGET_MIPS) || \
6080     defined(TARGET_SPARC) || defined(TARGET_PPC) || defined(TARGET_ALPHA)
6081         ret = do_sigaltstack(arg1, arg2, get_sp_from_cpustate((CPUState *)cpu_env));
6082         break;
6083 #else
6084         goto unimplemented;
6085 #endif
6086     case TARGET_NR_sendfile:
6087         goto unimplemented;
6088 #ifdef TARGET_NR_getpmsg
6089     case TARGET_NR_getpmsg:
6090         goto unimplemented;
6091 #endif
6092 #ifdef TARGET_NR_putpmsg
6093     case TARGET_NR_putpmsg:
6094         goto unimplemented;
6095 #endif
6096 #ifdef TARGET_NR_vfork
6097     case TARGET_NR_vfork:
6098         ret = get_errno(do_fork(cpu_env, CLONE_VFORK | CLONE_VM | SIGCHLD,
6099                         0, 0, 0, 0));
6100         break;
6101 #endif
6102 #ifdef TARGET_NR_ugetrlimit
6103     case TARGET_NR_ugetrlimit:
6104     {
6105 	struct rlimit rlim;
6106 	ret = get_errno(getrlimit(arg1, &rlim));
6107 	if (!is_error(ret)) {
6108 	    struct target_rlimit *target_rlim;
6109             if (!lock_user_struct(VERIFY_WRITE, target_rlim, arg2, 0))
6110                 goto efault;
6111 	    target_rlim->rlim_cur = tswapl(rlim.rlim_cur);
6112 	    target_rlim->rlim_max = tswapl(rlim.rlim_max);
6113             unlock_user_struct(target_rlim, arg2, 1);
6114 	}
6115 	break;
6116     }
6117 #endif
6118 #ifdef TARGET_NR_truncate64
6119     case TARGET_NR_truncate64:
6120         if (!(p = lock_user_string(arg1)))
6121             goto efault;
6122 	ret = target_truncate64(cpu_env, p, arg2, arg3, arg4);
6123         unlock_user(p, arg1, 0);
6124 	break;
6125 #endif
6126 #ifdef TARGET_NR_ftruncate64
6127     case TARGET_NR_ftruncate64:
6128 	ret = target_ftruncate64(cpu_env, arg1, arg2, arg3, arg4);
6129 	break;
6130 #endif
6131 #ifdef TARGET_NR_stat64
6132     case TARGET_NR_stat64:
6133         if (!(p = lock_user_string(arg1)))
6134             goto efault;
6135         ret = get_errno(stat(path(p), &st));
6136         unlock_user(p, arg1, 0);
6137         if (!is_error(ret))
6138             ret = host_to_target_stat64(cpu_env, arg2, &st);
6139         break;
6140 #endif
6141 #ifdef TARGET_NR_lstat64
6142     case TARGET_NR_lstat64:
6143         if (!(p = lock_user_string(arg1)))
6144             goto efault;
6145         ret = get_errno(lstat(path(p), &st));
6146         unlock_user(p, arg1, 0);
6147         if (!is_error(ret))
6148             ret = host_to_target_stat64(cpu_env, arg2, &st);
6149         break;
6150 #endif
6151 #ifdef TARGET_NR_fstat64
6152     case TARGET_NR_fstat64:
6153         ret = get_errno(fstat(arg1, &st));
6154         if (!is_error(ret))
6155             ret = host_to_target_stat64(cpu_env, arg2, &st);
6156         break;
6157 #endif
6158 #if (defined(TARGET_NR_fstatat64) || defined(TARGET_NR_newfstatat)) && \
6159         (defined(__NR_fstatat64) || defined(__NR_newfstatat))
6160 #ifdef TARGET_NR_fstatat64
6161     case TARGET_NR_fstatat64:
6162 #endif
6163 #ifdef TARGET_NR_newfstatat
6164     case TARGET_NR_newfstatat:
6165 #endif
6166         if (!(p = lock_user_string(arg2)))
6167             goto efault;
6168 #ifdef __NR_fstatat64
6169         ret = get_errno(sys_fstatat64(arg1, path(p), &st, arg4));
6170 #else
6171         ret = get_errno(sys_newfstatat(arg1, path(p), &st, arg4));
6172 #endif
6173         if (!is_error(ret))
6174             ret = host_to_target_stat64(cpu_env, arg3, &st);
6175         break;
6176 #endif
6177 #ifdef USE_UID16
6178     case TARGET_NR_lchown:
6179         if (!(p = lock_user_string(arg1)))
6180             goto efault;
6181         ret = get_errno(lchown(p, low2highuid(arg2), low2highgid(arg3)));
6182         unlock_user(p, arg1, 0);
6183         break;
6184     case TARGET_NR_getuid:
6185         ret = get_errno(high2lowuid(getuid()));
6186         break;
6187     case TARGET_NR_getgid:
6188         ret = get_errno(high2lowgid(getgid()));
6189         break;
6190     case TARGET_NR_geteuid:
6191         ret = get_errno(high2lowuid(geteuid()));
6192         break;
6193     case TARGET_NR_getegid:
6194         ret = get_errno(high2lowgid(getegid()));
6195         break;
6196     case TARGET_NR_setreuid:
6197         ret = get_errno(setreuid(low2highuid(arg1), low2highuid(arg2)));
6198         break;
6199     case TARGET_NR_setregid:
6200         ret = get_errno(setregid(low2highgid(arg1), low2highgid(arg2)));
6201         break;
6202     case TARGET_NR_getgroups:
6203         {
6204             int gidsetsize = arg1;
6205             uint16_t *target_grouplist;
6206             gid_t *grouplist;
6207             int i;
6208 
6209             grouplist = alloca(gidsetsize * sizeof(gid_t));
6210             ret = get_errno(getgroups(gidsetsize, grouplist));
6211             if (gidsetsize == 0)
6212                 break;
6213             if (!is_error(ret)) {
6214                 target_grouplist = lock_user(VERIFY_WRITE, arg2, gidsetsize * 2, 0);
6215                 if (!target_grouplist)
6216                     goto efault;
6217                 for(i = 0;i < ret; i++)
6218                     target_grouplist[i] = tswap16(grouplist[i]);
6219                 unlock_user(target_grouplist, arg2, gidsetsize * 2);
6220             }
6221         }
6222         break;
6223     case TARGET_NR_setgroups:
6224         {
6225             int gidsetsize = arg1;
6226             uint16_t *target_grouplist;
6227             gid_t *grouplist;
6228             int i;
6229 
6230             grouplist = alloca(gidsetsize * sizeof(gid_t));
6231             target_grouplist = lock_user(VERIFY_READ, arg2, gidsetsize * 2, 1);
6232             if (!target_grouplist) {
6233                 ret = -TARGET_EFAULT;
6234                 goto fail;
6235             }
6236             for(i = 0;i < gidsetsize; i++)
6237                 grouplist[i] = tswap16(target_grouplist[i]);
6238             unlock_user(target_grouplist, arg2, 0);
6239             ret = get_errno(setgroups(gidsetsize, grouplist));
6240         }
6241         break;
6242     case TARGET_NR_fchown:
6243         ret = get_errno(fchown(arg1, low2highuid(arg2), low2highgid(arg3)));
6244         break;
6245 #if defined(TARGET_NR_fchownat) && defined(__NR_fchownat)
6246     case TARGET_NR_fchownat:
6247         if (!(p = lock_user_string(arg2)))
6248             goto efault;
6249         ret = get_errno(sys_fchownat(arg1, p, low2highuid(arg3), low2highgid(arg4), arg5));
6250         unlock_user(p, arg2, 0);
6251         break;
6252 #endif
6253 #ifdef TARGET_NR_setresuid
6254     case TARGET_NR_setresuid:
6255         ret = get_errno(setresuid(low2highuid(arg1),
6256                                   low2highuid(arg2),
6257                                   low2highuid(arg3)));
6258         break;
6259 #endif
6260 #ifdef TARGET_NR_getresuid
6261     case TARGET_NR_getresuid:
6262         {
6263             uid_t ruid, euid, suid;
6264             ret = get_errno(getresuid(&ruid, &euid, &suid));
6265             if (!is_error(ret)) {
6266                 if (put_user_u16(high2lowuid(ruid), arg1)
6267                     || put_user_u16(high2lowuid(euid), arg2)
6268                     || put_user_u16(high2lowuid(suid), arg3))
6269                     goto efault;
6270             }
6271         }
6272         break;
6273 #endif
6274 #ifdef TARGET_NR_getresgid
6275     case TARGET_NR_setresgid:
6276         ret = get_errno(setresgid(low2highgid(arg1),
6277                                   low2highgid(arg2),
6278                                   low2highgid(arg3)));
6279         break;
6280 #endif
6281 #ifdef TARGET_NR_getresgid
6282     case TARGET_NR_getresgid:
6283         {
6284             gid_t rgid, egid, sgid;
6285             ret = get_errno(getresgid(&rgid, &egid, &sgid));
6286             if (!is_error(ret)) {
6287                 if (put_user_u16(high2lowgid(rgid), arg1)
6288                     || put_user_u16(high2lowgid(egid), arg2)
6289                     || put_user_u16(high2lowgid(sgid), arg3))
6290                     goto efault;
6291             }
6292         }
6293         break;
6294 #endif
6295     case TARGET_NR_chown:
6296         if (!(p = lock_user_string(arg1)))
6297             goto efault;
6298         ret = get_errno(chown(p, low2highuid(arg2), low2highgid(arg3)));
6299         unlock_user(p, arg1, 0);
6300         break;
6301     case TARGET_NR_setuid:
6302         ret = get_errno(setuid(low2highuid(arg1)));
6303         break;
6304     case TARGET_NR_setgid:
6305         ret = get_errno(setgid(low2highgid(arg1)));
6306         break;
6307     case TARGET_NR_setfsuid:
6308         ret = get_errno(setfsuid(arg1));
6309         break;
6310     case TARGET_NR_setfsgid:
6311         ret = get_errno(setfsgid(arg1));
6312         break;
6313 #endif /* USE_UID16 */
6314 
6315 #ifdef TARGET_NR_lchown32
6316     case TARGET_NR_lchown32:
6317         if (!(p = lock_user_string(arg1)))
6318             goto efault;
6319         ret = get_errno(lchown(p, arg2, arg3));
6320         unlock_user(p, arg1, 0);
6321         break;
6322 #endif
6323 #ifdef TARGET_NR_getuid32
6324     case TARGET_NR_getuid32:
6325         ret = get_errno(getuid());
6326         break;
6327 #endif
6328 
6329 #if defined(TARGET_NR_getxuid) && defined(TARGET_ALPHA)
6330    /* Alpha specific */
6331     case TARGET_NR_getxuid:
6332 	 {
6333 	    uid_t euid;
6334 	    euid=geteuid();
6335 	    ((CPUAlphaState *)cpu_env)->ir[IR_A4]=euid;
6336 	 }
6337         ret = get_errno(getuid());
6338         break;
6339 #endif
6340 #if defined(TARGET_NR_getxgid) && defined(TARGET_ALPHA)
6341    /* Alpha specific */
6342     case TARGET_NR_getxgid:
6343 	 {
6344 	    uid_t egid;
6345 	    egid=getegid();
6346 	    ((CPUAlphaState *)cpu_env)->ir[IR_A4]=egid;
6347 	 }
6348         ret = get_errno(getgid());
6349         break;
6350 #endif
6351 
6352 #ifdef TARGET_NR_getgid32
6353     case TARGET_NR_getgid32:
6354         ret = get_errno(getgid());
6355         break;
6356 #endif
6357 #ifdef TARGET_NR_geteuid32
6358     case TARGET_NR_geteuid32:
6359         ret = get_errno(geteuid());
6360         break;
6361 #endif
6362 #ifdef TARGET_NR_getegid32
6363     case TARGET_NR_getegid32:
6364         ret = get_errno(getegid());
6365         break;
6366 #endif
6367 #ifdef TARGET_NR_setreuid32
6368     case TARGET_NR_setreuid32:
6369         ret = get_errno(setreuid(arg1, arg2));
6370         break;
6371 #endif
6372 #ifdef TARGET_NR_setregid32
6373     case TARGET_NR_setregid32:
6374         ret = get_errno(setregid(arg1, arg2));
6375         break;
6376 #endif
6377 #ifdef TARGET_NR_getgroups32
6378     case TARGET_NR_getgroups32:
6379         {
6380             int gidsetsize = arg1;
6381             uint32_t *target_grouplist;
6382             gid_t *grouplist;
6383             int i;
6384 
6385             grouplist = alloca(gidsetsize * sizeof(gid_t));
6386             ret = get_errno(getgroups(gidsetsize, grouplist));
6387             if (gidsetsize == 0)
6388                 break;
6389             if (!is_error(ret)) {
6390                 target_grouplist = lock_user(VERIFY_WRITE, arg2, gidsetsize * 4, 0);
6391                 if (!target_grouplist) {
6392                     ret = -TARGET_EFAULT;
6393                     goto fail;
6394                 }
6395                 for(i = 0;i < ret; i++)
6396                     target_grouplist[i] = tswap32(grouplist[i]);
6397                 unlock_user(target_grouplist, arg2, gidsetsize * 4);
6398             }
6399         }
6400         break;
6401 #endif
6402 #ifdef TARGET_NR_setgroups32
6403     case TARGET_NR_setgroups32:
6404         {
6405             int gidsetsize = arg1;
6406             uint32_t *target_grouplist;
6407             gid_t *grouplist;
6408             int i;
6409 
6410             grouplist = alloca(gidsetsize * sizeof(gid_t));
6411             target_grouplist = lock_user(VERIFY_READ, arg2, gidsetsize * 4, 1);
6412             if (!target_grouplist) {
6413                 ret = -TARGET_EFAULT;
6414                 goto fail;
6415             }
6416             for(i = 0;i < gidsetsize; i++)
6417                 grouplist[i] = tswap32(target_grouplist[i]);
6418             unlock_user(target_grouplist, arg2, 0);
6419             ret = get_errno(setgroups(gidsetsize, grouplist));
6420         }
6421         break;
6422 #endif
6423 #ifdef TARGET_NR_fchown32
6424     case TARGET_NR_fchown32:
6425         ret = get_errno(fchown(arg1, arg2, arg3));
6426         break;
6427 #endif
6428 #ifdef TARGET_NR_setresuid32
6429     case TARGET_NR_setresuid32:
6430         ret = get_errno(setresuid(arg1, arg2, arg3));
6431         break;
6432 #endif
6433 #ifdef TARGET_NR_getresuid32
6434     case TARGET_NR_getresuid32:
6435         {
6436             uid_t ruid, euid, suid;
6437             ret = get_errno(getresuid(&ruid, &euid, &suid));
6438             if (!is_error(ret)) {
6439                 if (put_user_u32(ruid, arg1)
6440                     || put_user_u32(euid, arg2)
6441                     || put_user_u32(suid, arg3))
6442                     goto efault;
6443             }
6444         }
6445         break;
6446 #endif
6447 #ifdef TARGET_NR_setresgid32
6448     case TARGET_NR_setresgid32:
6449         ret = get_errno(setresgid(arg1, arg2, arg3));
6450         break;
6451 #endif
6452 #ifdef TARGET_NR_getresgid32
6453     case TARGET_NR_getresgid32:
6454         {
6455             gid_t rgid, egid, sgid;
6456             ret = get_errno(getresgid(&rgid, &egid, &sgid));
6457             if (!is_error(ret)) {
6458                 if (put_user_u32(rgid, arg1)
6459                     || put_user_u32(egid, arg2)
6460                     || put_user_u32(sgid, arg3))
6461                     goto efault;
6462             }
6463         }
6464         break;
6465 #endif
6466 #ifdef TARGET_NR_chown32
6467     case TARGET_NR_chown32:
6468         if (!(p = lock_user_string(arg1)))
6469             goto efault;
6470         ret = get_errno(chown(p, arg2, arg3));
6471         unlock_user(p, arg1, 0);
6472         break;
6473 #endif
6474 #ifdef TARGET_NR_setuid32
6475     case TARGET_NR_setuid32:
6476         ret = get_errno(setuid(arg1));
6477         break;
6478 #endif
6479 #ifdef TARGET_NR_setgid32
6480     case TARGET_NR_setgid32:
6481         ret = get_errno(setgid(arg1));
6482         break;
6483 #endif
6484 #ifdef TARGET_NR_setfsuid32
6485     case TARGET_NR_setfsuid32:
6486         ret = get_errno(setfsuid(arg1));
6487         break;
6488 #endif
6489 #ifdef TARGET_NR_setfsgid32
6490     case TARGET_NR_setfsgid32:
6491         ret = get_errno(setfsgid(arg1));
6492         break;
6493 #endif
6494 
6495     case TARGET_NR_pivot_root:
6496         goto unimplemented;
6497 #ifdef TARGET_NR_mincore
6498     case TARGET_NR_mincore:
6499         {
6500             void *a;
6501             ret = -TARGET_EFAULT;
6502             if (!(a = lock_user(VERIFY_READ, arg1,arg2, 0)))
6503                 goto efault;
6504             if (!(p = lock_user_string(arg3)))
6505                 goto mincore_fail;
6506             ret = get_errno(mincore(a, arg2, p));
6507             unlock_user(p, arg3, ret);
6508             mincore_fail:
6509             unlock_user(a, arg1, 0);
6510         }
6511         break;
6512 #endif
6513 #ifdef TARGET_NR_arm_fadvise64_64
6514     case TARGET_NR_arm_fadvise64_64:
6515 	{
6516 		/*
6517 		 * arm_fadvise64_64 looks like fadvise64_64 but
6518 		 * with different argument order
6519 		 */
6520 		abi_long temp;
6521 		temp = arg3;
6522 		arg3 = arg4;
6523 		arg4 = temp;
6524 	}
6525 #endif
6526 #if defined(TARGET_NR_fadvise64_64) || defined(TARGET_NR_arm_fadvise64_64)
6527 #ifdef TARGET_NR_fadvise64_64
6528     case TARGET_NR_fadvise64_64:
6529 #endif
6530         /* This is a hint, so ignoring and returning success is ok.  */
6531 	ret = get_errno(0);
6532 	break;
6533 #endif
6534 #ifdef TARGET_NR_madvise
6535     case TARGET_NR_madvise:
6536         /* A straight passthrough may not be safe because qemu sometimes
6537            turns private flie-backed mappings into anonymous mappings.
6538            This will break MADV_DONTNEED.
6539            This is a hint, so ignoring and returning success is ok.  */
6540         ret = get_errno(0);
6541         break;
6542 #endif
6543 #if TARGET_ABI_BITS == 32
6544     case TARGET_NR_fcntl64:
6545     {
6546 	int cmd;
6547 	struct flock64 fl;
6548 	struct target_flock64 *target_fl;
6549 #ifdef TARGET_ARM
6550 	struct target_eabi_flock64 *target_efl;
6551 #endif
6552 
6553 	cmd = target_to_host_fcntl_cmd(arg2);
6554 	if (cmd == -TARGET_EINVAL)
6555 		return cmd;
6556 
6557         switch(arg2) {
6558         case TARGET_F_GETLK64:
6559 #ifdef TARGET_ARM
6560             if (((CPUARMState *)cpu_env)->eabi) {
6561                 if (!lock_user_struct(VERIFY_READ, target_efl, arg3, 1))
6562                     goto efault;
6563                 fl.l_type = tswap16(target_efl->l_type);
6564                 fl.l_whence = tswap16(target_efl->l_whence);
6565                 fl.l_start = tswap64(target_efl->l_start);
6566                 fl.l_len = tswap64(target_efl->l_len);
6567                 fl.l_pid = tswapl(target_efl->l_pid);
6568                 unlock_user_struct(target_efl, arg3, 0);
6569             } else
6570 #endif
6571             {
6572                 if (!lock_user_struct(VERIFY_READ, target_fl, arg3, 1))
6573                     goto efault;
6574                 fl.l_type = tswap16(target_fl->l_type);
6575                 fl.l_whence = tswap16(target_fl->l_whence);
6576                 fl.l_start = tswap64(target_fl->l_start);
6577                 fl.l_len = tswap64(target_fl->l_len);
6578                 fl.l_pid = tswapl(target_fl->l_pid);
6579                 unlock_user_struct(target_fl, arg3, 0);
6580             }
6581             ret = get_errno(fcntl(arg1, cmd, &fl));
6582 	    if (ret == 0) {
6583 #ifdef TARGET_ARM
6584                 if (((CPUARMState *)cpu_env)->eabi) {
6585                     if (!lock_user_struct(VERIFY_WRITE, target_efl, arg3, 0))
6586                         goto efault;
6587                     target_efl->l_type = tswap16(fl.l_type);
6588                     target_efl->l_whence = tswap16(fl.l_whence);
6589                     target_efl->l_start = tswap64(fl.l_start);
6590                     target_efl->l_len = tswap64(fl.l_len);
6591                     target_efl->l_pid = tswapl(fl.l_pid);
6592                     unlock_user_struct(target_efl, arg3, 1);
6593                 } else
6594 #endif
6595                 {
6596                     if (!lock_user_struct(VERIFY_WRITE, target_fl, arg3, 0))
6597                         goto efault;
6598                     target_fl->l_type = tswap16(fl.l_type);
6599                     target_fl->l_whence = tswap16(fl.l_whence);
6600                     target_fl->l_start = tswap64(fl.l_start);
6601                     target_fl->l_len = tswap64(fl.l_len);
6602                     target_fl->l_pid = tswapl(fl.l_pid);
6603                     unlock_user_struct(target_fl, arg3, 1);
6604                 }
6605 	    }
6606 	    break;
6607 
6608         case TARGET_F_SETLK64:
6609         case TARGET_F_SETLKW64:
6610 #ifdef TARGET_ARM
6611             if (((CPUARMState *)cpu_env)->eabi) {
6612                 if (!lock_user_struct(VERIFY_READ, target_efl, arg3, 1))
6613                     goto efault;
6614                 fl.l_type = tswap16(target_efl->l_type);
6615                 fl.l_whence = tswap16(target_efl->l_whence);
6616                 fl.l_start = tswap64(target_efl->l_start);
6617                 fl.l_len = tswap64(target_efl->l_len);
6618                 fl.l_pid = tswapl(target_efl->l_pid);
6619                 unlock_user_struct(target_efl, arg3, 0);
6620             } else
6621 #endif
6622             {
6623                 if (!lock_user_struct(VERIFY_READ, target_fl, arg3, 1))
6624                     goto efault;
6625                 fl.l_type = tswap16(target_fl->l_type);
6626                 fl.l_whence = tswap16(target_fl->l_whence);
6627                 fl.l_start = tswap64(target_fl->l_start);
6628                 fl.l_len = tswap64(target_fl->l_len);
6629                 fl.l_pid = tswapl(target_fl->l_pid);
6630                 unlock_user_struct(target_fl, arg3, 0);
6631             }
6632             ret = get_errno(fcntl(arg1, cmd, &fl));
6633 	    break;
6634         default:
6635             ret = do_fcntl(arg1, arg2, arg3);
6636             break;
6637         }
6638 	break;
6639     }
6640 #endif
6641 #ifdef TARGET_NR_cacheflush
6642     case TARGET_NR_cacheflush:
6643         /* self-modifying code is handled automatically, so nothing needed */
6644         ret = 0;
6645         break;
6646 #endif
6647 #ifdef TARGET_NR_security
6648     case TARGET_NR_security:
6649         goto unimplemented;
6650 #endif
6651 #ifdef TARGET_NR_getpagesize
6652     case TARGET_NR_getpagesize:
6653         ret = TARGET_PAGE_SIZE;
6654         break;
6655 #endif
6656     case TARGET_NR_gettid:
6657         ret = get_errno(gettid());
6658         break;
6659 #ifdef TARGET_NR_readahead
6660     case TARGET_NR_readahead:
6661 #if TARGET_ABI_BITS == 32
6662 #ifdef TARGET_ARM
6663         if (((CPUARMState *)cpu_env)->eabi)
6664         {
6665             arg2 = arg3;
6666             arg3 = arg4;
6667             arg4 = arg5;
6668         }
6669 #endif
6670         ret = get_errno(readahead(arg1, ((off64_t)arg3 << 32) | arg2, arg4));
6671 #else
6672         ret = get_errno(readahead(arg1, arg2, arg3));
6673 #endif
6674         break;
6675 #endif
6676 #ifdef TARGET_NR_setxattr
6677     case TARGET_NR_setxattr:
6678     case TARGET_NR_lsetxattr:
6679     case TARGET_NR_fsetxattr:
6680     case TARGET_NR_getxattr:
6681     case TARGET_NR_lgetxattr:
6682     case TARGET_NR_fgetxattr:
6683     case TARGET_NR_listxattr:
6684     case TARGET_NR_llistxattr:
6685     case TARGET_NR_flistxattr:
6686     case TARGET_NR_removexattr:
6687     case TARGET_NR_lremovexattr:
6688     case TARGET_NR_fremovexattr:
6689         ret = -TARGET_EOPNOTSUPP;
6690         break;
6691 #endif
6692 #ifdef TARGET_NR_set_thread_area
6693     case TARGET_NR_set_thread_area:
6694 #if defined(TARGET_MIPS)
6695       ((CPUMIPSState *) cpu_env)->tls_value = arg1;
6696       ret = 0;
6697       break;
6698 #elif defined(TARGET_CRIS)
6699       if (arg1 & 0xff)
6700           ret = -TARGET_EINVAL;
6701       else {
6702           ((CPUCRISState *) cpu_env)->pregs[PR_PID] = arg1;
6703           ret = 0;
6704       }
6705       break;
6706 #elif defined(TARGET_I386) && defined(TARGET_ABI32)
6707       ret = do_set_thread_area(cpu_env, arg1);
6708       break;
6709 #else
6710       goto unimplemented_nowarn;
6711 #endif
6712 #endif
6713 #ifdef TARGET_NR_get_thread_area
6714     case TARGET_NR_get_thread_area:
6715 #if defined(TARGET_I386) && defined(TARGET_ABI32)
6716         ret = do_get_thread_area(cpu_env, arg1);
6717 #else
6718         goto unimplemented_nowarn;
6719 #endif
6720 #endif
6721 #ifdef TARGET_NR_getdomainname
6722     case TARGET_NR_getdomainname:
6723         goto unimplemented_nowarn;
6724 #endif
6725 
6726 #ifdef TARGET_NR_clock_gettime
6727     case TARGET_NR_clock_gettime:
6728     {
6729         struct timespec ts;
6730         ret = get_errno(clock_gettime(arg1, &ts));
6731         if (!is_error(ret)) {
6732             host_to_target_timespec(arg2, &ts);
6733         }
6734         break;
6735     }
6736 #endif
6737 #ifdef TARGET_NR_clock_getres
6738     case TARGET_NR_clock_getres:
6739     {
6740         struct timespec ts;
6741         ret = get_errno(clock_getres(arg1, &ts));
6742         if (!is_error(ret)) {
6743             host_to_target_timespec(arg2, &ts);
6744         }
6745         break;
6746     }
6747 #endif
6748 #ifdef TARGET_NR_clock_nanosleep
6749     case TARGET_NR_clock_nanosleep:
6750     {
6751         struct timespec ts;
6752         target_to_host_timespec(&ts, arg3);
6753         ret = get_errno(clock_nanosleep(arg1, arg2, &ts, arg4 ? &ts : NULL));
6754         if (arg4)
6755             host_to_target_timespec(arg4, &ts);
6756         break;
6757     }
6758 #endif
6759 
6760 #if defined(TARGET_NR_set_tid_address) && defined(__NR_set_tid_address)
6761     case TARGET_NR_set_tid_address:
6762         ret = get_errno(set_tid_address((int *)g2h(arg1)));
6763         break;
6764 #endif
6765 
6766 #if defined(TARGET_NR_tkill) && defined(__NR_tkill)
6767     case TARGET_NR_tkill:
6768         ret = get_errno(sys_tkill((int)arg1, target_to_host_signal(arg2)));
6769         break;
6770 #endif
6771 
6772 #if defined(TARGET_NR_tgkill) && defined(__NR_tgkill)
6773     case TARGET_NR_tgkill:
6774 	ret = get_errno(sys_tgkill((int)arg1, (int)arg2,
6775                         target_to_host_signal(arg3)));
6776 	break;
6777 #endif
6778 
6779 #ifdef TARGET_NR_set_robust_list
6780     case TARGET_NR_set_robust_list:
6781 	goto unimplemented_nowarn;
6782 #endif
6783 
6784 #if defined(TARGET_NR_utimensat) && defined(__NR_utimensat)
6785     case TARGET_NR_utimensat:
6786         {
6787             struct timespec *tsp, ts[2];
6788             if (!arg3) {
6789                 tsp = NULL;
6790             } else {
6791                 target_to_host_timespec(ts, arg3);
6792                 target_to_host_timespec(ts+1, arg3+sizeof(struct target_timespec));
6793                 tsp = ts;
6794             }
6795             if (!arg2)
6796                 ret = get_errno(sys_utimensat(arg1, NULL, tsp, arg4));
6797             else {
6798                 if (!(p = lock_user_string(arg2))) {
6799                     ret = -TARGET_EFAULT;
6800                     goto fail;
6801                 }
6802                 ret = get_errno(sys_utimensat(arg1, path(p), tsp, arg4));
6803                 unlock_user(p, arg2, 0);
6804             }
6805         }
6806 	break;
6807 #endif
6808 #if defined(USE_NPTL)
6809     case TARGET_NR_futex:
6810         ret = do_futex(arg1, arg2, arg3, arg4, arg5, arg6);
6811         break;
6812 #endif
6813 #if defined(TARGET_NR_inotify_init) && defined(__NR_inotify_init)
6814     case TARGET_NR_inotify_init:
6815         ret = get_errno(sys_inotify_init());
6816         break;
6817 #endif
6818 #if defined(TARGET_NR_inotify_add_watch) && defined(__NR_inotify_add_watch)
6819     case TARGET_NR_inotify_add_watch:
6820         p = lock_user_string(arg2);
6821         ret = get_errno(sys_inotify_add_watch(arg1, path(p), arg3));
6822         unlock_user(p, arg2, 0);
6823         break;
6824 #endif
6825 #if defined(TARGET_NR_inotify_rm_watch) && defined(__NR_inotify_rm_watch)
6826     case TARGET_NR_inotify_rm_watch:
6827         ret = get_errno(sys_inotify_rm_watch(arg1, arg2));
6828         break;
6829 #endif
6830 
6831 #ifdef TARGET_NR_mq_open
6832     case TARGET_NR_mq_open:
6833         {
6834             struct mq_attr posix_mq_attr;
6835 
6836             p = lock_user_string(arg1 - 1);
6837             if (arg4 != 0)
6838                 copy_from_user_mq_attr (&posix_mq_attr, arg4);
6839             ret = get_errno(mq_open(p, arg2, arg3, &posix_mq_attr));
6840             unlock_user (p, arg1, 0);
6841         }
6842         break;
6843 
6844     case TARGET_NR_mq_unlink:
6845         p = lock_user_string(arg1 - 1);
6846         ret = get_errno(mq_unlink(p));
6847         unlock_user (p, arg1, 0);
6848         break;
6849 
6850     case TARGET_NR_mq_timedsend:
6851         {
6852             struct timespec ts;
6853 
6854             p = lock_user (VERIFY_READ, arg2, arg3, 1);
6855             if (arg5 != 0) {
6856                 target_to_host_timespec(&ts, arg5);
6857                 ret = get_errno(mq_timedsend(arg1, p, arg3, arg4, &ts));
6858                 host_to_target_timespec(arg5, &ts);
6859             }
6860             else
6861                 ret = get_errno(mq_send(arg1, p, arg3, arg4));
6862             unlock_user (p, arg2, arg3);
6863         }
6864         break;
6865 
6866     case TARGET_NR_mq_timedreceive:
6867         {
6868             struct timespec ts;
6869             unsigned int prio;
6870 
6871             p = lock_user (VERIFY_READ, arg2, arg3, 1);
6872             if (arg5 != 0) {
6873                 target_to_host_timespec(&ts, arg5);
6874                 ret = get_errno(mq_timedreceive(arg1, p, arg3, &prio, &ts));
6875                 host_to_target_timespec(arg5, &ts);
6876             }
6877             else
6878                 ret = get_errno(mq_receive(arg1, p, arg3, &prio));
6879             unlock_user (p, arg2, arg3);
6880             if (arg4 != 0)
6881                 put_user_u32(prio, arg4);
6882         }
6883         break;
6884 
6885     /* Not implemented for now... */
6886 /*     case TARGET_NR_mq_notify: */
6887 /*         break; */
6888 
6889     case TARGET_NR_mq_getsetattr:
6890         {
6891             struct mq_attr posix_mq_attr_in, posix_mq_attr_out;
6892             ret = 0;
6893             if (arg3 != 0) {
6894                 ret = mq_getattr(arg1, &posix_mq_attr_out);
6895                 copy_to_user_mq_attr(arg3, &posix_mq_attr_out);
6896             }
6897             if (arg2 != 0) {
6898                 copy_from_user_mq_attr(&posix_mq_attr_in, arg2);
6899                 ret |= mq_setattr(arg1, &posix_mq_attr_in, &posix_mq_attr_out);
6900             }
6901 
6902         }
6903         break;
6904 #endif
6905 
6906 #ifdef CONFIG_SPLICE
6907 #ifdef TARGET_NR_tee
6908     case TARGET_NR_tee:
6909         {
6910             ret = get_errno(tee(arg1,arg2,arg3,arg4));
6911         }
6912         break;
6913 #endif
6914 #ifdef TARGET_NR_splice
6915     case TARGET_NR_splice:
6916         {
6917             loff_t loff_in, loff_out;
6918             loff_t *ploff_in = NULL, *ploff_out = NULL;
6919             if(arg2) {
6920                 get_user_u64(loff_in, arg2);
6921                 ploff_in = &loff_in;
6922             }
6923             if(arg4) {
6924                 get_user_u64(loff_out, arg2);
6925                 ploff_out = &loff_out;
6926             }
6927             ret = get_errno(splice(arg1, ploff_in, arg3, ploff_out, arg5, arg6));
6928         }
6929         break;
6930 #endif
6931 #ifdef TARGET_NR_vmsplice
6932 	case TARGET_NR_vmsplice:
6933         {
6934             int count = arg3;
6935             struct iovec *vec;
6936 
6937             vec = alloca(count * sizeof(struct iovec));
6938             if (lock_iovec(VERIFY_READ, vec, arg2, count, 1) < 0)
6939                 goto efault;
6940             ret = get_errno(vmsplice(arg1, vec, count, arg4));
6941             unlock_iovec(vec, arg2, count, 0);
6942         }
6943         break;
6944 #endif
6945 #endif /* CONFIG_SPLICE */
6946     default:
6947     unimplemented:
6948         gemu_log("qemu: Unsupported syscall: %d\n", num);
6949 #if defined(TARGET_NR_setxattr) || defined(TARGET_NR_get_thread_area) || defined(TARGET_NR_getdomainname) || defined(TARGET_NR_set_robust_list)
6950     unimplemented_nowarn:
6951 #endif
6952         ret = -TARGET_ENOSYS;
6953         break;
6954     }
6955 fail:
6956 #ifdef DEBUG
6957     gemu_log(" = %ld\n", ret);
6958 #endif
6959     if(do_strace)
6960         print_syscall_ret(num, ret);
6961     return ret;
6962 efault:
6963     ret = -TARGET_EFAULT;
6964     goto fail;
6965 }
6966