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