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