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