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