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