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