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