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