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