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