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