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