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