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