Make various generated structures static
[qemu] / linux-user / syscall.c
1 /*
2  *  Linux syscalls
3  *
4  *  Copyright (c) 2003 Fabrice Bellard
5  *
6  *  This program is free software; you can redistribute it and/or modify
7  *  it under the terms of the GNU General Public License as published by
8  *  the Free Software Foundation; either version 2 of the License, or
9  *  (at your option) any later version.
10  *
11  *  This program is distributed in the hope that it will be useful,
12  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
13  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14  *  GNU General Public License for more details.
15  *
16  *  You should have received a copy of the GNU General Public License
17  *  along with this program; if not, write to the Free Software
18  *  Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
19  */
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 <dirent.h>
32 #include <sys/types.h>
33 #include <sys/ipc.h>
34 #include <sys/msg.h>
35 #include <sys/wait.h>
36 #include <sys/time.h>
37 #include <sys/stat.h>
38 #include <sys/mount.h>
39 #include <sys/prctl.h>
40 #include <sys/resource.h>
41 #include <sys/mman.h>
42 #include <sys/swap.h>
43 #include <signal.h>
44 #include <sched.h>
45 #include <sys/socket.h>
46 #include <sys/uio.h>
47 #include <sys/poll.h>
48 #include <sys/times.h>
49 #include <sys/shm.h>
50 #include <sys/sem.h>
51 #include <sys/statfs.h>
52 #include <utime.h>
53 #include <sys/sysinfo.h>
54 //#include <sys/user.h>
55 #include <netinet/ip.h>
56 #include <netinet/tcp.h>
57 #include <qemu-common.h>
58
59 #define termios host_termios
60 #define winsize host_winsize
61 #define termio host_termio
62 #define sgttyb host_sgttyb /* same as target */
63 #define tchars host_tchars /* same as target */
64 #define ltchars host_ltchars /* same as target */
65
66 #include <linux/termios.h>
67 #include <linux/unistd.h>
68 #include <linux/utsname.h>
69 #include <linux/cdrom.h>
70 #include <linux/hdreg.h>
71 #include <linux/soundcard.h>
72 #include <linux/kd.h>
73 #include <linux/mtio.h>
74 #include "linux_loop.h"
75
76 #include "qemu.h"
77 #include "qemu-common.h"
78
79 #if defined(USE_NPTL)
80 #include <linux/futex.h>
81 #define CLONE_NPTL_FLAGS2 (CLONE_SETTLS | \
82     CLONE_PARENT_SETTID | CLONE_CHILD_SETTID | CLONE_CHILD_CLEARTID)
83 #else
84 /* XXX: Hardcode the above values.  */
85 #define CLONE_NPTL_FLAGS2 0
86 #endif
87
88 //#define DEBUG
89
90 #if defined(TARGET_I386) || defined(TARGET_ARM) || defined(TARGET_SPARC) \
91     || defined(TARGET_M68K) || defined(TARGET_SH4) || defined(TARGET_CRIS)
92 /* 16 bit uid wrappers emulation */
93 #define USE_UID16
94 #endif
95
96 //#include <linux/msdos_fs.h>
97 #define VFAT_IOCTL_READDIR_BOTH         _IOR('r', 1, struct dirent [2])
98 #define VFAT_IOCTL_READDIR_SHORT        _IOR('r', 2, struct dirent [2])
99
100
101 #undef _syscall0
102 #undef _syscall1
103 #undef _syscall2
104 #undef _syscall3
105 #undef _syscall4
106 #undef _syscall5
107 #undef _syscall6
108
109 #define _syscall0(type,name)            \
110 static type name (void)                 \
111 {                                       \
112         return syscall(__NR_##name);    \
113 }
114
115 #define _syscall1(type,name,type1,arg1)         \
116 static type name (type1 arg1)                   \
117 {                                               \
118         return syscall(__NR_##name, arg1);      \
119 }
120
121 #define _syscall2(type,name,type1,arg1,type2,arg2)      \
122 static type name (type1 arg1,type2 arg2)                \
123 {                                                       \
124         return syscall(__NR_##name, arg1, arg2);        \
125 }
126
127 #define _syscall3(type,name,type1,arg1,type2,arg2,type3,arg3)   \
128 static type name (type1 arg1,type2 arg2,type3 arg3)             \
129 {                                                               \
130         return syscall(__NR_##name, arg1, arg2, arg3);          \
131 }
132
133 #define _syscall4(type,name,type1,arg1,type2,arg2,type3,arg3,type4,arg4)        \
134 static type name (type1 arg1,type2 arg2,type3 arg3,type4 arg4)                  \
135 {                                                                               \
136         return syscall(__NR_##name, arg1, arg2, arg3, arg4);                    \
137 }
138
139 #define _syscall5(type,name,type1,arg1,type2,arg2,type3,arg3,type4,arg4,        \
140                   type5,arg5)                                                   \
141 static type name (type1 arg1,type2 arg2,type3 arg3,type4 arg4,type5 arg5)       \
142 {                                                                               \
143         return syscall(__NR_##name, arg1, arg2, arg3, arg4, arg5);              \
144 }
145
146
147 #define _syscall6(type,name,type1,arg1,type2,arg2,type3,arg3,type4,arg4,        \
148                   type5,arg5,type6,arg6)                                        \
149 static type name (type1 arg1,type2 arg2,type3 arg3,type4 arg4,type5 arg5,       \
150                   type6 arg6)                                                   \
151 {                                                                               \
152         return syscall(__NR_##name, arg1, arg2, arg3, arg4, arg5, arg6);        \
153 }
154
155
156 #define __NR_sys_uname __NR_uname
157 #define __NR_sys_faccessat __NR_faccessat
158 #define __NR_sys_fchmodat __NR_fchmodat
159 #define __NR_sys_fchownat __NR_fchownat
160 #define __NR_sys_fstatat64 __NR_fstatat64
161 #define __NR_sys_futimesat __NR_futimesat
162 #define __NR_sys_getcwd1 __NR_getcwd
163 #define __NR_sys_getdents __NR_getdents
164 #define __NR_sys_getdents64 __NR_getdents64
165 #define __NR_sys_getpriority __NR_getpriority
166 #define __NR_sys_linkat __NR_linkat
167 #define __NR_sys_mkdirat __NR_mkdirat
168 #define __NR_sys_mknodat __NR_mknodat
169 #define __NR_sys_openat __NR_openat
170 #define __NR_sys_readlinkat __NR_readlinkat
171 #define __NR_sys_renameat __NR_renameat
172 #define __NR_sys_rt_sigqueueinfo __NR_rt_sigqueueinfo
173 #define __NR_sys_symlinkat __NR_symlinkat
174 #define __NR_sys_syslog __NR_syslog
175 #define __NR_sys_tgkill __NR_tgkill
176 #define __NR_sys_tkill __NR_tkill
177 #define __NR_sys_unlinkat __NR_unlinkat
178 #define __NR_sys_utimensat __NR_utimensat
179 #define __NR_sys_futex __NR_futex
180 #define __NR_sys_inotify_init __NR_inotify_init
181 #define __NR_sys_inotify_add_watch __NR_inotify_add_watch
182 #define __NR_sys_inotify_rm_watch __NR_inotify_rm_watch
183
184 #if defined(__alpha__) || defined (__ia64__) || defined(__x86_64__)
185 #define __NR__llseek __NR_lseek
186 #endif
187
188 #ifdef __NR_gettid
189 _syscall0(int, gettid)
190 #else
191 /* This is a replacement for the host gettid() and must return a host
192    errno. */
193 static int gettid(void) {
194     return -ENOSYS;
195 }
196 #endif
197 _syscall1(int,sys_uname,struct new_utsname *,buf)
198 #if defined(TARGET_NR_faccessat) && defined(__NR_faccessat)
199 _syscall4(int,sys_faccessat,int,dirfd,const char *,pathname,int,mode,int,flags)
200 #endif
201 #if defined(TARGET_NR_fchmodat) && defined(__NR_fchmodat)
202 _syscall4(int,sys_fchmodat,int,dirfd,const char *,pathname,
203           mode_t,mode,int,flags)
204 #endif
205 #if defined(TARGET_NR_fchownat) && defined(__NR_fchownat) && defined(USE_UID16)
206 _syscall5(int,sys_fchownat,int,dirfd,const char *,pathname,
207           uid_t,owner,gid_t,group,int,flags)
208 #endif
209 #if defined(TARGET_NR_fstatat64) && defined(__NR_fstatat64)
210 _syscall4(int,sys_fstatat64,int,dirfd,const char *,pathname,
211           struct stat *,buf,int,flags)
212 #endif
213 #if defined(TARGET_NR_futimesat) && defined(__NR_futimesat)
214 _syscall3(int,sys_futimesat,int,dirfd,const char *,pathname,
215          const struct timeval *,times)
216 #endif
217 _syscall2(int,sys_getcwd1,char *,buf,size_t,size)
218 #if TARGET_ABI_BITS == 32
219 _syscall3(int, sys_getdents, uint, fd, struct dirent *, dirp, uint, count);
220 #endif
221 #if defined(TARGET_NR_getdents64) && defined(__NR_getdents64)
222 _syscall3(int, sys_getdents64, uint, fd, struct dirent64 *, dirp, uint, count);
223 #endif
224 _syscall2(int, sys_getpriority, int, which, int, who);
225 #if !defined (__x86_64__)
226 _syscall5(int, _llseek,  uint,  fd, ulong, hi, ulong, lo,
227           loff_t *, res, uint, wh);
228 #endif
229 #if defined(TARGET_NR_linkat) && defined(__NR_linkat)
230 _syscall5(int,sys_linkat,int,olddirfd,const char *,oldpath,
231           int,newdirfd,const char *,newpath,int,flags)
232 #endif
233 #if defined(TARGET_NR_mkdirat) && defined(__NR_mkdirat)
234 _syscall3(int,sys_mkdirat,int,dirfd,const char *,pathname,mode_t,mode)
235 #endif
236 #if defined(TARGET_NR_mknodat) && defined(__NR_mknodat)
237 _syscall4(int,sys_mknodat,int,dirfd,const char *,pathname,
238           mode_t,mode,dev_t,dev)
239 #endif
240 #if defined(TARGET_NR_openat) && defined(__NR_openat)
241 _syscall4(int,sys_openat,int,dirfd,const char *,pathname,int,flags,mode_t,mode)
242 #endif
243 #if defined(TARGET_NR_readlinkat) && defined(__NR_readlinkat)
244 _syscall4(int,sys_readlinkat,int,dirfd,const char *,pathname,
245           char *,buf,size_t,bufsize)
246 #endif
247 #if defined(TARGET_NR_renameat) && defined(__NR_renameat)
248 _syscall4(int,sys_renameat,int,olddirfd,const char *,oldpath,
249           int,newdirfd,const char *,newpath)
250 #endif
251 _syscall3(int,sys_rt_sigqueueinfo,int,pid,int,sig,siginfo_t *,uinfo)
252 #if defined(TARGET_NR_symlinkat) && defined(__NR_symlinkat)
253 _syscall3(int,sys_symlinkat,const char *,oldpath,
254           int,newdirfd,const char *,newpath)
255 #endif
256 _syscall3(int,sys_syslog,int,type,char*,bufp,int,len)
257 #if defined(TARGET_NR_tgkill) && defined(__NR_tgkill)
258 _syscall3(int,sys_tgkill,int,tgid,int,pid,int,sig)
259 #endif
260 #if defined(TARGET_NR_tkill) && defined(__NR_tkill)
261 _syscall2(int,sys_tkill,int,tid,int,sig)
262 #endif
263 #ifdef __NR_exit_group
264 _syscall1(int,exit_group,int,error_code)
265 #endif
266 #if defined(TARGET_NR_set_tid_address) && defined(__NR_set_tid_address)
267 _syscall1(int,set_tid_address,int *,tidptr)
268 #endif
269 #if defined(TARGET_NR_unlinkat) && defined(__NR_unlinkat)
270 _syscall3(int,sys_unlinkat,int,dirfd,const char *,pathname,int,flags)
271 #endif
272 #if defined(TARGET_NR_utimensat) && defined(__NR_utimensat)
273 _syscall4(int,sys_utimensat,int,dirfd,const char *,pathname,
274           const struct timespec *,tsp,int,flags)
275 #endif
276 #if defined(TARGET_NR_inotify_init) && defined(__NR_inotify_init)
277 _syscall0(int,sys_inotify_init)
278 #endif
279 #if defined(TARGET_NR_inotify_add_watch) && defined(__NR_inotify_add_watch)
280 _syscall3(int,sys_inotify_add_watch,int,fd,const char *,pathname,uint32_t,mask)
281 #endif
282 #if defined(TARGET_NR_inotify_rm_watch) && defined(__NR_inotify_rm_watch)
283 _syscall2(int,sys_inotify_rm_watch,int,fd,uint32_t,wd)
284 #endif
285 #if defined(USE_NPTL)
286 #if defined(TARGET_NR_futex) && defined(__NR_futex)
287 _syscall6(int,sys_futex,int *,uaddr,int,op,int,val,
288           const struct timespec *,timeout,int *,uaddr2,int,val3)
289 #endif
290 #endif
291
292 extern int personality(int);
293 extern int flock(int, int);
294 extern int setfsuid(int);
295 extern int setfsgid(int);
296 extern int setgroups(int, gid_t *);
297
298 #define ERRNO_TABLE_SIZE 1200
299
300 /* target_to_host_errno_table[] is initialized from
301  * host_to_target_errno_table[] in syscall_init(). */
302 static uint16_t target_to_host_errno_table[ERRNO_TABLE_SIZE] = {
303 };
304
305 /*
306  * This list is the union of errno values overridden in asm-<arch>/errno.h
307  * minus the errnos that are not actually generic to all archs.
308  */
309 static uint16_t host_to_target_errno_table[ERRNO_TABLE_SIZE] = {
310     [EIDRM]             = TARGET_EIDRM,
311     [ECHRNG]            = TARGET_ECHRNG,
312     [EL2NSYNC]          = TARGET_EL2NSYNC,
313     [EL3HLT]            = TARGET_EL3HLT,
314     [EL3RST]            = TARGET_EL3RST,
315     [ELNRNG]            = TARGET_ELNRNG,
316     [EUNATCH]           = TARGET_EUNATCH,
317     [ENOCSI]            = TARGET_ENOCSI,
318     [EL2HLT]            = TARGET_EL2HLT,
319     [EDEADLK]           = TARGET_EDEADLK,
320     [ENOLCK]            = TARGET_ENOLCK,
321     [EBADE]             = TARGET_EBADE,
322     [EBADR]             = TARGET_EBADR,
323     [EXFULL]            = TARGET_EXFULL,
324     [ENOANO]            = TARGET_ENOANO,
325     [EBADRQC]           = TARGET_EBADRQC,
326     [EBADSLT]           = TARGET_EBADSLT,
327     [EBFONT]            = TARGET_EBFONT,
328     [ENOSTR]            = TARGET_ENOSTR,
329     [ENODATA]           = TARGET_ENODATA,
330     [ETIME]             = TARGET_ETIME,
331     [ENOSR]             = TARGET_ENOSR,
332     [ENONET]            = TARGET_ENONET,
333     [ENOPKG]            = TARGET_ENOPKG,
334     [EREMOTE]           = TARGET_EREMOTE,
335     [ENOLINK]           = TARGET_ENOLINK,
336     [EADV]              = TARGET_EADV,
337     [ESRMNT]            = TARGET_ESRMNT,
338     [ECOMM]             = TARGET_ECOMM,
339     [EPROTO]            = TARGET_EPROTO,
340     [EDOTDOT]           = TARGET_EDOTDOT,
341     [EMULTIHOP]         = TARGET_EMULTIHOP,
342     [EBADMSG]           = TARGET_EBADMSG,
343     [ENAMETOOLONG]      = TARGET_ENAMETOOLONG,
344     [EOVERFLOW]         = TARGET_EOVERFLOW,
345     [ENOTUNIQ]          = TARGET_ENOTUNIQ,
346     [EBADFD]            = TARGET_EBADFD,
347     [EREMCHG]           = TARGET_EREMCHG,
348     [ELIBACC]           = TARGET_ELIBACC,
349     [ELIBBAD]           = TARGET_ELIBBAD,
350     [ELIBSCN]           = TARGET_ELIBSCN,
351     [ELIBMAX]           = TARGET_ELIBMAX,
352     [ELIBEXEC]          = TARGET_ELIBEXEC,
353     [EILSEQ]            = TARGET_EILSEQ,
354     [ENOSYS]            = TARGET_ENOSYS,
355     [ELOOP]             = TARGET_ELOOP,
356     [ERESTART]          = TARGET_ERESTART,
357     [ESTRPIPE]          = TARGET_ESTRPIPE,
358     [ENOTEMPTY]         = TARGET_ENOTEMPTY,
359     [EUSERS]            = TARGET_EUSERS,
360     [ENOTSOCK]          = TARGET_ENOTSOCK,
361     [EDESTADDRREQ]      = TARGET_EDESTADDRREQ,
362     [EMSGSIZE]          = TARGET_EMSGSIZE,
363     [EPROTOTYPE]        = TARGET_EPROTOTYPE,
364     [ENOPROTOOPT]       = TARGET_ENOPROTOOPT,
365     [EPROTONOSUPPORT]   = TARGET_EPROTONOSUPPORT,
366     [ESOCKTNOSUPPORT]   = TARGET_ESOCKTNOSUPPORT,
367     [EOPNOTSUPP]        = TARGET_EOPNOTSUPP,
368     [EPFNOSUPPORT]      = TARGET_EPFNOSUPPORT,
369     [EAFNOSUPPORT]      = TARGET_EAFNOSUPPORT,
370     [EADDRINUSE]        = TARGET_EADDRINUSE,
371     [EADDRNOTAVAIL]     = TARGET_EADDRNOTAVAIL,
372     [ENETDOWN]          = TARGET_ENETDOWN,
373     [ENETUNREACH]       = TARGET_ENETUNREACH,
374     [ENETRESET]         = TARGET_ENETRESET,
375     [ECONNABORTED]      = TARGET_ECONNABORTED,
376     [ECONNRESET]        = TARGET_ECONNRESET,
377     [ENOBUFS]           = TARGET_ENOBUFS,
378     [EISCONN]           = TARGET_EISCONN,
379     [ENOTCONN]          = TARGET_ENOTCONN,
380     [EUCLEAN]           = TARGET_EUCLEAN,
381     [ENOTNAM]           = TARGET_ENOTNAM,
382     [ENAVAIL]           = TARGET_ENAVAIL,
383     [EISNAM]            = TARGET_EISNAM,
384     [EREMOTEIO]         = TARGET_EREMOTEIO,
385     [ESHUTDOWN]         = TARGET_ESHUTDOWN,
386     [ETOOMANYREFS]      = TARGET_ETOOMANYREFS,
387     [ETIMEDOUT]         = TARGET_ETIMEDOUT,
388     [ECONNREFUSED]      = TARGET_ECONNREFUSED,
389     [EHOSTDOWN]         = TARGET_EHOSTDOWN,
390     [EHOSTUNREACH]      = TARGET_EHOSTUNREACH,
391     [EALREADY]          = TARGET_EALREADY,
392     [EINPROGRESS]       = TARGET_EINPROGRESS,
393     [ESTALE]            = TARGET_ESTALE,
394     [ECANCELED]         = TARGET_ECANCELED,
395     [ENOMEDIUM]         = TARGET_ENOMEDIUM,
396     [EMEDIUMTYPE]       = TARGET_EMEDIUMTYPE,
397 #ifdef ENOKEY
398     [ENOKEY]            = TARGET_ENOKEY,
399 #endif
400 #ifdef EKEYEXPIRED
401     [EKEYEXPIRED]       = TARGET_EKEYEXPIRED,
402 #endif
403 #ifdef EKEYREVOKED
404     [EKEYREVOKED]       = TARGET_EKEYREVOKED,
405 #endif
406 #ifdef EKEYREJECTED
407     [EKEYREJECTED]      = TARGET_EKEYREJECTED,
408 #endif
409 #ifdef EOWNERDEAD
410     [EOWNERDEAD]        = TARGET_EOWNERDEAD,
411 #endif
412 #ifdef ENOTRECOVERABLE
413     [ENOTRECOVERABLE]   = TARGET_ENOTRECOVERABLE,
414 #endif
415 };
416
417 static inline int host_to_target_errno(int err)
418 {
419     if(host_to_target_errno_table[err])
420         return host_to_target_errno_table[err];
421     return err;
422 }
423
424 static inline int target_to_host_errno(int err)
425 {
426     if (target_to_host_errno_table[err])
427         return target_to_host_errno_table[err];
428     return err;
429 }
430
431 static inline abi_long get_errno(abi_long ret)
432 {
433     if (ret == -1)
434         return -host_to_target_errno(errno);
435     else
436         return ret;
437 }
438
439 static inline int is_error(abi_long ret)
440 {
441     return (abi_ulong)ret >= (abi_ulong)(-4096);
442 }
443
444 char *target_strerror(int err)
445 {
446     return strerror(target_to_host_errno(err));
447 }
448
449 static abi_ulong target_brk;
450 static abi_ulong target_original_brk;
451
452 void target_set_brk(abi_ulong new_brk)
453 {
454     target_original_brk = target_brk = HOST_PAGE_ALIGN(new_brk);
455 }
456
457 /* do_brk() must return target values and target errnos. */
458 abi_long do_brk(abi_ulong new_brk)
459 {
460     abi_ulong brk_page;
461     abi_long mapped_addr;
462     int new_alloc_size;
463
464     if (!new_brk)
465         return target_brk;
466     if (new_brk < target_original_brk)
467         return target_brk;
468
469     brk_page = HOST_PAGE_ALIGN(target_brk);
470
471     /* If the new brk is less than this, set it and we're done... */
472     if (new_brk < brk_page) {
473         target_brk = new_brk;
474         return target_brk;
475     }
476
477     /* We need to allocate more memory after the brk... */
478     new_alloc_size = HOST_PAGE_ALIGN(new_brk - brk_page + 1);
479     mapped_addr = get_errno(target_mmap(brk_page, new_alloc_size,
480                                         PROT_READ|PROT_WRITE,
481                                         MAP_ANON|MAP_FIXED|MAP_PRIVATE, 0, 0));
482
483     if (!is_error(mapped_addr))
484         target_brk = new_brk;
485     
486     return target_brk;
487 }
488
489 static inline abi_long copy_from_user_fdset(fd_set *fds,
490                                             abi_ulong target_fds_addr,
491                                             int n)
492 {
493     int i, nw, j, k;
494     abi_ulong b, *target_fds;
495
496     nw = (n + TARGET_ABI_BITS - 1) / TARGET_ABI_BITS;
497     if (!(target_fds = lock_user(VERIFY_READ,
498                                  target_fds_addr,
499                                  sizeof(abi_ulong) * nw,
500                                  1)))
501         return -TARGET_EFAULT;
502
503     FD_ZERO(fds);
504     k = 0;
505     for (i = 0; i < nw; i++) {
506         /* grab the abi_ulong */
507         __get_user(b, &target_fds[i]);
508         for (j = 0; j < TARGET_ABI_BITS; j++) {
509             /* check the bit inside the abi_ulong */
510             if ((b >> j) & 1)
511                 FD_SET(k, fds);
512             k++;
513         }
514     }
515
516     unlock_user(target_fds, target_fds_addr, 0);
517
518     return 0;
519 }
520
521 static inline abi_long copy_to_user_fdset(abi_ulong target_fds_addr,
522                                           const fd_set *fds,
523                                           int n)
524 {
525     int i, nw, j, k;
526     abi_long v;
527     abi_ulong *target_fds;
528
529     nw = (n + TARGET_ABI_BITS - 1) / TARGET_ABI_BITS;
530     if (!(target_fds = lock_user(VERIFY_WRITE,
531                                  target_fds_addr,
532                                  sizeof(abi_ulong) * nw,
533                                  0)))
534         return -TARGET_EFAULT;
535
536     k = 0;
537     for (i = 0; i < nw; i++) {
538         v = 0;
539         for (j = 0; j < TARGET_ABI_BITS; j++) {
540             v |= ((FD_ISSET(k, fds) != 0) << j);
541             k++;
542         }
543         __put_user(v, &target_fds[i]);
544     }
545
546     unlock_user(target_fds, target_fds_addr, sizeof(abi_ulong) * nw);
547
548     return 0;
549 }
550
551 #if defined(__alpha__)
552 #define HOST_HZ 1024
553 #else
554 #define HOST_HZ 100
555 #endif
556
557 static inline abi_long host_to_target_clock_t(long ticks)
558 {
559 #if HOST_HZ == TARGET_HZ
560     return ticks;
561 #else
562     return ((int64_t)ticks * TARGET_HZ) / HOST_HZ;
563 #endif
564 }
565
566 static inline abi_long host_to_target_rusage(abi_ulong target_addr,
567                                              const struct rusage *rusage)
568 {
569     struct target_rusage *target_rusage;
570
571     if (!lock_user_struct(VERIFY_WRITE, target_rusage, target_addr, 0))
572         return -TARGET_EFAULT;
573     target_rusage->ru_utime.tv_sec = tswapl(rusage->ru_utime.tv_sec);
574     target_rusage->ru_utime.tv_usec = tswapl(rusage->ru_utime.tv_usec);
575     target_rusage->ru_stime.tv_sec = tswapl(rusage->ru_stime.tv_sec);
576     target_rusage->ru_stime.tv_usec = tswapl(rusage->ru_stime.tv_usec);
577     target_rusage->ru_maxrss = tswapl(rusage->ru_maxrss);
578     target_rusage->ru_ixrss = tswapl(rusage->ru_ixrss);
579     target_rusage->ru_idrss = tswapl(rusage->ru_idrss);
580     target_rusage->ru_isrss = tswapl(rusage->ru_isrss);
581     target_rusage->ru_minflt = tswapl(rusage->ru_minflt);
582     target_rusage->ru_majflt = tswapl(rusage->ru_majflt);
583     target_rusage->ru_nswap = tswapl(rusage->ru_nswap);
584     target_rusage->ru_inblock = tswapl(rusage->ru_inblock);
585     target_rusage->ru_oublock = tswapl(rusage->ru_oublock);
586     target_rusage->ru_msgsnd = tswapl(rusage->ru_msgsnd);
587     target_rusage->ru_msgrcv = tswapl(rusage->ru_msgrcv);
588     target_rusage->ru_nsignals = tswapl(rusage->ru_nsignals);
589     target_rusage->ru_nvcsw = tswapl(rusage->ru_nvcsw);
590     target_rusage->ru_nivcsw = tswapl(rusage->ru_nivcsw);
591     unlock_user_struct(target_rusage, target_addr, 1);
592
593     return 0;
594 }
595
596 static inline abi_long copy_from_user_timeval(struct timeval *tv,
597                                               abi_ulong target_tv_addr)
598 {
599     struct target_timeval *target_tv;
600
601     if (!lock_user_struct(VERIFY_READ, target_tv, target_tv_addr, 1))
602         return -TARGET_EFAULT;
603
604     __get_user(tv->tv_sec, &target_tv->tv_sec);
605     __get_user(tv->tv_usec, &target_tv->tv_usec);
606
607     unlock_user_struct(target_tv, target_tv_addr, 0);
608
609     return 0;
610 }
611
612 static inline abi_long copy_to_user_timeval(abi_ulong target_tv_addr,
613                                             const struct timeval *tv)
614 {
615     struct target_timeval *target_tv;
616
617     if (!lock_user_struct(VERIFY_WRITE, target_tv, target_tv_addr, 0))
618         return -TARGET_EFAULT;
619
620     __put_user(tv->tv_sec, &target_tv->tv_sec);
621     __put_user(tv->tv_usec, &target_tv->tv_usec);
622
623     unlock_user_struct(target_tv, target_tv_addr, 1);
624
625     return 0;
626 }
627
628
629 /* do_select() must return target values and target errnos. */
630 static abi_long do_select(int n,
631                           abi_ulong rfd_addr, abi_ulong wfd_addr,
632                           abi_ulong efd_addr, abi_ulong target_tv_addr)
633 {
634     fd_set rfds, wfds, efds;
635     fd_set *rfds_ptr, *wfds_ptr, *efds_ptr;
636     struct timeval tv, *tv_ptr;
637     abi_long ret;
638
639     if (rfd_addr) {
640         if (copy_from_user_fdset(&rfds, rfd_addr, n))
641             return -TARGET_EFAULT;
642         rfds_ptr = &rfds;
643     } else {
644         rfds_ptr = NULL;
645     }
646     if (wfd_addr) {
647         if (copy_from_user_fdset(&wfds, wfd_addr, n))
648             return -TARGET_EFAULT;
649         wfds_ptr = &wfds;
650     } else {
651         wfds_ptr = NULL;
652     }
653     if (efd_addr) {
654         if (copy_from_user_fdset(&efds, efd_addr, n))
655             return -TARGET_EFAULT;
656         efds_ptr = &efds;
657     } else {
658         efds_ptr = NULL;
659     }
660
661     if (target_tv_addr) {
662         if (copy_from_user_timeval(&tv, target_tv_addr))
663             return -TARGET_EFAULT;
664         tv_ptr = &tv;
665     } else {
666         tv_ptr = NULL;
667     }
668
669     ret = get_errno(select(n, rfds_ptr, wfds_ptr, efds_ptr, tv_ptr));
670
671     if (!is_error(ret)) {
672         if (rfd_addr && copy_to_user_fdset(rfd_addr, &rfds, n))
673             return -TARGET_EFAULT;
674         if (wfd_addr && copy_to_user_fdset(wfd_addr, &wfds, n))
675             return -TARGET_EFAULT;
676         if (efd_addr && copy_to_user_fdset(efd_addr, &efds, n))
677             return -TARGET_EFAULT;
678
679         if (target_tv_addr && copy_to_user_timeval(target_tv_addr, &tv))
680             return -TARGET_EFAULT;
681     }
682
683     return ret;
684 }
685
686 static inline abi_long target_to_host_sockaddr(struct sockaddr *addr,
687                                                abi_ulong target_addr,
688                                                socklen_t len)
689 {
690     struct target_sockaddr *target_saddr;
691
692     target_saddr = lock_user(VERIFY_READ, target_addr, len, 1);
693     if (!target_saddr)
694         return -TARGET_EFAULT;
695     memcpy(addr, target_saddr, len);
696     addr->sa_family = tswap16(target_saddr->sa_family);
697     unlock_user(target_saddr, target_addr, 0);
698
699     return 0;
700 }
701
702 static inline abi_long host_to_target_sockaddr(abi_ulong target_addr,
703                                                struct sockaddr *addr,
704                                                socklen_t len)
705 {
706     struct target_sockaddr *target_saddr;
707
708     target_saddr = lock_user(VERIFY_WRITE, target_addr, len, 0);
709     if (!target_saddr)
710         return -TARGET_EFAULT;
711     memcpy(target_saddr, addr, len);
712     target_saddr->sa_family = tswap16(addr->sa_family);
713     unlock_user(target_saddr, target_addr, len);
714
715     return 0;
716 }
717
718 /* ??? Should this also swap msgh->name?  */
719 static inline abi_long target_to_host_cmsg(struct msghdr *msgh,
720                                            struct target_msghdr *target_msgh)
721 {
722     struct cmsghdr *cmsg = CMSG_FIRSTHDR(msgh);
723     abi_long msg_controllen;
724     abi_ulong target_cmsg_addr;
725     struct target_cmsghdr *target_cmsg;
726     socklen_t space = 0;
727     
728     msg_controllen = tswapl(target_msgh->msg_controllen);
729     if (msg_controllen < sizeof (struct target_cmsghdr)) 
730         goto the_end;
731     target_cmsg_addr = tswapl(target_msgh->msg_control);
732     target_cmsg = lock_user(VERIFY_READ, target_cmsg_addr, msg_controllen, 1);
733     if (!target_cmsg)
734         return -TARGET_EFAULT;
735
736     while (cmsg && target_cmsg) {
737         void *data = CMSG_DATA(cmsg);
738         void *target_data = TARGET_CMSG_DATA(target_cmsg);
739
740         int len = tswapl(target_cmsg->cmsg_len)
741                   - TARGET_CMSG_ALIGN(sizeof (struct target_cmsghdr));
742
743         space += CMSG_SPACE(len);
744         if (space > msgh->msg_controllen) {
745             space -= CMSG_SPACE(len);
746             gemu_log("Host cmsg overflow\n");
747             break;
748         }
749
750         cmsg->cmsg_level = tswap32(target_cmsg->cmsg_level);
751         cmsg->cmsg_type = tswap32(target_cmsg->cmsg_type);
752         cmsg->cmsg_len = CMSG_LEN(len);
753
754         if (cmsg->cmsg_level != TARGET_SOL_SOCKET || cmsg->cmsg_type != SCM_RIGHTS) {
755             gemu_log("Unsupported ancillary data: %d/%d\n", cmsg->cmsg_level, cmsg->cmsg_type);
756             memcpy(data, target_data, len);
757         } else {
758             int *fd = (int *)data;
759             int *target_fd = (int *)target_data;
760             int i, numfds = len / sizeof(int);
761
762             for (i = 0; i < numfds; i++)
763                 fd[i] = tswap32(target_fd[i]);
764         }
765
766         cmsg = CMSG_NXTHDR(msgh, cmsg);
767         target_cmsg = TARGET_CMSG_NXTHDR(target_msgh, target_cmsg);
768     }
769     unlock_user(target_cmsg, target_cmsg_addr, 0);
770  the_end:
771     msgh->msg_controllen = space;
772     return 0;
773 }
774
775 /* ??? Should this also swap msgh->name?  */
776 static inline abi_long host_to_target_cmsg(struct target_msghdr *target_msgh,
777                                            struct msghdr *msgh)
778 {
779     struct cmsghdr *cmsg = CMSG_FIRSTHDR(msgh);
780     abi_long msg_controllen;
781     abi_ulong target_cmsg_addr;
782     struct target_cmsghdr *target_cmsg;
783     socklen_t space = 0;
784
785     msg_controllen = tswapl(target_msgh->msg_controllen);
786     if (msg_controllen < sizeof (struct target_cmsghdr)) 
787         goto the_end;
788     target_cmsg_addr = tswapl(target_msgh->msg_control);
789     target_cmsg = lock_user(VERIFY_WRITE, target_cmsg_addr, msg_controllen, 0);
790     if (!target_cmsg)
791         return -TARGET_EFAULT;
792
793     while (cmsg && target_cmsg) {
794         void *data = CMSG_DATA(cmsg);
795         void *target_data = TARGET_CMSG_DATA(target_cmsg);
796
797         int len = cmsg->cmsg_len - CMSG_ALIGN(sizeof (struct cmsghdr));
798
799         space += TARGET_CMSG_SPACE(len);
800         if (space > msg_controllen) {
801             space -= TARGET_CMSG_SPACE(len);
802             gemu_log("Target cmsg overflow\n");
803             break;
804         }
805
806         target_cmsg->cmsg_level = tswap32(cmsg->cmsg_level);
807         target_cmsg->cmsg_type = tswap32(cmsg->cmsg_type);
808         target_cmsg->cmsg_len = tswapl(TARGET_CMSG_LEN(len));
809
810         if (cmsg->cmsg_level != TARGET_SOL_SOCKET || cmsg->cmsg_type != SCM_RIGHTS) {
811             gemu_log("Unsupported ancillary data: %d/%d\n", cmsg->cmsg_level, cmsg->cmsg_type);
812             memcpy(target_data, data, len);
813         } else {
814             int *fd = (int *)data;
815             int *target_fd = (int *)target_data;
816             int i, numfds = len / sizeof(int);
817
818             for (i = 0; i < numfds; i++)
819                 target_fd[i] = tswap32(fd[i]);
820         }
821
822         cmsg = CMSG_NXTHDR(msgh, cmsg);
823         target_cmsg = TARGET_CMSG_NXTHDR(target_msgh, target_cmsg);
824     }
825     unlock_user(target_cmsg, target_cmsg_addr, space);
826  the_end:
827     target_msgh->msg_controllen = tswapl(space);
828     return 0;
829 }
830
831 /* do_setsockopt() Must return target values and target errnos. */
832 static abi_long do_setsockopt(int sockfd, int level, int optname,
833                               abi_ulong optval_addr, socklen_t optlen)
834 {
835     abi_long ret;
836     int val;
837
838     switch(level) {
839     case SOL_TCP:
840         /* TCP options all take an 'int' value.  */
841         if (optlen < sizeof(uint32_t))
842             return -TARGET_EINVAL;
843
844         if (get_user_u32(val, optval_addr))
845             return -TARGET_EFAULT;
846         ret = get_errno(setsockopt(sockfd, level, optname, &val, sizeof(val)));
847         break;
848     case SOL_IP:
849         switch(optname) {
850         case IP_TOS:
851         case IP_TTL:
852         case IP_HDRINCL:
853         case IP_ROUTER_ALERT:
854         case IP_RECVOPTS:
855         case IP_RETOPTS:
856         case IP_PKTINFO:
857         case IP_MTU_DISCOVER:
858         case IP_RECVERR:
859         case IP_RECVTOS:
860 #ifdef IP_FREEBIND
861         case IP_FREEBIND:
862 #endif
863         case IP_MULTICAST_TTL:
864         case IP_MULTICAST_LOOP:
865             val = 0;
866             if (optlen >= sizeof(uint32_t)) {
867                 if (get_user_u32(val, optval_addr))
868                     return -TARGET_EFAULT;
869             } else if (optlen >= 1) {
870                 if (get_user_u8(val, optval_addr))
871                     return -TARGET_EFAULT;
872             }
873             ret = get_errno(setsockopt(sockfd, level, optname, &val, sizeof(val)));
874             break;
875         default:
876             goto unimplemented;
877         }
878         break;
879     case TARGET_SOL_SOCKET:
880         switch (optname) {
881             /* Options with 'int' argument.  */
882         case TARGET_SO_DEBUG:
883                 optname = SO_DEBUG;
884                 break;
885         case TARGET_SO_REUSEADDR:
886                 optname = SO_REUSEADDR;
887                 break;
888         case TARGET_SO_TYPE:
889                 optname = SO_TYPE;
890                 break;
891         case TARGET_SO_ERROR:
892                 optname = SO_ERROR;
893                 break;
894         case TARGET_SO_DONTROUTE:
895                 optname = SO_DONTROUTE;
896                 break;
897         case TARGET_SO_BROADCAST:
898                 optname = SO_BROADCAST;
899                 break;
900         case TARGET_SO_SNDBUF:
901                 optname = SO_SNDBUF;
902                 break;
903         case TARGET_SO_RCVBUF:
904                 optname = SO_RCVBUF;
905                 break;
906         case TARGET_SO_KEEPALIVE:
907                 optname = SO_KEEPALIVE;
908                 break;
909         case TARGET_SO_OOBINLINE:
910                 optname = SO_OOBINLINE;
911                 break;
912         case TARGET_SO_NO_CHECK:
913                 optname = SO_NO_CHECK;
914                 break;
915         case TARGET_SO_PRIORITY:
916                 optname = SO_PRIORITY;
917                 break;
918 #ifdef SO_BSDCOMPAT
919         case TARGET_SO_BSDCOMPAT:
920                 optname = SO_BSDCOMPAT;
921                 break;
922 #endif
923         case TARGET_SO_PASSCRED:
924                 optname = SO_PASSCRED;
925                 break;
926         case TARGET_SO_TIMESTAMP:
927                 optname = SO_TIMESTAMP;
928                 break;
929         case TARGET_SO_RCVLOWAT:
930                 optname = SO_RCVLOWAT;
931                 break;
932         case TARGET_SO_RCVTIMEO:
933                 optname = SO_RCVTIMEO;
934                 break;
935         case TARGET_SO_SNDTIMEO:
936                 optname = SO_SNDTIMEO;
937                 break;
938             break;
939         default:
940             goto unimplemented;
941         }
942         if (optlen < sizeof(uint32_t))
943             return -TARGET_EINVAL;
944
945         if (get_user_u32(val, optval_addr))
946             return -TARGET_EFAULT;
947         ret = get_errno(setsockopt(sockfd, SOL_SOCKET, optname, &val, sizeof(val)));
948         break;
949     default:
950     unimplemented:
951         gemu_log("Unsupported setsockopt level=%d optname=%d \n", level, optname);
952         ret = -TARGET_ENOPROTOOPT;
953     }
954     return ret;
955 }
956
957 /* do_getsockopt() Must return target values and target errnos. */
958 static abi_long do_getsockopt(int sockfd, int level, int optname,
959                               abi_ulong optval_addr, abi_ulong optlen)
960 {
961     abi_long ret;
962     int len, val;
963     socklen_t lv;
964
965     switch(level) {
966     case TARGET_SOL_SOCKET:
967         level = SOL_SOCKET;
968         switch (optname) {
969         case TARGET_SO_LINGER:
970         case TARGET_SO_RCVTIMEO:
971         case TARGET_SO_SNDTIMEO:
972         case TARGET_SO_PEERCRED:
973         case TARGET_SO_PEERNAME:
974             /* These don't just return a single integer */
975             goto unimplemented;
976         default:
977             goto int_case;
978         }
979         break;
980     case SOL_TCP:
981         /* TCP options all take an 'int' value.  */
982     int_case:
983         if (get_user_u32(len, optlen))
984             return -TARGET_EFAULT;
985         if (len < 0)
986             return -TARGET_EINVAL;
987         lv = sizeof(int);
988         ret = get_errno(getsockopt(sockfd, level, optname, &val, &lv));
989         if (ret < 0)
990             return ret;
991         val = tswap32(val);
992         if (len > lv)
993             len = lv;
994         if (len == 4) {
995             if (put_user_u32(val, optval_addr))
996                 return -TARGET_EFAULT;
997         } else {
998             if (put_user_u8(val, optval_addr))
999                 return -TARGET_EFAULT;
1000         }
1001         if (put_user_u32(len, optlen))
1002             return -TARGET_EFAULT;
1003         break;
1004     case SOL_IP:
1005         switch(optname) {
1006         case IP_TOS:
1007         case IP_TTL:
1008         case IP_HDRINCL:
1009         case IP_ROUTER_ALERT:
1010         case IP_RECVOPTS:
1011         case IP_RETOPTS:
1012         case IP_PKTINFO:
1013         case IP_MTU_DISCOVER:
1014         case IP_RECVERR:
1015         case IP_RECVTOS:
1016 #ifdef IP_FREEBIND
1017         case IP_FREEBIND:
1018 #endif
1019         case IP_MULTICAST_TTL:
1020         case IP_MULTICAST_LOOP:
1021             if (get_user_u32(len, optlen))
1022                 return -TARGET_EFAULT;
1023             if (len < 0)
1024                 return -TARGET_EINVAL;
1025             lv = sizeof(int);
1026             ret = get_errno(getsockopt(sockfd, level, optname, &val, &lv));
1027             if (ret < 0)
1028                 return ret;
1029             if (len < sizeof(int) && len > 0 && val >= 0 && val < 255) {
1030                 len = 1;
1031                 if (put_user_u32(len, optlen)
1032                     || put_user_u8(val, optval_addr))
1033                     return -TARGET_EFAULT;
1034             } else {
1035                 if (len > sizeof(int))
1036                     len = sizeof(int);
1037                 if (put_user_u32(len, optlen)
1038                     || put_user_u32(val, optval_addr))
1039                     return -TARGET_EFAULT;
1040             }
1041             break;
1042         default:
1043             ret = -TARGET_ENOPROTOOPT;
1044             break;
1045         }
1046         break;
1047     default:
1048     unimplemented:
1049         gemu_log("getsockopt level=%d optname=%d not yet supported\n",
1050                  level, optname);
1051         ret = -TARGET_EOPNOTSUPP;
1052         break;
1053     }
1054     return ret;
1055 }
1056
1057 /* FIXME
1058  * lock_iovec()/unlock_iovec() have a return code of 0 for success where
1059  * other lock functions have a return code of 0 for failure.
1060  */
1061 static abi_long lock_iovec(int type, struct iovec *vec, abi_ulong target_addr,
1062                            int count, int copy)
1063 {
1064     struct target_iovec *target_vec;
1065     abi_ulong base;
1066     int i, j;
1067
1068     target_vec = lock_user(VERIFY_READ, target_addr, count * sizeof(struct target_iovec), 1);
1069     if (!target_vec)
1070         return -TARGET_EFAULT;
1071     for(i = 0;i < count; i++) {
1072         base = tswapl(target_vec[i].iov_base);
1073         vec[i].iov_len = tswapl(target_vec[i].iov_len);
1074         if (vec[i].iov_len != 0) {
1075             vec[i].iov_base = lock_user(type, base, vec[i].iov_len, copy);
1076             if (!vec[i].iov_base && vec[i].iov_len) 
1077                 goto fail;
1078         } else {
1079             /* zero length pointer is ignored */
1080             vec[i].iov_base = NULL;
1081         }
1082     }
1083     unlock_user (target_vec, target_addr, 0);
1084     return 0;
1085  fail:
1086     /* failure - unwind locks */
1087     for (j = 0; j < i; j++) {
1088         base = tswapl(target_vec[j].iov_base);
1089         unlock_user(vec[j].iov_base, base, 0);
1090     }
1091     unlock_user (target_vec, target_addr, 0);
1092     return -TARGET_EFAULT;
1093 }
1094
1095 static abi_long unlock_iovec(struct iovec *vec, abi_ulong target_addr,
1096                              int count, int copy)
1097 {
1098     struct target_iovec *target_vec;
1099     abi_ulong base;
1100     int i;
1101
1102     target_vec = lock_user(VERIFY_READ, target_addr, count * sizeof(struct target_iovec), 1);
1103     if (!target_vec)
1104         return -TARGET_EFAULT;
1105     for(i = 0;i < count; i++) {
1106         base = tswapl(target_vec[i].iov_base);
1107         unlock_user(vec[i].iov_base, base, copy ? vec[i].iov_len : 0);
1108     }
1109     unlock_user (target_vec, target_addr, 0);
1110
1111     return 0;
1112 }
1113
1114 /* do_socket() Must return target values and target errnos. */
1115 static abi_long do_socket(int domain, int type, int protocol)
1116 {
1117 #if defined(TARGET_MIPS)
1118     switch(type) {
1119     case TARGET_SOCK_DGRAM:
1120         type = SOCK_DGRAM;
1121         break;
1122     case TARGET_SOCK_STREAM:
1123         type = SOCK_STREAM;
1124         break;
1125     case TARGET_SOCK_RAW:
1126         type = SOCK_RAW;
1127         break;
1128     case TARGET_SOCK_RDM:
1129         type = SOCK_RDM;
1130         break;
1131     case TARGET_SOCK_SEQPACKET:
1132         type = SOCK_SEQPACKET;
1133         break;
1134     case TARGET_SOCK_PACKET:
1135         type = SOCK_PACKET;
1136         break;
1137     }
1138 #endif
1139     if (domain == PF_NETLINK)
1140         return -EAFNOSUPPORT; /* do not NETLINK socket connections possible */
1141     return get_errno(socket(domain, type, protocol));
1142 }
1143
1144 /* do_bind() Must return target values and target errnos. */
1145 static abi_long do_bind(int sockfd, abi_ulong target_addr,
1146                         socklen_t addrlen)
1147 {
1148     void *addr = alloca(addrlen);
1149
1150     target_to_host_sockaddr(addr, target_addr, addrlen);
1151     return get_errno(bind(sockfd, addr, addrlen));
1152 }
1153
1154 /* do_connect() Must return target values and target errnos. */
1155 static abi_long do_connect(int sockfd, abi_ulong target_addr,
1156                            socklen_t addrlen)
1157 {
1158     void *addr = alloca(addrlen);
1159
1160     target_to_host_sockaddr(addr, target_addr, addrlen);
1161     return get_errno(connect(sockfd, addr, addrlen));
1162 }
1163
1164 /* do_sendrecvmsg() Must return target values and target errnos. */
1165 static abi_long do_sendrecvmsg(int fd, abi_ulong target_msg,
1166                                int flags, int send)
1167 {
1168     abi_long ret;
1169     struct target_msghdr *msgp;
1170     struct msghdr msg;
1171     int count;
1172     struct iovec *vec;
1173     abi_ulong target_vec;
1174
1175     /* FIXME */
1176     if (!lock_user_struct(send ? VERIFY_READ : VERIFY_WRITE,
1177                           msgp,
1178                           target_msg,
1179                           send ? 1 : 0))
1180         return -TARGET_EFAULT;
1181     if (msgp->msg_name) {
1182         msg.msg_namelen = tswap32(msgp->msg_namelen);
1183         msg.msg_name = alloca(msg.msg_namelen);
1184         target_to_host_sockaddr(msg.msg_name, tswapl(msgp->msg_name),
1185                                 msg.msg_namelen);
1186     } else {
1187         msg.msg_name = NULL;
1188         msg.msg_namelen = 0;
1189     }
1190     msg.msg_controllen = 2 * tswapl(msgp->msg_controllen);
1191     msg.msg_control = alloca(msg.msg_controllen);
1192     msg.msg_flags = tswap32(msgp->msg_flags);
1193
1194     count = tswapl(msgp->msg_iovlen);
1195     vec = alloca(count * sizeof(struct iovec));
1196     target_vec = tswapl(msgp->msg_iov);
1197     lock_iovec(send ? VERIFY_READ : VERIFY_WRITE, vec, target_vec, count, send);
1198     msg.msg_iovlen = count;
1199     msg.msg_iov = vec;
1200
1201     if (send) {
1202         ret = target_to_host_cmsg(&msg, msgp);
1203         if (ret == 0)
1204             ret = get_errno(sendmsg(fd, &msg, flags));
1205     } else {
1206         ret = get_errno(recvmsg(fd, &msg, flags));
1207         if (!is_error(ret))
1208             ret = host_to_target_cmsg(msgp, &msg);
1209     }
1210     unlock_iovec(vec, target_vec, count, !send);
1211     unlock_user_struct(msgp, target_msg, send ? 0 : 1);
1212     return ret;
1213 }
1214
1215 /* do_accept() Must return target values and target errnos. */
1216 static abi_long do_accept(int fd, abi_ulong target_addr,
1217                           abi_ulong target_addrlen_addr)
1218 {
1219     socklen_t addrlen;
1220     void *addr;
1221     abi_long ret;
1222
1223     if (get_user_u32(addrlen, target_addrlen_addr))
1224         return -TARGET_EFAULT;
1225
1226     addr = alloca(addrlen);
1227
1228     ret = get_errno(accept(fd, addr, &addrlen));
1229     if (!is_error(ret)) {
1230         host_to_target_sockaddr(target_addr, addr, addrlen);
1231         if (put_user_u32(addrlen, target_addrlen_addr))
1232             ret = -TARGET_EFAULT;
1233     }
1234     return ret;
1235 }
1236
1237 /* do_getpeername() Must return target values and target errnos. */
1238 static abi_long do_getpeername(int fd, abi_ulong target_addr,
1239                                abi_ulong target_addrlen_addr)
1240 {
1241     socklen_t addrlen;
1242     void *addr;
1243     abi_long ret;
1244
1245     if (get_user_u32(addrlen, target_addrlen_addr))
1246         return -TARGET_EFAULT;
1247
1248     addr = alloca(addrlen);
1249
1250     ret = get_errno(getpeername(fd, addr, &addrlen));
1251     if (!is_error(ret)) {
1252         host_to_target_sockaddr(target_addr, addr, addrlen);
1253         if (put_user_u32(addrlen, target_addrlen_addr))
1254             ret = -TARGET_EFAULT;
1255     }
1256     return ret;
1257 }
1258
1259 /* do_getsockname() Must return target values and target errnos. */
1260 static abi_long do_getsockname(int fd, abi_ulong target_addr,
1261                                abi_ulong target_addrlen_addr)
1262 {
1263     socklen_t addrlen;
1264     void *addr;
1265     abi_long ret;
1266
1267     if (get_user_u32(addrlen, target_addrlen_addr))
1268         return -TARGET_EFAULT;
1269
1270     addr = alloca(addrlen);
1271
1272     ret = get_errno(getsockname(fd, addr, &addrlen));
1273     if (!is_error(ret)) {
1274         host_to_target_sockaddr(target_addr, addr, addrlen);
1275         if (put_user_u32(addrlen, target_addrlen_addr))
1276             ret = -TARGET_EFAULT;
1277     }
1278     return ret;
1279 }
1280
1281 /* do_socketpair() Must return target values and target errnos. */
1282 static abi_long do_socketpair(int domain, int type, int protocol,
1283                               abi_ulong target_tab_addr)
1284 {
1285     int tab[2];
1286     abi_long ret;
1287
1288     ret = get_errno(socketpair(domain, type, protocol, tab));
1289     if (!is_error(ret)) {
1290         if (put_user_s32(tab[0], target_tab_addr)
1291             || put_user_s32(tab[1], target_tab_addr + sizeof(tab[0])))
1292             ret = -TARGET_EFAULT;
1293     }
1294     return ret;
1295 }
1296
1297 /* do_sendto() Must return target values and target errnos. */
1298 static abi_long do_sendto(int fd, abi_ulong msg, size_t len, int flags,
1299                           abi_ulong target_addr, socklen_t addrlen)
1300 {
1301     void *addr;
1302     void *host_msg;
1303     abi_long ret;
1304
1305     host_msg = lock_user(VERIFY_READ, msg, len, 1);
1306     if (!host_msg)
1307         return -TARGET_EFAULT;
1308     if (target_addr) {
1309         addr = alloca(addrlen);
1310         target_to_host_sockaddr(addr, target_addr, addrlen);
1311         ret = get_errno(sendto(fd, host_msg, len, flags, addr, addrlen));
1312     } else {
1313         ret = get_errno(send(fd, host_msg, len, flags));
1314     }
1315     unlock_user(host_msg, msg, 0);
1316     return ret;
1317 }
1318
1319 /* do_recvfrom() Must return target values and target errnos. */
1320 static abi_long do_recvfrom(int fd, abi_ulong msg, size_t len, int flags,
1321                             abi_ulong target_addr,
1322                             abi_ulong target_addrlen)
1323 {
1324     socklen_t addrlen;
1325     void *addr;
1326     void *host_msg;
1327     abi_long ret;
1328
1329     host_msg = lock_user(VERIFY_WRITE, msg, len, 0);
1330     if (!host_msg)
1331         return -TARGET_EFAULT;
1332     if (target_addr) {
1333         if (get_user_u32(addrlen, target_addrlen)) {
1334             ret = -TARGET_EFAULT;
1335             goto fail;
1336         }
1337         addr = alloca(addrlen);
1338         ret = get_errno(recvfrom(fd, host_msg, len, flags, addr, &addrlen));
1339     } else {
1340         addr = NULL; /* To keep compiler quiet.  */
1341         ret = get_errno(recv(fd, host_msg, len, flags));
1342     }
1343     if (!is_error(ret)) {
1344         if (target_addr) {
1345             host_to_target_sockaddr(target_addr, addr, addrlen);
1346             if (put_user_u32(addrlen, target_addrlen)) {
1347                 ret = -TARGET_EFAULT;
1348                 goto fail;
1349             }
1350         }
1351         unlock_user(host_msg, msg, len);
1352     } else {
1353 fail:
1354         unlock_user(host_msg, msg, 0);
1355     }
1356     return ret;
1357 }
1358
1359 #ifdef TARGET_NR_socketcall
1360 /* do_socketcall() Must return target values and target errnos. */
1361 static abi_long do_socketcall(int num, abi_ulong vptr)
1362 {
1363     abi_long ret;
1364     const int n = sizeof(abi_ulong);
1365
1366     switch(num) {
1367     case SOCKOP_socket:
1368         {
1369             int domain, type, protocol;
1370
1371             if (get_user_s32(domain, vptr)
1372                 || get_user_s32(type, vptr + n)
1373                 || get_user_s32(protocol, vptr + 2 * n))
1374                 return -TARGET_EFAULT;
1375
1376             ret = do_socket(domain, type, protocol);
1377         }
1378         break;
1379     case SOCKOP_bind:
1380         {
1381             int sockfd;
1382             abi_ulong target_addr;
1383             socklen_t addrlen;
1384
1385             if (get_user_s32(sockfd, vptr)
1386                 || get_user_ual(target_addr, vptr + n)
1387                 || get_user_u32(addrlen, vptr + 2 * n))
1388                 return -TARGET_EFAULT;
1389
1390             ret = do_bind(sockfd, target_addr, addrlen);
1391         }
1392         break;
1393     case SOCKOP_connect:
1394         {
1395             int sockfd;
1396             abi_ulong target_addr;
1397             socklen_t addrlen;
1398
1399             if (get_user_s32(sockfd, vptr)
1400                 || get_user_ual(target_addr, vptr + n)
1401                 || get_user_u32(addrlen, vptr + 2 * n))
1402                 return -TARGET_EFAULT;
1403
1404             ret = do_connect(sockfd, target_addr, addrlen);
1405         }
1406         break;
1407     case SOCKOP_listen:
1408         {
1409             int sockfd, backlog;
1410
1411             if (get_user_s32(sockfd, vptr)
1412                 || get_user_s32(backlog, vptr + n))
1413                 return -TARGET_EFAULT;
1414
1415             ret = get_errno(listen(sockfd, backlog));
1416         }
1417         break;
1418     case SOCKOP_accept:
1419         {
1420             int sockfd;
1421             abi_ulong target_addr, target_addrlen;
1422
1423             if (get_user_s32(sockfd, vptr)
1424                 || get_user_ual(target_addr, vptr + n)
1425                 || get_user_u32(target_addrlen, vptr + 2 * n))
1426                 return -TARGET_EFAULT;
1427
1428             ret = do_accept(sockfd, target_addr, target_addrlen);
1429         }
1430         break;
1431     case SOCKOP_getsockname:
1432         {
1433             int sockfd;
1434             abi_ulong target_addr, target_addrlen;
1435
1436             if (get_user_s32(sockfd, vptr)
1437                 || get_user_ual(target_addr, vptr + n)
1438                 || get_user_u32(target_addrlen, vptr + 2 * n))
1439                 return -TARGET_EFAULT;
1440
1441             ret = do_getsockname(sockfd, target_addr, target_addrlen);
1442         }
1443         break;
1444     case SOCKOP_getpeername:
1445         {
1446             int sockfd;
1447             abi_ulong target_addr, target_addrlen;
1448
1449             if (get_user_s32(sockfd, vptr)
1450                 || get_user_ual(target_addr, vptr + n)
1451                 || get_user_u32(target_addrlen, vptr + 2 * n))
1452                 return -TARGET_EFAULT;
1453
1454             ret = do_getpeername(sockfd, target_addr, target_addrlen);
1455         }
1456         break;
1457     case SOCKOP_socketpair:
1458         {
1459             int domain, type, protocol;
1460             abi_ulong tab;
1461
1462             if (get_user_s32(domain, vptr)
1463                 || get_user_s32(type, vptr + n)
1464                 || get_user_s32(protocol, vptr + 2 * n)
1465                 || get_user_ual(tab, vptr + 3 * n))
1466                 return -TARGET_EFAULT;
1467
1468             ret = do_socketpair(domain, type, protocol, tab);
1469         }
1470         break;
1471     case SOCKOP_send:
1472         {
1473             int sockfd;
1474             abi_ulong msg;
1475             size_t len;
1476             int flags;
1477
1478             if (get_user_s32(sockfd, vptr)
1479                 || get_user_ual(msg, vptr + n)
1480                 || get_user_ual(len, vptr + 2 * n)
1481                 || get_user_s32(flags, vptr + 3 * n))
1482                 return -TARGET_EFAULT;
1483
1484             ret = do_sendto(sockfd, msg, len, flags, 0, 0);
1485         }
1486         break;
1487     case SOCKOP_recv:
1488         {
1489             int sockfd;
1490             abi_ulong msg;
1491             size_t len;
1492             int flags;
1493
1494             if (get_user_s32(sockfd, vptr)
1495                 || get_user_ual(msg, vptr + n)
1496                 || get_user_ual(len, vptr + 2 * n)
1497                 || get_user_s32(flags, vptr + 3 * n))
1498                 return -TARGET_EFAULT;
1499
1500             ret = do_recvfrom(sockfd, msg, len, flags, 0, 0);
1501         }
1502         break;
1503     case SOCKOP_sendto:
1504         {
1505             int sockfd;
1506             abi_ulong msg;
1507             size_t len;
1508             int flags;
1509             abi_ulong addr;
1510             socklen_t addrlen;
1511
1512             if (get_user_s32(sockfd, vptr)
1513                 || get_user_ual(msg, vptr + n)
1514                 || get_user_ual(len, vptr + 2 * n)
1515                 || get_user_s32(flags, vptr + 3 * n)
1516                 || get_user_ual(addr, vptr + 4 * n)
1517                 || get_user_u32(addrlen, vptr + 5 * n))
1518                 return -TARGET_EFAULT;
1519
1520             ret = do_sendto(sockfd, msg, len, flags, addr, addrlen);
1521         }
1522         break;
1523     case SOCKOP_recvfrom:
1524         {
1525             int sockfd;
1526             abi_ulong msg;
1527             size_t len;
1528             int flags;
1529             abi_ulong addr;
1530             socklen_t addrlen;
1531
1532             if (get_user_s32(sockfd, vptr)
1533                 || get_user_ual(msg, vptr + n)
1534                 || get_user_ual(len, vptr + 2 * n)
1535                 || get_user_s32(flags, vptr + 3 * n)
1536                 || get_user_ual(addr, vptr + 4 * n)
1537                 || get_user_u32(addrlen, vptr + 5 * n))
1538                 return -TARGET_EFAULT;
1539
1540             ret = do_recvfrom(sockfd, msg, len, flags, addr, addrlen);
1541         }
1542         break;
1543     case SOCKOP_shutdown:
1544         {
1545             int sockfd, how;
1546
1547             if (get_user_s32(sockfd, vptr)
1548                 || get_user_s32(how, vptr + n))
1549                 return -TARGET_EFAULT;
1550
1551             ret = get_errno(shutdown(sockfd, how));
1552         }
1553         break;
1554     case SOCKOP_sendmsg:
1555     case SOCKOP_recvmsg:
1556         {
1557             int fd;
1558             abi_ulong target_msg;
1559             int flags;
1560
1561             if (get_user_s32(fd, vptr)
1562                 || get_user_ual(target_msg, vptr + n)
1563                 || get_user_s32(flags, vptr + 2 * n))
1564                 return -TARGET_EFAULT;
1565
1566             ret = do_sendrecvmsg(fd, target_msg, flags,
1567                                  (num == SOCKOP_sendmsg));
1568         }
1569         break;
1570     case SOCKOP_setsockopt:
1571         {
1572             int sockfd;
1573             int level;
1574             int optname;
1575             abi_ulong optval;
1576             socklen_t optlen;
1577
1578             if (get_user_s32(sockfd, vptr)
1579                 || get_user_s32(level, vptr + n)
1580                 || get_user_s32(optname, vptr + 2 * n)
1581                 || get_user_ual(optval, vptr + 3 * n)
1582                 || get_user_u32(optlen, vptr + 4 * n))
1583                 return -TARGET_EFAULT;
1584
1585             ret = do_setsockopt(sockfd, level, optname, optval, optlen);
1586         }
1587         break;
1588     case SOCKOP_getsockopt:
1589         {
1590             int sockfd;
1591             int level;
1592             int optname;
1593             abi_ulong optval;
1594             socklen_t optlen;
1595
1596             if (get_user_s32(sockfd, vptr)
1597                 || get_user_s32(level, vptr + n)
1598                 || get_user_s32(optname, vptr + 2 * n)
1599                 || get_user_ual(optval, vptr + 3 * n)
1600                 || get_user_u32(optlen, vptr + 4 * n))
1601                 return -TARGET_EFAULT;
1602
1603             ret = do_getsockopt(sockfd, level, optname, optval, optlen);
1604         }
1605         break;
1606     default:
1607         gemu_log("Unsupported socketcall: %d\n", num);
1608         ret = -TARGET_ENOSYS;
1609         break;
1610     }
1611     return ret;
1612 }
1613 #endif
1614
1615 #ifdef TARGET_NR_ipc
1616 #define N_SHM_REGIONS   32
1617
1618 static struct shm_region {
1619     abi_ulong   start;
1620     abi_ulong   size;
1621 } shm_regions[N_SHM_REGIONS];
1622
1623 struct target_ipc_perm
1624 {
1625     abi_long __key;
1626     abi_ulong uid;
1627     abi_ulong gid;
1628     abi_ulong cuid;
1629     abi_ulong cgid;
1630     unsigned short int mode;
1631     unsigned short int __pad1;
1632     unsigned short int __seq;
1633     unsigned short int __pad2;
1634     abi_ulong __unused1;
1635     abi_ulong __unused2;
1636 };
1637
1638 struct target_semid_ds
1639 {
1640   struct target_ipc_perm sem_perm;
1641   abi_ulong sem_otime;
1642   abi_ulong __unused1;
1643   abi_ulong sem_ctime;
1644   abi_ulong __unused2;
1645   abi_ulong sem_nsems;
1646   abi_ulong __unused3;
1647   abi_ulong __unused4;
1648 };
1649
1650 static inline abi_long target_to_host_ipc_perm(struct ipc_perm *host_ip,
1651                                                abi_ulong target_addr)
1652 {
1653     struct target_ipc_perm *target_ip;
1654     struct target_semid_ds *target_sd;
1655
1656     if (!lock_user_struct(VERIFY_READ, target_sd, target_addr, 1))
1657         return -TARGET_EFAULT;
1658     target_ip=&(target_sd->sem_perm);
1659     host_ip->__key = tswapl(target_ip->__key);
1660     host_ip->uid = tswapl(target_ip->uid);
1661     host_ip->gid = tswapl(target_ip->gid);
1662     host_ip->cuid = tswapl(target_ip->cuid);
1663     host_ip->cgid = tswapl(target_ip->cgid);
1664     host_ip->mode = tswapl(target_ip->mode);
1665     unlock_user_struct(target_sd, target_addr, 0);
1666     return 0;
1667 }
1668
1669 static inline abi_long host_to_target_ipc_perm(abi_ulong target_addr,
1670                                                struct ipc_perm *host_ip)
1671 {
1672     struct target_ipc_perm *target_ip;
1673     struct target_semid_ds *target_sd;
1674
1675     if (!lock_user_struct(VERIFY_WRITE, target_sd, target_addr, 0))
1676         return -TARGET_EFAULT;
1677     target_ip = &(target_sd->sem_perm);
1678     target_ip->__key = tswapl(host_ip->__key);
1679     target_ip->uid = tswapl(host_ip->uid);
1680     target_ip->gid = tswapl(host_ip->gid);
1681     target_ip->cuid = tswapl(host_ip->cuid);
1682     target_ip->cgid = tswapl(host_ip->cgid);
1683     target_ip->mode = tswapl(host_ip->mode);
1684     unlock_user_struct(target_sd, target_addr, 1);
1685     return 0;
1686 }
1687
1688 static inline abi_long target_to_host_semid_ds(struct semid_ds *host_sd,
1689                                                abi_ulong target_addr)
1690 {
1691     struct target_semid_ds *target_sd;
1692
1693     if (!lock_user_struct(VERIFY_READ, target_sd, target_addr, 1))
1694         return -TARGET_EFAULT;
1695     target_to_host_ipc_perm(&(host_sd->sem_perm),target_addr);
1696     host_sd->sem_nsems = tswapl(target_sd->sem_nsems);
1697     host_sd->sem_otime = tswapl(target_sd->sem_otime);
1698     host_sd->sem_ctime = tswapl(target_sd->sem_ctime);
1699     unlock_user_struct(target_sd, target_addr, 0);
1700     return 0;
1701 }
1702
1703 static inline abi_long host_to_target_semid_ds(abi_ulong target_addr,
1704                                                struct semid_ds *host_sd)
1705 {
1706     struct target_semid_ds *target_sd;
1707
1708     if (!lock_user_struct(VERIFY_WRITE, target_sd, target_addr, 0))
1709         return -TARGET_EFAULT;
1710     host_to_target_ipc_perm(target_addr,&(host_sd->sem_perm));
1711     target_sd->sem_nsems = tswapl(host_sd->sem_nsems);
1712     target_sd->sem_otime = tswapl(host_sd->sem_otime);
1713     target_sd->sem_ctime = tswapl(host_sd->sem_ctime);
1714     unlock_user_struct(target_sd, target_addr, 1);
1715     return 0;
1716 }
1717
1718 union semun {
1719         int val;
1720         struct semid_ds *buf;
1721         unsigned short *array;
1722 };
1723
1724 union target_semun {
1725         int val;
1726         abi_long buf;
1727         unsigned short int *array;
1728 };
1729
1730 static inline abi_long target_to_host_semun(int cmd,
1731                                             union semun *host_su,
1732                                             abi_ulong target_addr,
1733                                             struct semid_ds *ds)
1734 {
1735     union target_semun *target_su;
1736
1737     switch( cmd ) {
1738         case IPC_STAT:
1739         case IPC_SET:
1740            if (!lock_user_struct(VERIFY_READ, target_su, target_addr, 1))
1741                return -TARGET_EFAULT;
1742            target_to_host_semid_ds(ds,target_su->buf);
1743            host_su->buf = ds;
1744            unlock_user_struct(target_su, target_addr, 0);
1745            break;
1746         case GETVAL:
1747         case SETVAL:
1748            if (!lock_user_struct(VERIFY_READ, target_su, target_addr, 1))
1749                return -TARGET_EFAULT;
1750            host_su->val = tswapl(target_su->val);
1751            unlock_user_struct(target_su, target_addr, 0);
1752            break;
1753         case GETALL:
1754         case SETALL:
1755            if (!lock_user_struct(VERIFY_READ, target_su, target_addr, 1))
1756                return -TARGET_EFAULT;
1757            *host_su->array = tswap16(*target_su->array);
1758            unlock_user_struct(target_su, target_addr, 0);
1759            break;
1760         default:
1761            gemu_log("semun operation not fully supported: %d\n", (int)cmd);
1762     }
1763     return 0;
1764 }
1765
1766 static inline abi_long host_to_target_semun(int cmd,
1767                                             abi_ulong target_addr,
1768                                             union semun *host_su,
1769                                             struct semid_ds *ds)
1770 {
1771     union target_semun *target_su;
1772
1773     switch( cmd ) {
1774         case IPC_STAT:
1775         case IPC_SET:
1776            if (lock_user_struct(VERIFY_WRITE, target_su, target_addr, 0))
1777                return -TARGET_EFAULT;
1778            host_to_target_semid_ds(target_su->buf,ds);
1779            unlock_user_struct(target_su, target_addr, 1);
1780            break;
1781         case GETVAL:
1782         case SETVAL:
1783            if (lock_user_struct(VERIFY_WRITE, target_su, target_addr, 0))
1784                return -TARGET_EFAULT;
1785            target_su->val = tswapl(host_su->val);
1786            unlock_user_struct(target_su, target_addr, 1);
1787            break;
1788         case GETALL:
1789         case SETALL:
1790            if (lock_user_struct(VERIFY_WRITE, target_su, target_addr, 0))
1791                return -TARGET_EFAULT;
1792            *target_su->array = tswap16(*host_su->array);
1793            unlock_user_struct(target_su, target_addr, 1);
1794            break;
1795         default:
1796            gemu_log("semun operation not fully supported: %d\n", (int)cmd);
1797     }
1798     return 0;
1799 }
1800
1801 static inline abi_long do_semctl(int first, int second, int third,
1802                                  abi_long ptr)
1803 {
1804     union semun arg;
1805     struct semid_ds dsarg;
1806     int cmd = third&0xff;
1807     abi_long ret = 0;
1808
1809     switch( cmd ) {
1810         case GETVAL:
1811             target_to_host_semun(cmd,&arg,ptr,&dsarg);
1812             ret = get_errno(semctl(first, second, cmd, arg));
1813             host_to_target_semun(cmd,ptr,&arg,&dsarg);
1814             break;
1815         case SETVAL:
1816             target_to_host_semun(cmd,&arg,ptr,&dsarg);
1817             ret = get_errno(semctl(first, second, cmd, arg));
1818             host_to_target_semun(cmd,ptr,&arg,&dsarg);
1819             break;
1820         case GETALL:
1821             target_to_host_semun(cmd,&arg,ptr,&dsarg);
1822             ret = get_errno(semctl(first, second, cmd, arg));
1823             host_to_target_semun(cmd,ptr,&arg,&dsarg);
1824             break;
1825         case SETALL:
1826             target_to_host_semun(cmd,&arg,ptr,&dsarg);
1827             ret = get_errno(semctl(first, second, cmd, arg));
1828             host_to_target_semun(cmd,ptr,&arg,&dsarg);
1829             break;
1830         case IPC_STAT:
1831             target_to_host_semun(cmd,&arg,ptr,&dsarg);
1832             ret = get_errno(semctl(first, second, cmd, arg));
1833             host_to_target_semun(cmd,ptr,&arg,&dsarg);
1834             break;
1835         case IPC_SET:
1836             target_to_host_semun(cmd,&arg,ptr,&dsarg);
1837             ret = get_errno(semctl(first, second, cmd, arg));
1838             host_to_target_semun(cmd,ptr,&arg,&dsarg);
1839             break;
1840     default:
1841             ret = get_errno(semctl(first, second, cmd, arg));
1842     }
1843
1844     return ret;
1845 }
1846
1847 struct target_msqid_ds
1848 {
1849   struct target_ipc_perm msg_perm;
1850   abi_ulong msg_stime;
1851   abi_ulong __unused1;
1852   abi_ulong msg_rtime;
1853   abi_ulong __unused2;
1854   abi_ulong msg_ctime;
1855   abi_ulong __unused3;
1856   abi_ulong __msg_cbytes;
1857   abi_ulong msg_qnum;
1858   abi_ulong msg_qbytes;
1859   abi_ulong msg_lspid;
1860   abi_ulong msg_lrpid;
1861   abi_ulong __unused4;
1862   abi_ulong __unused5;
1863 };
1864
1865 static inline abi_long target_to_host_msqid_ds(struct msqid_ds *host_md,
1866                                                abi_ulong target_addr)
1867 {
1868     struct target_msqid_ds *target_md;
1869
1870     if (!lock_user_struct(VERIFY_READ, target_md, target_addr, 1))
1871         return -TARGET_EFAULT;
1872     target_to_host_ipc_perm(&(host_md->msg_perm),target_addr);
1873     host_md->msg_stime = tswapl(target_md->msg_stime);
1874     host_md->msg_rtime = tswapl(target_md->msg_rtime);
1875     host_md->msg_ctime = tswapl(target_md->msg_ctime);
1876     host_md->__msg_cbytes = tswapl(target_md->__msg_cbytes);
1877     host_md->msg_qnum = tswapl(target_md->msg_qnum);
1878     host_md->msg_qbytes = tswapl(target_md->msg_qbytes);
1879     host_md->msg_lspid = tswapl(target_md->msg_lspid);
1880     host_md->msg_lrpid = tswapl(target_md->msg_lrpid);
1881     unlock_user_struct(target_md, target_addr, 0);
1882     return 0;
1883 }
1884
1885 static inline abi_long host_to_target_msqid_ds(abi_ulong target_addr,
1886                                                struct msqid_ds *host_md)
1887 {
1888     struct target_msqid_ds *target_md;
1889
1890     if (!lock_user_struct(VERIFY_WRITE, target_md, target_addr, 0))
1891         return -TARGET_EFAULT;
1892     host_to_target_ipc_perm(target_addr,&(host_md->msg_perm));
1893     target_md->msg_stime = tswapl(host_md->msg_stime);
1894     target_md->msg_rtime = tswapl(host_md->msg_rtime);
1895     target_md->msg_ctime = tswapl(host_md->msg_ctime);
1896     target_md->__msg_cbytes = tswapl(host_md->__msg_cbytes);
1897     target_md->msg_qnum = tswapl(host_md->msg_qnum);
1898     target_md->msg_qbytes = tswapl(host_md->msg_qbytes);
1899     target_md->msg_lspid = tswapl(host_md->msg_lspid);
1900     target_md->msg_lrpid = tswapl(host_md->msg_lrpid);
1901     unlock_user_struct(target_md, target_addr, 1);
1902     return 0;
1903 }
1904
1905 static inline abi_long do_msgctl(int first, int second, abi_long ptr)
1906 {
1907     struct msqid_ds dsarg;
1908     int cmd = second&0xff;
1909     abi_long ret = 0;
1910     switch( cmd ) {
1911     case IPC_STAT:
1912     case IPC_SET:
1913         target_to_host_msqid_ds(&dsarg,ptr);
1914         ret = get_errno(msgctl(first, cmd, &dsarg));
1915         host_to_target_msqid_ds(ptr,&dsarg);
1916     default:
1917         ret = get_errno(msgctl(first, cmd, &dsarg));
1918     }
1919     return ret;
1920 }
1921
1922 struct target_msgbuf {
1923         abi_ulong mtype;
1924         char    mtext[1];
1925 };
1926
1927 static inline abi_long do_msgsnd(int msqid, abi_long msgp,
1928                                  unsigned int msgsz, int msgflg)
1929 {
1930     struct target_msgbuf *target_mb;
1931     struct msgbuf *host_mb;
1932     abi_long ret = 0;
1933
1934     if (!lock_user_struct(VERIFY_READ, target_mb, msgp, 0))
1935         return -TARGET_EFAULT;
1936     host_mb = malloc(msgsz+sizeof(long));
1937     host_mb->mtype = tswapl(target_mb->mtype);
1938     memcpy(host_mb->mtext,target_mb->mtext,msgsz);
1939     ret = get_errno(msgsnd(msqid, host_mb, msgsz, msgflg));
1940     free(host_mb);
1941     unlock_user_struct(target_mb, msgp, 0);
1942
1943     return ret;
1944 }
1945
1946 static inline abi_long do_msgrcv(int msqid, abi_long msgp,
1947                                  unsigned int msgsz, int msgtype,
1948                                  int msgflg)
1949 {
1950     struct target_msgbuf *target_mb;
1951     char *target_mtext;
1952     struct msgbuf *host_mb;
1953     abi_long ret = 0;
1954
1955     if (!lock_user_struct(VERIFY_WRITE, target_mb, msgp, 0))
1956         return -TARGET_EFAULT;
1957     host_mb = malloc(msgsz+sizeof(long));
1958     ret = get_errno(msgrcv(msqid, host_mb, msgsz, 1, msgflg));
1959     if (ret > 0) {
1960         abi_ulong target_mtext_addr = msgp + sizeof(abi_ulong);
1961         target_mtext = lock_user(VERIFY_WRITE, target_mtext_addr, ret, 0);
1962         if (!target_mtext) {
1963             ret = -TARGET_EFAULT;
1964             goto end;
1965         }
1966         memcpy(target_mb->mtext, host_mb->mtext, ret);
1967         unlock_user(target_mtext, target_mtext_addr, ret);
1968     }
1969     target_mb->mtype = tswapl(host_mb->mtype);
1970     free(host_mb);
1971
1972 end:
1973     if (target_mb)
1974         unlock_user_struct(target_mb, msgp, 1);
1975     return ret;
1976 }
1977
1978 /* ??? This only works with linear mappings.  */
1979 /* do_ipc() must return target values and target errnos. */
1980 static abi_long do_ipc(unsigned int call, int first,
1981                        int second, int third,
1982                        abi_long ptr, abi_long fifth)
1983 {
1984     int version;
1985     abi_long ret = 0;
1986     struct shmid_ds shm_info;
1987     int i;
1988
1989     version = call >> 16;
1990     call &= 0xffff;
1991
1992     switch (call) {
1993     case IPCOP_semop:
1994         ret = get_errno(semop(first,(struct sembuf *)g2h(ptr), second));
1995         break;
1996
1997     case IPCOP_semget:
1998         ret = get_errno(semget(first, second, third));
1999         break;
2000
2001     case IPCOP_semctl:
2002         ret = do_semctl(first, second, third, ptr);
2003         break;
2004
2005     case IPCOP_semtimedop:
2006         gemu_log("Unsupported ipc call: %d (version %d)\n", call, version);
2007         ret = -TARGET_ENOSYS;
2008         break;
2009
2010         case IPCOP_msgget:
2011                 ret = get_errno(msgget(first, second));
2012                 break;
2013
2014         case IPCOP_msgsnd:
2015                 ret = do_msgsnd(first, ptr, second, third);
2016                 break;
2017
2018         case IPCOP_msgctl:
2019                 ret = do_msgctl(first, second, ptr);
2020                 break;
2021
2022         case IPCOP_msgrcv:
2023                 {
2024                       /* XXX: this code is not correct */
2025                       struct ipc_kludge
2026                       {
2027                               void *__unbounded msgp;
2028                               long int msgtyp;
2029                       };
2030
2031                       struct ipc_kludge *foo = (struct ipc_kludge *)g2h(ptr);
2032                       struct msgbuf *msgp = (struct msgbuf *) foo->msgp;
2033
2034                       ret = do_msgrcv(first, (long)msgp, second, 0, third);
2035
2036                 }
2037                 break;
2038
2039     case IPCOP_shmat:
2040         {
2041             abi_ulong raddr;
2042             void *host_addr;
2043             /* SHM_* flags are the same on all linux platforms */
2044             host_addr = shmat(first, (void *)g2h(ptr), second);
2045             if (host_addr == (void *)-1) {
2046                 ret = get_errno((long)host_addr);
2047                 break;
2048             }
2049             raddr = h2g((unsigned long)host_addr);
2050             /* find out the length of the shared memory segment */
2051             
2052             ret = get_errno(shmctl(first, IPC_STAT, &shm_info));
2053             if (is_error(ret)) {
2054                 /* can't get length, bail out */
2055                 shmdt(host_addr);
2056                 break;
2057             }
2058             page_set_flags(raddr, raddr + shm_info.shm_segsz,
2059                            PAGE_VALID | PAGE_READ |
2060                            ((second & SHM_RDONLY)? 0: PAGE_WRITE));
2061             for (i = 0; i < N_SHM_REGIONS; ++i) {
2062                 if (shm_regions[i].start == 0) {
2063                     shm_regions[i].start = raddr;
2064                     shm_regions[i].size = shm_info.shm_segsz;
2065                     break;
2066                 }
2067             }
2068             if (put_user_ual(raddr, third))
2069                 return -TARGET_EFAULT;
2070             ret = 0;
2071         }
2072         break;
2073     case IPCOP_shmdt:
2074         for (i = 0; i < N_SHM_REGIONS; ++i) {
2075             if (shm_regions[i].start == ptr) {
2076                 shm_regions[i].start = 0;
2077                 page_set_flags(ptr, shm_regions[i].size, 0);
2078                 break;
2079             }
2080         }
2081         ret = get_errno(shmdt((void *)g2h(ptr)));
2082         break;
2083
2084     case IPCOP_shmget:
2085         /* IPC_* flag values are the same on all linux platforms */
2086         ret = get_errno(shmget(first, second, third));
2087         break;
2088
2089         /* IPC_* and SHM_* command values are the same on all linux platforms */
2090     case IPCOP_shmctl:
2091         switch(second) {
2092         case IPC_RMID:
2093         case SHM_LOCK:
2094         case SHM_UNLOCK:
2095             ret = get_errno(shmctl(first, second, NULL));
2096             break;
2097         default:
2098             goto unimplemented;
2099         }
2100         break;
2101     default:
2102     unimplemented:
2103         gemu_log("Unsupported ipc call: %d (version %d)\n", call, version);
2104         ret = -TARGET_ENOSYS;
2105         break;
2106     }
2107     return ret;
2108 }
2109 #endif
2110
2111 /* kernel structure types definitions */
2112 #define IFNAMSIZ        16
2113
2114 #define STRUCT(name, list...) STRUCT_ ## name,
2115 #define STRUCT_SPECIAL(name) STRUCT_ ## name,
2116 enum {
2117 #include "syscall_types.h"
2118 };
2119 #undef STRUCT
2120 #undef STRUCT_SPECIAL
2121
2122 #define STRUCT(name, list...) static const argtype struct_ ## name ## _def[] = { list, TYPE_NULL };
2123 #define STRUCT_SPECIAL(name)
2124 #include "syscall_types.h"
2125 #undef STRUCT
2126 #undef STRUCT_SPECIAL
2127
2128 typedef struct IOCTLEntry {
2129     unsigned int target_cmd;
2130     unsigned int host_cmd;
2131     const char *name;
2132     int access;
2133     const argtype arg_type[5];
2134 } IOCTLEntry;
2135
2136 #define IOC_R 0x0001
2137 #define IOC_W 0x0002
2138 #define IOC_RW (IOC_R | IOC_W)
2139
2140 #define MAX_STRUCT_SIZE 4096
2141
2142 static IOCTLEntry ioctl_entries[] = {
2143 #define IOCTL(cmd, access, types...) \
2144     { TARGET_ ## cmd, cmd, #cmd, access, { types } },
2145 #include "ioctls.h"
2146     { 0, 0, },
2147 };
2148
2149 /* ??? Implement proper locking for ioctls.  */
2150 /* do_ioctl() Must return target values and target errnos. */
2151 static abi_long do_ioctl(int fd, abi_long cmd, abi_long arg)
2152 {
2153     const IOCTLEntry *ie;
2154     const argtype *arg_type;
2155     abi_long ret;
2156     uint8_t buf_temp[MAX_STRUCT_SIZE];
2157     int target_size;
2158     void *argptr;
2159
2160     ie = ioctl_entries;
2161     for(;;) {
2162         if (ie->target_cmd == 0) {
2163             gemu_log("Unsupported ioctl: cmd=0x%04lx\n", (long)cmd);
2164             return -TARGET_ENOSYS;
2165         }
2166         if (ie->target_cmd == cmd)
2167             break;
2168         ie++;
2169     }
2170     arg_type = ie->arg_type;
2171 #if defined(DEBUG)
2172     gemu_log("ioctl: cmd=0x%04lx (%s)\n", (long)cmd, ie->name);
2173 #endif
2174     switch(arg_type[0]) {
2175     case TYPE_NULL:
2176         /* no argument */
2177         ret = get_errno(ioctl(fd, ie->host_cmd));
2178         break;
2179     case TYPE_PTRVOID:
2180     case TYPE_INT:
2181         /* int argment */
2182         ret = get_errno(ioctl(fd, ie->host_cmd, arg));
2183         break;
2184     case TYPE_PTR:
2185         arg_type++;
2186         target_size = thunk_type_size(arg_type, 0);
2187         switch(ie->access) {
2188         case IOC_R:
2189             ret = get_errno(ioctl(fd, ie->host_cmd, buf_temp));
2190             if (!is_error(ret)) {
2191                 argptr = lock_user(VERIFY_WRITE, arg, target_size, 0);
2192                 if (!argptr)
2193                     return -TARGET_EFAULT;
2194                 thunk_convert(argptr, buf_temp, arg_type, THUNK_TARGET);
2195                 unlock_user(argptr, arg, target_size);
2196             }
2197             break;
2198         case IOC_W:
2199             argptr = lock_user(VERIFY_READ, arg, target_size, 1);
2200             if (!argptr)
2201                 return -TARGET_EFAULT;
2202             thunk_convert(buf_temp, argptr, arg_type, THUNK_HOST);
2203             unlock_user(argptr, arg, 0);
2204             ret = get_errno(ioctl(fd, ie->host_cmd, buf_temp));
2205             break;
2206         default:
2207         case IOC_RW:
2208             argptr = lock_user(VERIFY_READ, arg, target_size, 1);
2209             if (!argptr)
2210                 return -TARGET_EFAULT;
2211             thunk_convert(buf_temp, argptr, arg_type, THUNK_HOST);
2212             unlock_user(argptr, arg, 0);
2213             ret = get_errno(ioctl(fd, ie->host_cmd, buf_temp));
2214             if (!is_error(ret)) {
2215                 argptr = lock_user(VERIFY_WRITE, arg, target_size, 0);
2216                 if (!argptr)
2217                     return -TARGET_EFAULT;
2218                 thunk_convert(argptr, buf_temp, arg_type, THUNK_TARGET);
2219                 unlock_user(argptr, arg, target_size);
2220             }
2221             break;
2222         }
2223         break;
2224     default:
2225         gemu_log("Unsupported ioctl type: cmd=0x%04lx type=%d\n",
2226                  (long)cmd, arg_type[0]);
2227         ret = -TARGET_ENOSYS;
2228         break;
2229     }
2230     return ret;
2231 }
2232
2233 static const bitmask_transtbl iflag_tbl[] = {
2234         { TARGET_IGNBRK, TARGET_IGNBRK, IGNBRK, IGNBRK },
2235         { TARGET_BRKINT, TARGET_BRKINT, BRKINT, BRKINT },
2236         { TARGET_IGNPAR, TARGET_IGNPAR, IGNPAR, IGNPAR },
2237         { TARGET_PARMRK, TARGET_PARMRK, PARMRK, PARMRK },
2238         { TARGET_INPCK, TARGET_INPCK, INPCK, INPCK },
2239         { TARGET_ISTRIP, TARGET_ISTRIP, ISTRIP, ISTRIP },
2240         { TARGET_INLCR, TARGET_INLCR, INLCR, INLCR },
2241         { TARGET_IGNCR, TARGET_IGNCR, IGNCR, IGNCR },
2242         { TARGET_ICRNL, TARGET_ICRNL, ICRNL, ICRNL },
2243         { TARGET_IUCLC, TARGET_IUCLC, IUCLC, IUCLC },
2244         { TARGET_IXON, TARGET_IXON, IXON, IXON },
2245         { TARGET_IXANY, TARGET_IXANY, IXANY, IXANY },
2246         { TARGET_IXOFF, TARGET_IXOFF, IXOFF, IXOFF },
2247         { TARGET_IMAXBEL, TARGET_IMAXBEL, IMAXBEL, IMAXBEL },
2248         { 0, 0, 0, 0 }
2249 };
2250
2251 static const bitmask_transtbl oflag_tbl[] = {
2252         { TARGET_OPOST, TARGET_OPOST, OPOST, OPOST },
2253         { TARGET_OLCUC, TARGET_OLCUC, OLCUC, OLCUC },
2254         { TARGET_ONLCR, TARGET_ONLCR, ONLCR, ONLCR },
2255         { TARGET_OCRNL, TARGET_OCRNL, OCRNL, OCRNL },
2256         { TARGET_ONOCR, TARGET_ONOCR, ONOCR, ONOCR },
2257         { TARGET_ONLRET, TARGET_ONLRET, ONLRET, ONLRET },
2258         { TARGET_OFILL, TARGET_OFILL, OFILL, OFILL },
2259         { TARGET_OFDEL, TARGET_OFDEL, OFDEL, OFDEL },
2260         { TARGET_NLDLY, TARGET_NL0, NLDLY, NL0 },
2261         { TARGET_NLDLY, TARGET_NL1, NLDLY, NL1 },
2262         { TARGET_CRDLY, TARGET_CR0, CRDLY, CR0 },
2263         { TARGET_CRDLY, TARGET_CR1, CRDLY, CR1 },
2264         { TARGET_CRDLY, TARGET_CR2, CRDLY, CR2 },
2265         { TARGET_CRDLY, TARGET_CR3, CRDLY, CR3 },
2266         { TARGET_TABDLY, TARGET_TAB0, TABDLY, TAB0 },
2267         { TARGET_TABDLY, TARGET_TAB1, TABDLY, TAB1 },
2268         { TARGET_TABDLY, TARGET_TAB2, TABDLY, TAB2 },
2269         { TARGET_TABDLY, TARGET_TAB3, TABDLY, TAB3 },
2270         { TARGET_BSDLY, TARGET_BS0, BSDLY, BS0 },
2271         { TARGET_BSDLY, TARGET_BS1, BSDLY, BS1 },
2272         { TARGET_VTDLY, TARGET_VT0, VTDLY, VT0 },
2273         { TARGET_VTDLY, TARGET_VT1, VTDLY, VT1 },
2274         { TARGET_FFDLY, TARGET_FF0, FFDLY, FF0 },
2275         { TARGET_FFDLY, TARGET_FF1, FFDLY, FF1 },
2276         { 0, 0, 0, 0 }
2277 };
2278
2279 static const bitmask_transtbl cflag_tbl[] = {
2280         { TARGET_CBAUD, TARGET_B0, CBAUD, B0 },
2281         { TARGET_CBAUD, TARGET_B50, CBAUD, B50 },
2282         { TARGET_CBAUD, TARGET_B75, CBAUD, B75 },
2283         { TARGET_CBAUD, TARGET_B110, CBAUD, B110 },
2284         { TARGET_CBAUD, TARGET_B134, CBAUD, B134 },
2285         { TARGET_CBAUD, TARGET_B150, CBAUD, B150 },
2286         { TARGET_CBAUD, TARGET_B200, CBAUD, B200 },
2287         { TARGET_CBAUD, TARGET_B300, CBAUD, B300 },
2288         { TARGET_CBAUD, TARGET_B600, CBAUD, B600 },
2289         { TARGET_CBAUD, TARGET_B1200, CBAUD, B1200 },
2290         { TARGET_CBAUD, TARGET_B1800, CBAUD, B1800 },
2291         { TARGET_CBAUD, TARGET_B2400, CBAUD, B2400 },
2292         { TARGET_CBAUD, TARGET_B4800, CBAUD, B4800 },
2293         { TARGET_CBAUD, TARGET_B9600, CBAUD, B9600 },
2294         { TARGET_CBAUD, TARGET_B19200, CBAUD, B19200 },
2295         { TARGET_CBAUD, TARGET_B38400, CBAUD, B38400 },
2296         { TARGET_CBAUD, TARGET_B57600, CBAUD, B57600 },
2297         { TARGET_CBAUD, TARGET_B115200, CBAUD, B115200 },
2298         { TARGET_CBAUD, TARGET_B230400, CBAUD, B230400 },
2299         { TARGET_CBAUD, TARGET_B460800, CBAUD, B460800 },
2300         { TARGET_CSIZE, TARGET_CS5, CSIZE, CS5 },
2301         { TARGET_CSIZE, TARGET_CS6, CSIZE, CS6 },
2302         { TARGET_CSIZE, TARGET_CS7, CSIZE, CS7 },
2303         { TARGET_CSIZE, TARGET_CS8, CSIZE, CS8 },
2304         { TARGET_CSTOPB, TARGET_CSTOPB, CSTOPB, CSTOPB },
2305         { TARGET_CREAD, TARGET_CREAD, CREAD, CREAD },
2306         { TARGET_PARENB, TARGET_PARENB, PARENB, PARENB },
2307         { TARGET_PARODD, TARGET_PARODD, PARODD, PARODD },
2308         { TARGET_HUPCL, TARGET_HUPCL, HUPCL, HUPCL },
2309         { TARGET_CLOCAL, TARGET_CLOCAL, CLOCAL, CLOCAL },
2310         { TARGET_CRTSCTS, TARGET_CRTSCTS, CRTSCTS, CRTSCTS },
2311         { 0, 0, 0, 0 }
2312 };
2313
2314 static const bitmask_transtbl lflag_tbl[] = {
2315         { TARGET_ISIG, TARGET_ISIG, ISIG, ISIG },
2316         { TARGET_ICANON, TARGET_ICANON, ICANON, ICANON },
2317         { TARGET_XCASE, TARGET_XCASE, XCASE, XCASE },
2318         { TARGET_ECHO, TARGET_ECHO, ECHO, ECHO },
2319         { TARGET_ECHOE, TARGET_ECHOE, ECHOE, ECHOE },
2320         { TARGET_ECHOK, TARGET_ECHOK, ECHOK, ECHOK },
2321         { TARGET_ECHONL, TARGET_ECHONL, ECHONL, ECHONL },
2322         { TARGET_NOFLSH, TARGET_NOFLSH, NOFLSH, NOFLSH },
2323         { TARGET_TOSTOP, TARGET_TOSTOP, TOSTOP, TOSTOP },
2324         { TARGET_ECHOCTL, TARGET_ECHOCTL, ECHOCTL, ECHOCTL },
2325         { TARGET_ECHOPRT, TARGET_ECHOPRT, ECHOPRT, ECHOPRT },
2326         { TARGET_ECHOKE, TARGET_ECHOKE, ECHOKE, ECHOKE },
2327         { TARGET_FLUSHO, TARGET_FLUSHO, FLUSHO, FLUSHO },
2328         { TARGET_PENDIN, TARGET_PENDIN, PENDIN, PENDIN },
2329         { TARGET_IEXTEN, TARGET_IEXTEN, IEXTEN, IEXTEN },
2330         { 0, 0, 0, 0 }
2331 };
2332
2333 static void target_to_host_termios (void *dst, const void *src)
2334 {
2335     struct host_termios *host = dst;
2336     const struct target_termios *target = src;
2337
2338     host->c_iflag =
2339         target_to_host_bitmask(tswap32(target->c_iflag), iflag_tbl);
2340     host->c_oflag =
2341         target_to_host_bitmask(tswap32(target->c_oflag), oflag_tbl);
2342     host->c_cflag =
2343         target_to_host_bitmask(tswap32(target->c_cflag), cflag_tbl);
2344     host->c_lflag =
2345         target_to_host_bitmask(tswap32(target->c_lflag), lflag_tbl);
2346     host->c_line = target->c_line;
2347
2348     host->c_cc[VINTR] = target->c_cc[TARGET_VINTR];
2349     host->c_cc[VQUIT] = target->c_cc[TARGET_VQUIT];
2350     host->c_cc[VERASE] = target->c_cc[TARGET_VERASE];
2351     host->c_cc[VKILL] = target->c_cc[TARGET_VKILL];
2352     host->c_cc[VEOF] = target->c_cc[TARGET_VEOF];
2353     host->c_cc[VTIME] = target->c_cc[TARGET_VTIME];
2354     host->c_cc[VMIN] = target->c_cc[TARGET_VMIN];
2355     host->c_cc[VSWTC] = target->c_cc[TARGET_VSWTC];
2356     host->c_cc[VSTART] = target->c_cc[TARGET_VSTART];
2357     host->c_cc[VSTOP] = target->c_cc[TARGET_VSTOP];
2358     host->c_cc[VSUSP] = target->c_cc[TARGET_VSUSP];
2359     host->c_cc[VEOL] = target->c_cc[TARGET_VEOL];
2360     host->c_cc[VREPRINT] = target->c_cc[TARGET_VREPRINT];
2361     host->c_cc[VDISCARD] = target->c_cc[TARGET_VDISCARD];
2362     host->c_cc[VWERASE] = target->c_cc[TARGET_VWERASE];
2363     host->c_cc[VLNEXT] = target->c_cc[TARGET_VLNEXT];
2364     host->c_cc[VEOL2] = target->c_cc[TARGET_VEOL2];
2365 }
2366
2367 static void host_to_target_termios (void *dst, const void *src)
2368 {
2369     struct target_termios *target = dst;
2370     const struct host_termios *host = src;
2371
2372     target->c_iflag =
2373         tswap32(host_to_target_bitmask(host->c_iflag, iflag_tbl));
2374     target->c_oflag =
2375         tswap32(host_to_target_bitmask(host->c_oflag, oflag_tbl));
2376     target->c_cflag =
2377         tswap32(host_to_target_bitmask(host->c_cflag, cflag_tbl));
2378     target->c_lflag =
2379         tswap32(host_to_target_bitmask(host->c_lflag, lflag_tbl));
2380     target->c_line = host->c_line;
2381
2382     target->c_cc[TARGET_VINTR] = host->c_cc[VINTR];
2383     target->c_cc[TARGET_VQUIT] = host->c_cc[VQUIT];
2384     target->c_cc[TARGET_VERASE] = host->c_cc[VERASE];
2385     target->c_cc[TARGET_VKILL] = host->c_cc[VKILL];
2386     target->c_cc[TARGET_VEOF] = host->c_cc[VEOF];
2387     target->c_cc[TARGET_VTIME] = host->c_cc[VTIME];
2388     target->c_cc[TARGET_VMIN] = host->c_cc[VMIN];
2389     target->c_cc[TARGET_VSWTC] = host->c_cc[VSWTC];
2390     target->c_cc[TARGET_VSTART] = host->c_cc[VSTART];
2391     target->c_cc[TARGET_VSTOP] = host->c_cc[VSTOP];
2392     target->c_cc[TARGET_VSUSP] = host->c_cc[VSUSP];
2393     target->c_cc[TARGET_VEOL] = host->c_cc[VEOL];
2394     target->c_cc[TARGET_VREPRINT] = host->c_cc[VREPRINT];
2395     target->c_cc[TARGET_VDISCARD] = host->c_cc[VDISCARD];
2396     target->c_cc[TARGET_VWERASE] = host->c_cc[VWERASE];
2397     target->c_cc[TARGET_VLNEXT] = host->c_cc[VLNEXT];
2398     target->c_cc[TARGET_VEOL2] = host->c_cc[VEOL2];
2399 }
2400
2401 static const StructEntry struct_termios_def = {
2402     .convert = { host_to_target_termios, target_to_host_termios },
2403     .size = { sizeof(struct target_termios), sizeof(struct host_termios) },
2404     .align = { __alignof__(struct target_termios), __alignof__(struct host_termios) },
2405 };
2406
2407 static bitmask_transtbl mmap_flags_tbl[] = {
2408         { TARGET_MAP_SHARED, TARGET_MAP_SHARED, MAP_SHARED, MAP_SHARED },
2409         { TARGET_MAP_PRIVATE, TARGET_MAP_PRIVATE, MAP_PRIVATE, MAP_PRIVATE },
2410         { TARGET_MAP_FIXED, TARGET_MAP_FIXED, MAP_FIXED, MAP_FIXED },
2411         { TARGET_MAP_ANONYMOUS, TARGET_MAP_ANONYMOUS, MAP_ANONYMOUS, MAP_ANONYMOUS },
2412         { TARGET_MAP_GROWSDOWN, TARGET_MAP_GROWSDOWN, MAP_GROWSDOWN, MAP_GROWSDOWN },
2413         { TARGET_MAP_DENYWRITE, TARGET_MAP_DENYWRITE, MAP_DENYWRITE, MAP_DENYWRITE },
2414         { TARGET_MAP_EXECUTABLE, TARGET_MAP_EXECUTABLE, MAP_EXECUTABLE, MAP_EXECUTABLE },
2415         { TARGET_MAP_LOCKED, TARGET_MAP_LOCKED, MAP_LOCKED, MAP_LOCKED },
2416         { 0, 0, 0, 0 }
2417 };
2418
2419 static bitmask_transtbl fcntl_flags_tbl[] = {
2420         { TARGET_O_ACCMODE,   TARGET_O_WRONLY,    O_ACCMODE,   O_WRONLY,    },
2421         { TARGET_O_ACCMODE,   TARGET_O_RDWR,      O_ACCMODE,   O_RDWR,      },
2422         { TARGET_O_CREAT,     TARGET_O_CREAT,     O_CREAT,     O_CREAT,     },
2423         { TARGET_O_EXCL,      TARGET_O_EXCL,      O_EXCL,      O_EXCL,      },
2424         { TARGET_O_NOCTTY,    TARGET_O_NOCTTY,    O_NOCTTY,    O_NOCTTY,    },
2425         { TARGET_O_TRUNC,     TARGET_O_TRUNC,     O_TRUNC,     O_TRUNC,     },
2426         { TARGET_O_APPEND,    TARGET_O_APPEND,    O_APPEND,    O_APPEND,    },
2427         { TARGET_O_NONBLOCK,  TARGET_O_NONBLOCK,  O_NONBLOCK,  O_NONBLOCK,  },
2428         { TARGET_O_SYNC,      TARGET_O_SYNC,      O_SYNC,      O_SYNC,      },
2429         { TARGET_FASYNC,      TARGET_FASYNC,      FASYNC,      FASYNC,      },
2430         { TARGET_O_DIRECTORY, TARGET_O_DIRECTORY, O_DIRECTORY, O_DIRECTORY, },
2431         { TARGET_O_NOFOLLOW,  TARGET_O_NOFOLLOW,  O_NOFOLLOW,  O_NOFOLLOW,  },
2432         { TARGET_O_LARGEFILE, TARGET_O_LARGEFILE, O_LARGEFILE, O_LARGEFILE, },
2433 #if defined(O_DIRECT)
2434         { TARGET_O_DIRECT,    TARGET_O_DIRECT,    O_DIRECT,    O_DIRECT,    },
2435 #endif
2436         { 0, 0, 0, 0 }
2437 };
2438
2439 #if defined(TARGET_I386)
2440
2441 /* NOTE: there is really one LDT for all the threads */
2442 uint8_t *ldt_table;
2443
2444 static abi_long read_ldt(abi_ulong ptr, unsigned long bytecount)
2445 {
2446     int size;
2447     void *p;
2448
2449     if (!ldt_table)
2450         return 0;
2451     size = TARGET_LDT_ENTRIES * TARGET_LDT_ENTRY_SIZE;
2452     if (size > bytecount)
2453         size = bytecount;
2454     p = lock_user(VERIFY_WRITE, ptr, size, 0);
2455     if (!p)
2456         return -TARGET_EFAULT;
2457     /* ??? Should this by byteswapped?  */
2458     memcpy(p, ldt_table, size);
2459     unlock_user(p, ptr, size);
2460     return size;
2461 }
2462
2463 /* XXX: add locking support */
2464 static abi_long write_ldt(CPUX86State *env,
2465                           abi_ulong ptr, unsigned long bytecount, int oldmode)
2466 {
2467     struct target_modify_ldt_ldt_s ldt_info;
2468     struct target_modify_ldt_ldt_s *target_ldt_info;
2469     int seg_32bit, contents, read_exec_only, limit_in_pages;
2470     int seg_not_present, useable, lm;
2471     uint32_t *lp, entry_1, entry_2;
2472
2473     if (bytecount != sizeof(ldt_info))
2474         return -TARGET_EINVAL;
2475     if (!lock_user_struct(VERIFY_READ, target_ldt_info, ptr, 1))
2476         return -TARGET_EFAULT;
2477     ldt_info.entry_number = tswap32(target_ldt_info->entry_number);
2478     ldt_info.base_addr = tswapl(target_ldt_info->base_addr);
2479     ldt_info.limit = tswap32(target_ldt_info->limit);
2480     ldt_info.flags = tswap32(target_ldt_info->flags);
2481     unlock_user_struct(target_ldt_info, ptr, 0);
2482
2483     if (ldt_info.entry_number >= TARGET_LDT_ENTRIES)
2484         return -TARGET_EINVAL;
2485     seg_32bit = ldt_info.flags & 1;
2486     contents = (ldt_info.flags >> 1) & 3;
2487     read_exec_only = (ldt_info.flags >> 3) & 1;
2488     limit_in_pages = (ldt_info.flags >> 4) & 1;
2489     seg_not_present = (ldt_info.flags >> 5) & 1;
2490     useable = (ldt_info.flags >> 6) & 1;
2491 #ifdef TARGET_ABI32
2492     lm = 0;
2493 #else
2494     lm = (ldt_info.flags >> 7) & 1;
2495 #endif
2496     if (contents == 3) {
2497         if (oldmode)
2498             return -TARGET_EINVAL;
2499         if (seg_not_present == 0)
2500             return -TARGET_EINVAL;
2501     }
2502     /* allocate the LDT */
2503     if (!ldt_table) {
2504         ldt_table = malloc(TARGET_LDT_ENTRIES * TARGET_LDT_ENTRY_SIZE);
2505         if (!ldt_table)
2506             return -TARGET_ENOMEM;
2507         memset(ldt_table, 0, TARGET_LDT_ENTRIES * TARGET_LDT_ENTRY_SIZE);
2508         env->ldt.base = h2g((unsigned long)ldt_table);
2509         env->ldt.limit = 0xffff;
2510     }
2511
2512     /* NOTE: same code as Linux kernel */
2513     /* Allow LDTs to be cleared by the user. */
2514     if (ldt_info.base_addr == 0 && ldt_info.limit == 0) {
2515         if (oldmode ||
2516             (contents == 0              &&
2517              read_exec_only == 1        &&
2518              seg_32bit == 0             &&
2519              limit_in_pages == 0        &&
2520              seg_not_present == 1       &&
2521              useable == 0 )) {
2522             entry_1 = 0;
2523             entry_2 = 0;
2524             goto install;
2525         }
2526     }
2527
2528     entry_1 = ((ldt_info.base_addr & 0x0000ffff) << 16) |
2529         (ldt_info.limit & 0x0ffff);
2530     entry_2 = (ldt_info.base_addr & 0xff000000) |
2531         ((ldt_info.base_addr & 0x00ff0000) >> 16) |
2532         (ldt_info.limit & 0xf0000) |
2533         ((read_exec_only ^ 1) << 9) |
2534         (contents << 10) |
2535         ((seg_not_present ^ 1) << 15) |
2536         (seg_32bit << 22) |
2537         (limit_in_pages << 23) |
2538         (lm << 21) |
2539         0x7000;
2540     if (!oldmode)
2541         entry_2 |= (useable << 20);
2542
2543     /* Install the new entry ...  */
2544 install:
2545     lp = (uint32_t *)(ldt_table + (ldt_info.entry_number << 3));
2546     lp[0] = tswap32(entry_1);
2547     lp[1] = tswap32(entry_2);
2548     return 0;
2549 }
2550
2551 /* specific and weird i386 syscalls */
2552 static abi_long do_modify_ldt(CPUX86State *env, int func, abi_ulong ptr,
2553                               unsigned long bytecount)
2554 {
2555     abi_long ret;
2556
2557     switch (func) {
2558     case 0:
2559         ret = read_ldt(ptr, bytecount);
2560         break;
2561     case 1:
2562         ret = write_ldt(env, ptr, bytecount, 1);
2563         break;
2564     case 0x11:
2565         ret = write_ldt(env, ptr, bytecount, 0);
2566         break;
2567     default:
2568         ret = -TARGET_ENOSYS;
2569         break;
2570     }
2571     return ret;
2572 }
2573
2574 #if defined(TARGET_I386) && defined(TARGET_ABI32)
2575 static abi_long do_set_thread_area(CPUX86State *env, abi_ulong ptr)
2576 {
2577     uint64_t *gdt_table = g2h(env->gdt.base);
2578     struct target_modify_ldt_ldt_s ldt_info;
2579     struct target_modify_ldt_ldt_s *target_ldt_info;
2580     int seg_32bit, contents, read_exec_only, limit_in_pages;
2581     int seg_not_present, useable, lm;
2582     uint32_t *lp, entry_1, entry_2;
2583     int i;
2584
2585     lock_user_struct(VERIFY_WRITE, target_ldt_info, ptr, 1);
2586     if (!target_ldt_info)
2587         return -TARGET_EFAULT;
2588     ldt_info.entry_number = tswap32(target_ldt_info->entry_number);
2589     ldt_info.base_addr = tswapl(target_ldt_info->base_addr);
2590     ldt_info.limit = tswap32(target_ldt_info->limit);
2591     ldt_info.flags = tswap32(target_ldt_info->flags);
2592     if (ldt_info.entry_number == -1) {
2593         for (i=TARGET_GDT_ENTRY_TLS_MIN; i<=TARGET_GDT_ENTRY_TLS_MAX; i++) {
2594             if (gdt_table[i] == 0) {
2595                 ldt_info.entry_number = i;
2596                 target_ldt_info->entry_number = tswap32(i);
2597                 break;
2598             }
2599         }
2600     }
2601     unlock_user_struct(target_ldt_info, ptr, 1);
2602
2603     if (ldt_info.entry_number < TARGET_GDT_ENTRY_TLS_MIN || 
2604         ldt_info.entry_number > TARGET_GDT_ENTRY_TLS_MAX)
2605            return -TARGET_EINVAL;
2606     seg_32bit = ldt_info.flags & 1;
2607     contents = (ldt_info.flags >> 1) & 3;
2608     read_exec_only = (ldt_info.flags >> 3) & 1;
2609     limit_in_pages = (ldt_info.flags >> 4) & 1;
2610     seg_not_present = (ldt_info.flags >> 5) & 1;
2611     useable = (ldt_info.flags >> 6) & 1;
2612 #ifdef TARGET_ABI32
2613     lm = 0;
2614 #else
2615     lm = (ldt_info.flags >> 7) & 1;
2616 #endif
2617
2618     if (contents == 3) {
2619         if (seg_not_present == 0)
2620             return -TARGET_EINVAL;
2621     }
2622
2623     /* NOTE: same code as Linux kernel */
2624     /* Allow LDTs to be cleared by the user. */
2625     if (ldt_info.base_addr == 0 && ldt_info.limit == 0) {
2626         if ((contents == 0             &&
2627              read_exec_only == 1       &&
2628              seg_32bit == 0            &&
2629              limit_in_pages == 0       &&
2630              seg_not_present == 1      &&
2631              useable == 0 )) {
2632             entry_1 = 0;
2633             entry_2 = 0;
2634             goto install;
2635         }
2636     }
2637
2638     entry_1 = ((ldt_info.base_addr & 0x0000ffff) << 16) |
2639         (ldt_info.limit & 0x0ffff);
2640     entry_2 = (ldt_info.base_addr & 0xff000000) |
2641         ((ldt_info.base_addr & 0x00ff0000) >> 16) |
2642         (ldt_info.limit & 0xf0000) |
2643         ((read_exec_only ^ 1) << 9) |
2644         (contents << 10) |
2645         ((seg_not_present ^ 1) << 15) |
2646         (seg_32bit << 22) |
2647         (limit_in_pages << 23) |
2648         (useable << 20) |
2649         (lm << 21) |
2650         0x7000;
2651
2652     /* Install the new entry ...  */
2653 install:
2654     lp = (uint32_t *)(gdt_table + ldt_info.entry_number);
2655     lp[0] = tswap32(entry_1);
2656     lp[1] = tswap32(entry_2);
2657     return 0;
2658 }
2659
2660 static abi_long do_get_thread_area(CPUX86State *env, abi_ulong ptr)
2661 {
2662     struct target_modify_ldt_ldt_s *target_ldt_info;
2663     uint64_t *gdt_table = g2h(env->gdt.base);
2664     uint32_t base_addr, limit, flags;
2665     int seg_32bit, contents, read_exec_only, limit_in_pages, idx;
2666     int seg_not_present, useable, lm;
2667     uint32_t *lp, entry_1, entry_2;
2668
2669     lock_user_struct(VERIFY_WRITE, target_ldt_info, ptr, 1);
2670     if (!target_ldt_info)
2671         return -TARGET_EFAULT;
2672     idx = tswap32(target_ldt_info->entry_number);
2673     if (idx < TARGET_GDT_ENTRY_TLS_MIN ||
2674         idx > TARGET_GDT_ENTRY_TLS_MAX) {
2675         unlock_user_struct(target_ldt_info, ptr, 1);
2676         return -TARGET_EINVAL;
2677     }
2678     lp = (uint32_t *)(gdt_table + idx);
2679     entry_1 = tswap32(lp[0]);
2680     entry_2 = tswap32(lp[1]);
2681     
2682     read_exec_only = ((entry_2 >> 9) & 1) ^ 1;
2683     contents = (entry_2 >> 10) & 3;
2684     seg_not_present = ((entry_2 >> 15) & 1) ^ 1;
2685     seg_32bit = (entry_2 >> 22) & 1;
2686     limit_in_pages = (entry_2 >> 23) & 1;
2687     useable = (entry_2 >> 20) & 1;
2688 #ifdef TARGET_ABI32
2689     lm = 0;
2690 #else
2691     lm = (entry_2 >> 21) & 1;
2692 #endif
2693     flags = (seg_32bit << 0) | (contents << 1) |
2694         (read_exec_only << 3) | (limit_in_pages << 4) |
2695         (seg_not_present << 5) | (useable << 6) | (lm << 7);
2696     limit = (entry_1 & 0xffff) | (entry_2  & 0xf0000);
2697     base_addr = (entry_1 >> 16) | 
2698         (entry_2 & 0xff000000) | 
2699         ((entry_2 & 0xff) << 16);
2700     target_ldt_info->base_addr = tswapl(base_addr);
2701     target_ldt_info->limit = tswap32(limit);
2702     target_ldt_info->flags = tswap32(flags);
2703     unlock_user_struct(target_ldt_info, ptr, 1);
2704     return 0;
2705 }
2706 #endif /* TARGET_I386 && TARGET_ABI32 */
2707
2708 #ifndef TARGET_ABI32
2709 static abi_long do_arch_prctl(CPUX86State *env, int code, abi_ulong addr)
2710 {
2711     abi_long ret;
2712     abi_ulong val;
2713     int idx;
2714     
2715     switch(code) {
2716     case TARGET_ARCH_SET_GS:
2717     case TARGET_ARCH_SET_FS:
2718         if (code == TARGET_ARCH_SET_GS)
2719             idx = R_GS;
2720         else
2721             idx = R_FS;
2722         cpu_x86_load_seg(env, idx, 0);
2723         env->segs[idx].base = addr;
2724         break;
2725     case TARGET_ARCH_GET_GS:
2726     case TARGET_ARCH_GET_FS:
2727         if (code == TARGET_ARCH_GET_GS)
2728             idx = R_GS;
2729         else
2730             idx = R_FS;
2731         val = env->segs[idx].base;
2732         if (put_user(val, addr, abi_ulong))
2733             return -TARGET_EFAULT;
2734         break;
2735     default:
2736         ret = -TARGET_EINVAL;
2737         break;
2738     }
2739     return 0;
2740 }
2741 #endif
2742
2743 #endif /* defined(TARGET_I386) */
2744
2745 #if defined(USE_NPTL)
2746
2747 #define NEW_STACK_SIZE PTHREAD_STACK_MIN
2748
2749 static pthread_mutex_t clone_lock = PTHREAD_MUTEX_INITIALIZER;
2750 typedef struct {
2751     CPUState *env;
2752     pthread_mutex_t mutex;
2753     pthread_cond_t cond;
2754     pthread_t thread;
2755     uint32_t tid;
2756     abi_ulong child_tidptr;
2757     abi_ulong parent_tidptr;
2758     sigset_t sigmask;
2759 } new_thread_info;
2760
2761 static void *clone_func(void *arg)
2762 {
2763     new_thread_info *info = arg;
2764     CPUState *env;
2765
2766     env = info->env;
2767     thread_env = env;
2768     info->tid = gettid();
2769     if (info->child_tidptr)
2770         put_user_u32(info->tid, info->child_tidptr);
2771     if (info->parent_tidptr)
2772         put_user_u32(info->tid, info->parent_tidptr);
2773     /* Enable signals.  */
2774     sigprocmask(SIG_SETMASK, &info->sigmask, NULL);
2775     /* Signal to the parent that we're ready.  */
2776     pthread_mutex_lock(&info->mutex);
2777     pthread_cond_broadcast(&info->cond);
2778     pthread_mutex_unlock(&info->mutex);
2779     /* Wait until the parent has finshed initializing the tls state.  */
2780     pthread_mutex_lock(&clone_lock);
2781     pthread_mutex_unlock(&clone_lock);
2782     cpu_loop(env);
2783     /* never exits */
2784     return NULL;
2785 }
2786 #else
2787 /* this stack is the equivalent of the kernel stack associated with a
2788    thread/process */
2789 #define NEW_STACK_SIZE 8192
2790
2791 static int clone_func(void *arg)
2792 {
2793     CPUState *env = arg;
2794     cpu_loop(env);
2795     /* never exits */
2796     return 0;
2797 }
2798 #endif
2799
2800 /* do_fork() Must return host values and target errnos (unlike most
2801    do_*() functions). */
2802 static int do_fork(CPUState *env, unsigned int flags, abi_ulong newsp,
2803                    abi_ulong parent_tidptr, target_ulong newtls,
2804                    abi_ulong child_tidptr)
2805 {
2806     int ret;
2807     TaskState *ts;
2808     uint8_t *new_stack;
2809     CPUState *new_env;
2810 #if defined(USE_NPTL)
2811     unsigned int nptl_flags;
2812     sigset_t sigmask;
2813 #endif
2814
2815     /* Emulate vfork() with fork() */
2816     if (flags & CLONE_VFORK)
2817         flags &= ~(CLONE_VFORK | CLONE_VM);
2818
2819     if (flags & CLONE_VM) {
2820 #if defined(USE_NPTL)
2821         new_thread_info info;
2822         pthread_attr_t attr;
2823 #endif
2824         ts = qemu_mallocz(sizeof(TaskState) + NEW_STACK_SIZE);
2825         init_task_state(ts);
2826         new_stack = ts->stack;
2827         /* we create a new CPU instance. */
2828         new_env = cpu_copy(env);
2829         /* Init regs that differ from the parent.  */
2830         cpu_clone_regs(new_env, newsp);
2831         new_env->opaque = ts;
2832 #if defined(USE_NPTL)
2833         nptl_flags = flags;
2834         flags &= ~CLONE_NPTL_FLAGS2;
2835
2836         /* TODO: Implement CLONE_CHILD_CLEARTID.  */
2837         if (nptl_flags & CLONE_SETTLS)
2838             cpu_set_tls (new_env, newtls);
2839
2840         /* Grab a mutex so that thread setup appears atomic.  */
2841         pthread_mutex_lock(&clone_lock);
2842
2843         memset(&info, 0, sizeof(info));
2844         pthread_mutex_init(&info.mutex, NULL);
2845         pthread_mutex_lock(&info.mutex);
2846         pthread_cond_init(&info.cond, NULL);
2847         info.env = new_env;
2848         if (nptl_flags & CLONE_CHILD_SETTID)
2849             info.child_tidptr = child_tidptr;
2850         if (nptl_flags & CLONE_PARENT_SETTID)
2851             info.parent_tidptr = parent_tidptr;
2852
2853         ret = pthread_attr_init(&attr);
2854         ret = pthread_attr_setstack(&attr, new_stack, NEW_STACK_SIZE);
2855         /* It is not safe to deliver signals until the child has finished
2856            initializing, so temporarily block all signals.  */
2857         sigfillset(&sigmask);
2858         sigprocmask(SIG_BLOCK, &sigmask, &info.sigmask);
2859
2860         ret = pthread_create(&info.thread, &attr, clone_func, &info);
2861
2862         sigprocmask(SIG_SETMASK, &info.sigmask, NULL);
2863         pthread_attr_destroy(&attr);
2864         if (ret == 0) {
2865             /* Wait for the child to initialize.  */
2866             pthread_cond_wait(&info.cond, &info.mutex);
2867             ret = info.tid;
2868             if (flags & CLONE_PARENT_SETTID)
2869                 put_user_u32(ret, parent_tidptr);
2870         } else {
2871             ret = -1;
2872         }
2873         pthread_mutex_unlock(&info.mutex);
2874         pthread_cond_destroy(&info.cond);
2875         pthread_mutex_destroy(&info.mutex);
2876         pthread_mutex_unlock(&clone_lock);
2877 #else
2878         if (flags & CLONE_NPTL_FLAGS2)
2879             return -EINVAL;
2880         /* This is probably going to die very quickly, but do it anyway.  */
2881 #ifdef __ia64__
2882         ret = __clone2(clone_func, new_stack + NEW_STACK_SIZE, flags, new_env);
2883 #else
2884         ret = clone(clone_func, new_stack + NEW_STACK_SIZE, flags, new_env);
2885 #endif
2886 #endif
2887     } else {
2888         /* if no CLONE_VM, we consider it is a fork */
2889         if ((flags & ~(CSIGNAL | CLONE_NPTL_FLAGS2)) != 0)
2890             return -EINVAL;
2891         fork_start();
2892         ret = fork();
2893 #if defined(USE_NPTL)
2894         /* There is a race condition here.  The parent process could
2895            theoretically read the TID in the child process before the child
2896            tid is set.  This would require using either ptrace
2897            (not implemented) or having *_tidptr to point at a shared memory
2898            mapping.  We can't repeat the spinlock hack used above because
2899            the child process gets its own copy of the lock.  */
2900         if (ret == 0) {
2901             cpu_clone_regs(env, newsp);
2902             fork_end(1);
2903             /* Child Process.  */
2904             if (flags & CLONE_CHILD_SETTID)
2905                 put_user_u32(gettid(), child_tidptr);
2906             if (flags & CLONE_PARENT_SETTID)
2907                 put_user_u32(gettid(), parent_tidptr);
2908             ts = (TaskState *)env->opaque;
2909             if (flags & CLONE_SETTLS)
2910                 cpu_set_tls (env, newtls);
2911             /* TODO: Implement CLONE_CHILD_CLEARTID.  */
2912         } else {
2913             fork_end(0);
2914         }
2915 #else
2916         if (ret == 0) {
2917             cpu_clone_regs(env, newsp);
2918         }
2919 #endif
2920     }
2921     return ret;
2922 }
2923
2924 static abi_long do_fcntl(int fd, int cmd, abi_ulong arg)
2925 {
2926     struct flock fl;
2927     struct target_flock *target_fl;
2928     struct flock64 fl64;
2929     struct target_flock64 *target_fl64;
2930     abi_long ret;
2931
2932     switch(cmd) {
2933     case TARGET_F_GETLK:
2934         if (!lock_user_struct(VERIFY_READ, target_fl, arg, 1))
2935             return -TARGET_EFAULT;
2936         fl.l_type = tswap16(target_fl->l_type);
2937         fl.l_whence = tswap16(target_fl->l_whence);
2938         fl.l_start = tswapl(target_fl->l_start);
2939         fl.l_len = tswapl(target_fl->l_len);
2940         fl.l_pid = tswapl(target_fl->l_pid);
2941         unlock_user_struct(target_fl, arg, 0);
2942         ret = get_errno(fcntl(fd, cmd, &fl));
2943         if (ret == 0) {
2944             if (!lock_user_struct(VERIFY_WRITE, target_fl, arg, 0))
2945                 return -TARGET_EFAULT;
2946             target_fl->l_type = tswap16(fl.l_type);
2947             target_fl->l_whence = tswap16(fl.l_whence);
2948             target_fl->l_start = tswapl(fl.l_start);
2949             target_fl->l_len = tswapl(fl.l_len);
2950             target_fl->l_pid = tswapl(fl.l_pid);
2951             unlock_user_struct(target_fl, arg, 1);
2952         }
2953         break;
2954
2955     case TARGET_F_SETLK:
2956     case TARGET_F_SETLKW:
2957         if (!lock_user_struct(VERIFY_READ, target_fl, arg, 1))
2958             return -TARGET_EFAULT;
2959         fl.l_type = tswap16(target_fl->l_type);
2960         fl.l_whence = tswap16(target_fl->l_whence);
2961         fl.l_start = tswapl(target_fl->l_start);
2962         fl.l_len = tswapl(target_fl->l_len);
2963         fl.l_pid = tswapl(target_fl->l_pid);
2964         unlock_user_struct(target_fl, arg, 0);
2965         ret = get_errno(fcntl(fd, cmd, &fl));
2966         break;
2967
2968     case TARGET_F_GETLK64:
2969         if (!lock_user_struct(VERIFY_READ, target_fl64, arg, 1))
2970             return -TARGET_EFAULT;
2971         fl64.l_type = tswap16(target_fl64->l_type) >> 1;
2972         fl64.l_whence = tswap16(target_fl64->l_whence);
2973         fl64.l_start = tswapl(target_fl64->l_start);
2974         fl64.l_len = tswapl(target_fl64->l_len);
2975         fl64.l_pid = tswap16(target_fl64->l_pid);
2976         unlock_user_struct(target_fl64, arg, 0);
2977         ret = get_errno(fcntl(fd, cmd >> 1, &fl64));
2978         if (ret == 0) {
2979             if (!lock_user_struct(VERIFY_WRITE, target_fl64, arg, 0))
2980                 return -TARGET_EFAULT;
2981             target_fl64->l_type = tswap16(fl64.l_type) >> 1;
2982             target_fl64->l_whence = tswap16(fl64.l_whence);
2983             target_fl64->l_start = tswapl(fl64.l_start);
2984             target_fl64->l_len = tswapl(fl64.l_len);
2985             target_fl64->l_pid = tswapl(fl64.l_pid);
2986             unlock_user_struct(target_fl64, arg, 1);
2987         }
2988         break;
2989     case TARGET_F_SETLK64:
2990     case TARGET_F_SETLKW64:
2991         if (!lock_user_struct(VERIFY_READ, target_fl64, arg, 1))
2992             return -TARGET_EFAULT;
2993         fl64.l_type = tswap16(target_fl64->l_type) >> 1;
2994         fl64.l_whence = tswap16(target_fl64->l_whence);
2995         fl64.l_start = tswapl(target_fl64->l_start);
2996         fl64.l_len = tswapl(target_fl64->l_len);
2997         fl64.l_pid = tswap16(target_fl64->l_pid);
2998         unlock_user_struct(target_fl64, arg, 0);
2999         ret = get_errno(fcntl(fd, cmd >> 1, &fl64));
3000         break;
3001
3002     case F_GETFL:
3003         ret = get_errno(fcntl(fd, cmd, arg));
3004         if (ret >= 0) {
3005             ret = host_to_target_bitmask(ret, fcntl_flags_tbl);
3006         }
3007         break;
3008
3009     case F_SETFL:
3010         ret = get_errno(fcntl(fd, cmd, target_to_host_bitmask(arg, fcntl_flags_tbl)));
3011         break;
3012
3013     default:
3014         ret = get_errno(fcntl(fd, cmd, arg));
3015         break;
3016     }
3017     return ret;
3018 }
3019
3020 #ifdef USE_UID16
3021
3022 static inline int high2lowuid(int uid)
3023 {
3024     if (uid > 65535)
3025         return 65534;
3026     else
3027         return uid;
3028 }
3029
3030 static inline int high2lowgid(int gid)
3031 {
3032     if (gid > 65535)
3033         return 65534;
3034     else
3035         return gid;
3036 }
3037
3038 static inline int low2highuid(int uid)
3039 {
3040     if ((int16_t)uid == -1)
3041         return -1;
3042     else
3043         return uid;
3044 }
3045
3046 static inline int low2highgid(int gid)
3047 {
3048     if ((int16_t)gid == -1)
3049         return -1;
3050     else
3051         return gid;
3052 }
3053
3054 #endif /* USE_UID16 */
3055
3056 void syscall_init(void)
3057 {
3058     IOCTLEntry *ie;
3059     const argtype *arg_type;
3060     int size;
3061     int i;
3062
3063 #define STRUCT(name, list...) thunk_register_struct(STRUCT_ ## name, #name, struct_ ## name ## _def);
3064 #define STRUCT_SPECIAL(name) thunk_register_struct_direct(STRUCT_ ## name, #name, &struct_ ## name ## _def);
3065 #include "syscall_types.h"
3066 #undef STRUCT
3067 #undef STRUCT_SPECIAL
3068
3069     /* we patch the ioctl size if necessary. We rely on the fact that
3070        no ioctl has all the bits at '1' in the size field */
3071     ie = ioctl_entries;
3072     while (ie->target_cmd != 0) {
3073         if (((ie->target_cmd >> TARGET_IOC_SIZESHIFT) & TARGET_IOC_SIZEMASK) ==
3074             TARGET_IOC_SIZEMASK) {
3075             arg_type = ie->arg_type;
3076             if (arg_type[0] != TYPE_PTR) {
3077                 fprintf(stderr, "cannot patch size for ioctl 0x%x\n",
3078                         ie->target_cmd);
3079                 exit(1);
3080             }
3081             arg_type++;
3082             size = thunk_type_size(arg_type, 0);
3083             ie->target_cmd = (ie->target_cmd &
3084                               ~(TARGET_IOC_SIZEMASK << TARGET_IOC_SIZESHIFT)) |
3085                 (size << TARGET_IOC_SIZESHIFT);
3086         }
3087
3088         /* Build target_to_host_errno_table[] table from
3089          * host_to_target_errno_table[]. */
3090         for (i=0; i < ERRNO_TABLE_SIZE; i++)
3091                 target_to_host_errno_table[host_to_target_errno_table[i]] = i;
3092
3093         /* automatic consistency check if same arch */
3094 #if (defined(__i386__) && defined(TARGET_I386) && defined(TARGET_ABI32)) || \
3095     (defined(__x86_64__) && defined(TARGET_X86_64))
3096         if (unlikely(ie->target_cmd != ie->host_cmd)) {
3097             fprintf(stderr, "ERROR: ioctl(%s): target=0x%x host=0x%x\n",
3098                     ie->name, ie->target_cmd, ie->host_cmd);
3099         }
3100 #endif
3101         ie++;
3102     }
3103 }
3104
3105 #if TARGET_ABI_BITS == 32
3106 static inline uint64_t target_offset64(uint32_t word0, uint32_t word1)
3107 {
3108 #ifdef TARGET_WORDS_BIGENDIAN
3109     return ((uint64_t)word0 << 32) | word1;
3110 #else
3111     return ((uint64_t)word1 << 32) | word0;
3112 #endif
3113 }
3114 #else /* TARGET_ABI_BITS == 32 */
3115 static inline uint64_t target_offset64(uint64_t word0, uint64_t word1)
3116 {
3117     return word0;
3118 }
3119 #endif /* TARGET_ABI_BITS != 32 */
3120
3121 #ifdef TARGET_NR_truncate64
3122 static inline abi_long target_truncate64(void *cpu_env, const char *arg1,
3123                                          abi_long arg2,
3124                                          abi_long arg3,
3125                                          abi_long arg4)
3126 {
3127 #ifdef TARGET_ARM
3128     if (((CPUARMState *)cpu_env)->eabi)
3129       {
3130         arg2 = arg3;
3131         arg3 = arg4;
3132       }
3133 #endif
3134     return get_errno(truncate64(arg1, target_offset64(arg2, arg3)));
3135 }
3136 #endif
3137
3138 #ifdef TARGET_NR_ftruncate64
3139 static inline abi_long target_ftruncate64(void *cpu_env, abi_long arg1,
3140                                           abi_long arg2,
3141                                           abi_long arg3,
3142                                           abi_long arg4)
3143 {
3144 #ifdef TARGET_ARM
3145     if (((CPUARMState *)cpu_env)->eabi)
3146       {
3147         arg2 = arg3;
3148         arg3 = arg4;
3149       }
3150 #endif
3151     return get_errno(ftruncate64(arg1, target_offset64(arg2, arg3)));
3152 }
3153 #endif
3154
3155 static inline abi_long target_to_host_timespec(struct timespec *host_ts,
3156                                                abi_ulong target_addr)
3157 {
3158     struct target_timespec *target_ts;
3159
3160     if (!lock_user_struct(VERIFY_READ, target_ts, target_addr, 1))
3161         return -TARGET_EFAULT;
3162     host_ts->tv_sec = tswapl(target_ts->tv_sec);
3163     host_ts->tv_nsec = tswapl(target_ts->tv_nsec);
3164     unlock_user_struct(target_ts, target_addr, 0);
3165     return 0;
3166 }
3167
3168 static inline abi_long host_to_target_timespec(abi_ulong target_addr,
3169                                                struct timespec *host_ts)
3170 {
3171     struct target_timespec *target_ts;
3172
3173     if (!lock_user_struct(VERIFY_WRITE, target_ts, target_addr, 0))
3174         return -TARGET_EFAULT;
3175     target_ts->tv_sec = tswapl(host_ts->tv_sec);
3176     target_ts->tv_nsec = tswapl(host_ts->tv_nsec);
3177     unlock_user_struct(target_ts, target_addr, 1);
3178     return 0;
3179 }
3180
3181 #ifdef TARGET_NR_stat64
3182 static inline abi_long host_to_target_stat64(void *cpu_env,
3183                                              abi_ulong target_addr,
3184                                              struct stat *host_st)
3185 {
3186 #ifdef TARGET_ARM
3187     if (((CPUARMState *)cpu_env)->eabi) {
3188         struct target_eabi_stat64 *target_st;
3189
3190         if (!lock_user_struct(VERIFY_WRITE, target_st, target_addr, 0))
3191             return -TARGET_EFAULT;
3192         memset(target_st, 0, sizeof(struct target_eabi_stat64));
3193         __put_user(host_st->st_dev, &target_st->st_dev);
3194         __put_user(host_st->st_ino, &target_st->st_ino);
3195 #ifdef TARGET_STAT64_HAS_BROKEN_ST_INO
3196         __put_user(host_st->st_ino, &target_st->__st_ino);
3197 #endif
3198         __put_user(host_st->st_mode, &target_st->st_mode);
3199         __put_user(host_st->st_nlink, &target_st->st_nlink);
3200         __put_user(host_st->st_uid, &target_st->st_uid);
3201         __put_user(host_st->st_gid, &target_st->st_gid);
3202         __put_user(host_st->st_rdev, &target_st->st_rdev);
3203         __put_user(host_st->st_size, &target_st->st_size);
3204         __put_user(host_st->st_blksize, &target_st->st_blksize);
3205         __put_user(host_st->st_blocks, &target_st->st_blocks);
3206         __put_user(host_st->st_atime, &target_st->target_st_atime);
3207         __put_user(host_st->st_mtime, &target_st->target_st_mtime);
3208         __put_user(host_st->st_ctime, &target_st->target_st_ctime);
3209         unlock_user_struct(target_st, target_addr, 1);
3210     } else
3211 #endif
3212     {
3213         struct target_stat64 *target_st;
3214
3215         if (!lock_user_struct(VERIFY_WRITE, target_st, target_addr, 0))
3216             return -TARGET_EFAULT;
3217         memset(target_st, 0, sizeof(struct target_stat64));
3218         __put_user(host_st->st_dev, &target_st->st_dev);
3219         __put_user(host_st->st_ino, &target_st->st_ino);
3220 #ifdef TARGET_STAT64_HAS_BROKEN_ST_INO
3221         __put_user(host_st->st_ino, &target_st->__st_ino);
3222 #endif
3223         __put_user(host_st->st_mode, &target_st->st_mode);
3224         __put_user(host_st->st_nlink, &target_st->st_nlink);
3225         __put_user(host_st->st_uid, &target_st->st_uid);
3226         __put_user(host_st->st_gid, &target_st->st_gid);
3227         __put_user(host_st->st_rdev, &target_st->st_rdev);
3228         /* XXX: better use of kernel struct */
3229         __put_user(host_st->st_size, &target_st->st_size);
3230         __put_user(host_st->st_blksize, &target_st->st_blksize);
3231         __put_user(host_st->st_blocks, &target_st->st_blocks);
3232         __put_user(host_st->st_atime, &target_st->target_st_atime);
3233         __put_user(host_st->st_mtime, &target_st->target_st_mtime);
3234         __put_user(host_st->st_ctime, &target_st->target_st_ctime);
3235         unlock_user_struct(target_st, target_addr, 1);
3236     }
3237
3238     return 0;
3239 }
3240 #endif
3241
3242 #if defined(USE_NPTL)
3243 /* ??? Using host futex calls even when target atomic operations
3244    are not really atomic probably breaks things.  However implementing
3245    futexes locally would make futexes shared between multiple processes
3246    tricky.  However they're probably useless because guest atomic
3247    operations won't work either.  */
3248 static int do_futex(target_ulong uaddr, int op, int val, target_ulong timeout,
3249                     target_ulong uaddr2, int val3)
3250 {
3251     struct timespec ts, *pts;
3252
3253     /* ??? We assume FUTEX_* constants are the same on both host
3254        and target.  */
3255     switch (op) {
3256     case FUTEX_WAIT:
3257         if (timeout) {
3258             pts = &ts;
3259             target_to_host_timespec(pts, timeout);
3260         } else {
3261             pts = NULL;
3262         }
3263         return get_errno(sys_futex(g2h(uaddr), FUTEX_WAIT, tswap32(val),
3264                          pts, NULL, 0));
3265     case FUTEX_WAKE:
3266         return get_errno(sys_futex(g2h(uaddr), FUTEX_WAKE, val, NULL, NULL, 0));
3267     case FUTEX_FD:
3268         return get_errno(sys_futex(g2h(uaddr), FUTEX_FD, val, NULL, NULL, 0));
3269     case FUTEX_REQUEUE:
3270         return get_errno(sys_futex(g2h(uaddr), FUTEX_REQUEUE, val,
3271                          NULL, g2h(uaddr2), 0));
3272     case FUTEX_CMP_REQUEUE:
3273         return get_errno(sys_futex(g2h(uaddr), FUTEX_CMP_REQUEUE, val,
3274                          NULL, g2h(uaddr2), tswap32(val3)));
3275     default:
3276         return -TARGET_ENOSYS;
3277     }
3278 }
3279 #endif
3280
3281 int get_osversion(void)
3282 {
3283     static int osversion;
3284     struct new_utsname buf;
3285     const char *s;
3286     int i, n, tmp;
3287     if (osversion)
3288         return osversion;
3289     if (qemu_uname_release && *qemu_uname_release) {
3290         s = qemu_uname_release;
3291     } else {
3292         if (sys_uname(&buf))
3293             return 0;
3294         s = buf.release;
3295     }
3296     tmp = 0;
3297     for (i = 0; i < 3; i++) {
3298         n = 0;
3299         while (*s >= '0' && *s <= '9') {
3300             n *= 10;
3301             n += *s - '0';
3302             s++;
3303         }
3304         tmp = (tmp << 8) + n;
3305         if (*s == '.')
3306             s++;
3307     }
3308     osversion = tmp;
3309     return osversion;
3310 }
3311
3312 /* do_syscall() should always have a single exit point at the end so
3313    that actions, such as logging of syscall results, can be performed.
3314    All errnos that do_syscall() returns must be -TARGET_<errcode>. */
3315 abi_long do_syscall(void *cpu_env, int num, abi_long arg1,
3316                     abi_long arg2, abi_long arg3, abi_long arg4,
3317                     abi_long arg5, abi_long arg6)
3318 {
3319     abi_long ret;
3320     struct stat st;
3321     struct statfs stfs;
3322     void *p;
3323
3324 #ifdef DEBUG
3325     gemu_log("syscall %d", num);
3326 #endif
3327     if(do_strace)
3328         print_syscall(num, arg1, arg2, arg3, arg4, arg5, arg6);
3329
3330     switch(num) {
3331     case TARGET_NR_exit:
3332 #ifdef HAVE_GPROF
3333         _mcleanup();
3334 #endif
3335         gdb_exit(cpu_env, arg1);
3336         /* XXX: should free thread stack and CPU env */
3337         _exit(arg1);
3338         ret = 0; /* avoid warning */
3339         break;
3340     case TARGET_NR_read:
3341         if (!(p = lock_user(VERIFY_WRITE, arg2, arg3, 0)))
3342             goto efault;
3343         ret = get_errno(read(arg1, p, arg3));
3344         unlock_user(p, arg2, ret);
3345         break;
3346     case TARGET_NR_write:
3347         if (!(p = lock_user(VERIFY_READ, arg2, arg3, 1)))
3348             goto efault;
3349         ret = get_errno(write(arg1, p, arg3));
3350         unlock_user(p, arg2, 0);
3351         break;
3352     case TARGET_NR_open:
3353         if (!(p = lock_user_string(arg1)))
3354             goto efault;
3355         ret = get_errno(open(path(p),
3356                              target_to_host_bitmask(arg2, fcntl_flags_tbl),
3357                              arg3));
3358         unlock_user(p, arg1, 0);
3359         break;
3360 #if defined(TARGET_NR_openat) && defined(__NR_openat)
3361     case TARGET_NR_openat:
3362         if (!(p = lock_user_string(arg2)))
3363             goto efault;
3364         ret = get_errno(sys_openat(arg1,
3365                                    path(p),
3366                                    target_to_host_bitmask(arg3, fcntl_flags_tbl),
3367                                    arg4));
3368         unlock_user(p, arg2, 0);
3369         break;
3370 #endif
3371     case TARGET_NR_close:
3372         ret = get_errno(close(arg1));
3373         break;
3374     case TARGET_NR_brk:
3375         ret = do_brk(arg1);
3376         break;
3377     case TARGET_NR_fork:
3378         ret = get_errno(do_fork(cpu_env, SIGCHLD, 0, 0, 0, 0));
3379         break;
3380 #ifdef TARGET_NR_waitpid
3381     case TARGET_NR_waitpid:
3382         {
3383             int status;
3384             ret = get_errno(waitpid(arg1, &status, arg3));
3385             if (!is_error(ret) && arg2
3386                 && put_user_s32(status, arg2))
3387                 goto efault;
3388         }
3389         break;
3390 #endif
3391 #ifdef TARGET_NR_waitid
3392     case TARGET_NR_waitid:
3393         {
3394             siginfo_t info;
3395             info.si_pid = 0;
3396             ret = get_errno(waitid(arg1, arg2, &info, arg4));
3397             if (!is_error(ret) && arg3 && info.si_pid != 0) {
3398                 if (!(p = lock_user(VERIFY_WRITE, arg3, sizeof(target_siginfo_t), 0)))
3399                     goto efault;
3400                 host_to_target_siginfo(p, &info);
3401                 unlock_user(p, arg3, sizeof(target_siginfo_t));
3402             }
3403         }
3404         break;
3405 #endif
3406 #ifdef TARGET_NR_creat /* not on alpha */
3407     case TARGET_NR_creat:
3408         if (!(p = lock_user_string(arg1)))
3409             goto efault;
3410         ret = get_errno(creat(p, arg2));
3411         unlock_user(p, arg1, 0);
3412         break;
3413 #endif
3414     case TARGET_NR_link:
3415         {
3416             void * p2;
3417             p = lock_user_string(arg1);
3418             p2 = lock_user_string(arg2);
3419             if (!p || !p2)
3420                 ret = -TARGET_EFAULT;
3421             else
3422                 ret = get_errno(link(p, p2));
3423             unlock_user(p2, arg2, 0);
3424             unlock_user(p, arg1, 0);
3425         }
3426         break;
3427 #if defined(TARGET_NR_linkat) && defined(__NR_linkat)
3428     case TARGET_NR_linkat:
3429         {
3430             void * p2 = NULL;
3431             if (!arg2 || !arg4)
3432                 goto efault;
3433             p  = lock_user_string(arg2);
3434             p2 = lock_user_string(arg4);
3435             if (!p || !p2)
3436                 ret = -TARGET_EFAULT;
3437             else
3438                 ret = get_errno(sys_linkat(arg1, p, arg3, p2, arg5));
3439             unlock_user(p, arg2, 0);
3440             unlock_user(p2, arg4, 0);
3441         }
3442         break;
3443 #endif
3444     case TARGET_NR_unlink:
3445         if (!(p = lock_user_string(arg1)))
3446             goto efault;
3447         ret = get_errno(unlink(p));
3448         unlock_user(p, arg1, 0);
3449         break;
3450 #if defined(TARGET_NR_unlinkat) && defined(__NR_unlinkat)
3451     case TARGET_NR_unlinkat:
3452         if (!(p = lock_user_string(arg2)))
3453             goto efault;
3454         ret = get_errno(sys_unlinkat(arg1, p, arg3));
3455         unlock_user(p, arg2, 0);
3456         break;
3457 #endif
3458     case TARGET_NR_execve:
3459         {
3460             char **argp, **envp;
3461             int argc, envc;
3462             abi_ulong gp;
3463             abi_ulong guest_argp;
3464             abi_ulong guest_envp;
3465             abi_ulong addr;
3466             char **q;
3467
3468             argc = 0;
3469             guest_argp = arg2;
3470             for (gp = guest_argp; gp; gp += sizeof(abi_ulong)) {
3471                 if (get_user_ual(addr, gp))
3472                     goto efault;
3473                 if (!addr)
3474                     break;
3475                 argc++;
3476             }
3477             envc = 0;
3478             guest_envp = arg3;
3479             for (gp = guest_envp; gp; gp += sizeof(abi_ulong)) {
3480                 if (get_user_ual(addr, gp))
3481                     goto efault;
3482                 if (!addr)
3483                     break;
3484                 envc++;
3485             }
3486
3487             argp = alloca((argc + 1) * sizeof(void *));
3488             envp = alloca((envc + 1) * sizeof(void *));
3489
3490             for (gp = guest_argp, q = argp; gp;
3491                   gp += sizeof(abi_ulong), q++) {
3492                 if (get_user_ual(addr, gp))
3493                     goto execve_efault;
3494                 if (!addr)
3495                     break;
3496                 if (!(*q = lock_user_string(addr)))
3497                     goto execve_efault;
3498             }
3499             *q = NULL;
3500
3501             for (gp = guest_envp, q = envp; gp;
3502                   gp += sizeof(abi_ulong), q++) {
3503                 if (get_user_ual(addr, gp))
3504                     goto execve_efault;
3505                 if (!addr)
3506                     break;
3507                 if (!(*q = lock_user_string(addr)))
3508                     goto execve_efault;
3509             }
3510             *q = NULL;
3511
3512             if (!(p = lock_user_string(arg1)))
3513                 goto execve_efault;
3514             ret = get_errno(execve(p, argp, envp));
3515             unlock_user(p, arg1, 0);
3516
3517             goto execve_end;
3518
3519         execve_efault:
3520             ret = -TARGET_EFAULT;
3521
3522         execve_end:
3523             for (gp = guest_argp, q = argp; *q;
3524                   gp += sizeof(abi_ulong), q++) {
3525                 if (get_user_ual(addr, gp)
3526                     || !addr)
3527                     break;
3528                 unlock_user(*q, addr, 0);
3529             }
3530             for (gp = guest_envp, q = envp; *q;
3531                   gp += sizeof(abi_ulong), q++) {
3532                 if (get_user_ual(addr, gp)
3533                     || !addr)
3534                     break;
3535                 unlock_user(*q, addr, 0);
3536             }
3537         }
3538         break;
3539     case TARGET_NR_chdir:
3540         if (!(p = lock_user_string(arg1)))
3541             goto efault;
3542         ret = get_errno(chdir(p));
3543         unlock_user(p, arg1, 0);
3544         break;
3545 #ifdef TARGET_NR_time
3546     case TARGET_NR_time:
3547         {
3548             time_t host_time;
3549             ret = get_errno(time(&host_time));
3550             if (!is_error(ret)
3551                 && arg1
3552                 && put_user_sal(host_time, arg1))
3553                 goto efault;
3554         }
3555         break;
3556 #endif
3557     case TARGET_NR_mknod:
3558         if (!(p = lock_user_string(arg1)))
3559             goto efault;
3560         ret = get_errno(mknod(p, arg2, arg3));
3561         unlock_user(p, arg1, 0);
3562         break;
3563 #if defined(TARGET_NR_mknodat) && defined(__NR_mknodat)
3564     case TARGET_NR_mknodat:
3565         if (!(p = lock_user_string(arg2)))
3566             goto efault;
3567         ret = get_errno(sys_mknodat(arg1, p, arg3, arg4));
3568         unlock_user(p, arg2, 0);
3569         break;
3570 #endif
3571     case TARGET_NR_chmod:
3572         if (!(p = lock_user_string(arg1)))
3573             goto efault;
3574         ret = get_errno(chmod(p, arg2));
3575         unlock_user(p, arg1, 0);
3576         break;
3577 #ifdef TARGET_NR_break
3578     case TARGET_NR_break:
3579         goto unimplemented;
3580 #endif
3581 #ifdef TARGET_NR_oldstat
3582     case TARGET_NR_oldstat:
3583         goto unimplemented;
3584 #endif
3585     case TARGET_NR_lseek:
3586         ret = get_errno(lseek(arg1, arg2, arg3));
3587         break;
3588 #ifdef TARGET_NR_getxpid
3589     case TARGET_NR_getxpid:
3590 #else
3591     case TARGET_NR_getpid:
3592 #endif
3593         ret = get_errno(getpid());
3594         break;
3595     case TARGET_NR_mount:
3596                 {
3597                         /* need to look at the data field */
3598                         void *p2, *p3;
3599                         p = lock_user_string(arg1);
3600                         p2 = lock_user_string(arg2);
3601                         p3 = lock_user_string(arg3);
3602                         if (!p || !p2 || !p3)
3603                             ret = -TARGET_EFAULT;
3604                         else
3605                             /* FIXME - arg5 should be locked, but it isn't clear how to
3606                              * do that since it's not guaranteed to be a NULL-terminated
3607                              * string.
3608                              */
3609                             ret = get_errno(mount(p, p2, p3, (unsigned long)arg4, g2h(arg5)));
3610                         unlock_user(p, arg1, 0);
3611                         unlock_user(p2, arg2, 0);
3612                         unlock_user(p3, arg3, 0);
3613                         break;
3614                 }
3615 #ifdef TARGET_NR_umount
3616     case TARGET_NR_umount:
3617         if (!(p = lock_user_string(arg1)))
3618             goto efault;
3619         ret = get_errno(umount(p));
3620         unlock_user(p, arg1, 0);
3621         break;
3622 #endif
3623 #ifdef TARGET_NR_stime /* not on alpha */
3624     case TARGET_NR_stime:
3625         {
3626             time_t host_time;
3627             if (get_user_sal(host_time, arg1))
3628                 goto efault;
3629             ret = get_errno(stime(&host_time));
3630         }
3631         break;
3632 #endif
3633     case TARGET_NR_ptrace:
3634         goto unimplemented;
3635 #ifdef TARGET_NR_alarm /* not on alpha */
3636     case TARGET_NR_alarm:
3637         ret = alarm(arg1);
3638         break;
3639 #endif
3640 #ifdef TARGET_NR_oldfstat
3641     case TARGET_NR_oldfstat:
3642         goto unimplemented;
3643 #endif
3644 #ifdef TARGET_NR_pause /* not on alpha */
3645     case TARGET_NR_pause:
3646         ret = get_errno(pause());
3647         break;
3648 #endif
3649 #ifdef TARGET_NR_utime
3650     case TARGET_NR_utime:
3651         {
3652             struct utimbuf tbuf, *host_tbuf;
3653             struct target_utimbuf *target_tbuf;
3654             if (arg2) {
3655                 if (!lock_user_struct(VERIFY_READ, target_tbuf, arg2, 1))
3656                     goto efault;
3657                 tbuf.actime = tswapl(target_tbuf->actime);
3658                 tbuf.modtime = tswapl(target_tbuf->modtime);
3659                 unlock_user_struct(target_tbuf, arg2, 0);
3660                 host_tbuf = &tbuf;
3661             } else {
3662                 host_tbuf = NULL;
3663             }
3664             if (!(p = lock_user_string(arg1)))
3665                 goto efault;
3666             ret = get_errno(utime(p, host_tbuf));
3667             unlock_user(p, arg1, 0);
3668         }
3669         break;
3670 #endif
3671     case TARGET_NR_utimes:
3672         {
3673             struct timeval *tvp, tv[2];
3674             if (arg2) {
3675                 if (copy_from_user_timeval(&tv[0], arg2)
3676                     || copy_from_user_timeval(&tv[1],
3677                                               arg2 + sizeof(struct target_timeval)))
3678                     goto efault;
3679                 tvp = tv;
3680             } else {
3681                 tvp = NULL;
3682             }
3683             if (!(p = lock_user_string(arg1)))
3684                 goto efault;
3685             ret = get_errno(utimes(p, tvp));
3686             unlock_user(p, arg1, 0);
3687         }
3688         break;
3689 #if defined(TARGET_NR_futimesat) && defined(__NR_futimesat)
3690     case TARGET_NR_futimesat:
3691         {
3692             struct timeval *tvp, tv[2];
3693             if (arg3) {
3694                 if (copy_from_user_timeval(&tv[0], arg3)
3695                     || copy_from_user_timeval(&tv[1],
3696                                               arg3 + sizeof(struct target_timeval)))
3697                     goto efault;
3698                 tvp = tv;
3699             } else {
3700                 tvp = NULL;
3701             }
3702             if (!(p = lock_user_string(arg2)))
3703                 goto efault;
3704             ret = get_errno(sys_futimesat(arg1, path(p), tvp));
3705             unlock_user(p, arg2, 0);
3706         }
3707         break;
3708 #endif
3709 #ifdef TARGET_NR_stty
3710     case TARGET_NR_stty:
3711         goto unimplemented;
3712 #endif
3713 #ifdef TARGET_NR_gtty
3714     case TARGET_NR_gtty:
3715         goto unimplemented;
3716 #endif
3717     case TARGET_NR_access:
3718         if (!(p = lock_user_string(arg1)))
3719             goto efault;
3720         ret = get_errno(access(p, arg2));
3721         unlock_user(p, arg1, 0);
3722         break;
3723 #if defined(TARGET_NR_faccessat) && defined(__NR_faccessat)
3724     case TARGET_NR_faccessat:
3725         if (!(p = lock_user_string(arg2)))
3726             goto efault;
3727         ret = get_errno(sys_faccessat(arg1, p, arg3, arg4));
3728         unlock_user(p, arg2, 0);
3729         break;
3730 #endif
3731 #ifdef TARGET_NR_nice /* not on alpha */
3732     case TARGET_NR_nice:
3733         ret = get_errno(nice(arg1));
3734         break;
3735 #endif
3736 #ifdef TARGET_NR_ftime
3737     case TARGET_NR_ftime:
3738         goto unimplemented;
3739 #endif
3740     case TARGET_NR_sync:
3741         sync();
3742         ret = 0;
3743         break;
3744     case TARGET_NR_kill:
3745         ret = get_errno(kill(arg1, target_to_host_signal(arg2)));
3746         break;
3747     case TARGET_NR_rename:
3748         {
3749             void *p2;
3750             p = lock_user_string(arg1);
3751             p2 = lock_user_string(arg2);
3752             if (!p || !p2)
3753                 ret = -TARGET_EFAULT;
3754             else
3755                 ret = get_errno(rename(p, p2));
3756             unlock_user(p2, arg2, 0);
3757             unlock_user(p, arg1, 0);
3758         }
3759         break;
3760 #if defined(TARGET_NR_renameat) && defined(__NR_renameat)
3761     case TARGET_NR_renameat:
3762         {
3763             void *p2;
3764             p  = lock_user_string(arg2);
3765             p2 = lock_user_string(arg4);
3766             if (!p || !p2)
3767                 ret = -TARGET_EFAULT;
3768             else
3769                 ret = get_errno(sys_renameat(arg1, p, arg3, p2));
3770             unlock_user(p2, arg4, 0);
3771             unlock_user(p, arg2, 0);
3772         }
3773         break;
3774 #endif
3775     case TARGET_NR_mkdir:
3776         if (!(p = lock_user_string(arg1)))
3777             goto efault;
3778         ret = get_errno(mkdir(p, arg2));
3779         unlock_user(p, arg1, 0);
3780         break;
3781 #if defined(TARGET_NR_mkdirat) && defined(__NR_mkdirat)
3782     case TARGET_NR_mkdirat:
3783         if (!(p = lock_user_string(arg2)))
3784             goto efault;
3785         ret = get_errno(sys_mkdirat(arg1, p, arg3));
3786         unlock_user(p, arg2, 0);
3787         break;
3788 #endif
3789     case TARGET_NR_rmdir:
3790         if (!(p = lock_user_string(arg1)))
3791             goto efault;
3792         ret = get_errno(rmdir(p));
3793         unlock_user(p, arg1, 0);
3794         break;
3795     case TARGET_NR_dup:
3796         ret = get_errno(dup(arg1));
3797         break;
3798     case TARGET_NR_pipe:
3799         {
3800             int host_pipe[2];
3801             ret = get_errno(pipe(host_pipe));
3802             if (!is_error(ret)) {
3803 #if defined(TARGET_MIPS)
3804                 CPUMIPSState *env = (CPUMIPSState*)cpu_env;
3805                 env->active_tc.gpr[3] = host_pipe[1];
3806                 ret = host_pipe[0];
3807 #elif defined(TARGET_SH4)
3808                 ((CPUSH4State*)cpu_env)->gregs[1] = host_pipe[1];
3809                 ret = host_pipe[0];
3810 #else
3811                 if (put_user_s32(host_pipe[0], arg1)
3812                     || put_user_s32(host_pipe[1], arg1 + sizeof(host_pipe[0])))
3813                     goto efault;
3814 #endif
3815             }
3816         }
3817         break;
3818     case TARGET_NR_times:
3819         {
3820             struct target_tms *tmsp;
3821             struct tms tms;
3822             ret = get_errno(times(&tms));
3823             if (arg1) {
3824                 tmsp = lock_user(VERIFY_WRITE, arg1, sizeof(struct target_tms), 0);
3825                 if (!tmsp)
3826                     goto efault;
3827                 tmsp->tms_utime = tswapl(host_to_target_clock_t(tms.tms_utime));
3828                 tmsp->tms_stime = tswapl(host_to_target_clock_t(tms.tms_stime));
3829                 tmsp->tms_cutime = tswapl(host_to_target_clock_t(tms.tms_cutime));
3830                 tmsp->tms_cstime = tswapl(host_to_target_clock_t(tms.tms_cstime));
3831             }
3832             if (!is_error(ret))
3833                 ret = host_to_target_clock_t(ret);
3834         }
3835         break;
3836 #ifdef TARGET_NR_prof
3837     case TARGET_NR_prof:
3838         goto unimplemented;
3839 #endif
3840 #ifdef TARGET_NR_signal
3841     case TARGET_NR_signal:
3842         goto unimplemented;
3843 #endif
3844     case TARGET_NR_acct:
3845         if (!(p = lock_user_string(arg1)))
3846             goto efault;
3847         ret = get_errno(acct(path(p)));
3848         unlock_user(p, arg1, 0);
3849         break;
3850 #ifdef TARGET_NR_umount2 /* not on alpha */
3851     case TARGET_NR_umount2:
3852         if (!(p = lock_user_string(arg1)))
3853             goto efault;
3854         ret = get_errno(umount2(p, arg2));
3855         unlock_user(p, arg1, 0);
3856         break;
3857 #endif
3858 #ifdef TARGET_NR_lock
3859     case TARGET_NR_lock:
3860         goto unimplemented;
3861 #endif
3862     case TARGET_NR_ioctl:
3863         ret = do_ioctl(arg1, arg2, arg3);
3864         break;
3865     case TARGET_NR_fcntl:
3866         ret = do_fcntl(arg1, arg2, arg3);
3867         break;
3868 #ifdef TARGET_NR_mpx
3869     case TARGET_NR_mpx:
3870         goto unimplemented;
3871 #endif
3872     case TARGET_NR_setpgid:
3873         ret = get_errno(setpgid(arg1, arg2));
3874         break;
3875 #ifdef TARGET_NR_ulimit
3876     case TARGET_NR_ulimit:
3877         goto unimplemented;
3878 #endif
3879 #ifdef TARGET_NR_oldolduname
3880     case TARGET_NR_oldolduname:
3881         goto unimplemented;
3882 #endif
3883     case TARGET_NR_umask:
3884         ret = get_errno(umask(arg1));
3885         break;
3886     case TARGET_NR_chroot:
3887         if (!(p = lock_user_string(arg1)))
3888             goto efault;
3889         ret = get_errno(chroot(p));
3890         unlock_user(p, arg1, 0);
3891         break;
3892     case TARGET_NR_ustat:
3893         goto unimplemented;
3894     case TARGET_NR_dup2:
3895         ret = get_errno(dup2(arg1, arg2));
3896         break;
3897 #ifdef TARGET_NR_getppid /* not on alpha */
3898     case TARGET_NR_getppid:
3899         ret = get_errno(getppid());
3900         break;
3901 #endif
3902     case TARGET_NR_getpgrp:
3903         ret = get_errno(getpgrp());
3904         break;
3905     case TARGET_NR_setsid:
3906         ret = get_errno(setsid());
3907         break;
3908 #ifdef TARGET_NR_sigaction
3909     case TARGET_NR_sigaction:
3910         {
3911 #if !defined(TARGET_MIPS)
3912             struct target_old_sigaction *old_act;
3913             struct target_sigaction act, oact, *pact;
3914             if (arg2) {
3915                 if (!lock_user_struct(VERIFY_READ, old_act, arg2, 1))
3916                     goto efault;
3917                 act._sa_handler = old_act->_sa_handler;
3918                 target_siginitset(&act.sa_mask, old_act->sa_mask);
3919                 act.sa_flags = old_act->sa_flags;
3920                 act.sa_restorer = old_act->sa_restorer;
3921                 unlock_user_struct(old_act, arg2, 0);
3922                 pact = &act;
3923             } else {
3924                 pact = NULL;
3925             }
3926             ret = get_errno(do_sigaction(arg1, pact, &oact));
3927             if (!is_error(ret) && arg3) {
3928                 if (!lock_user_struct(VERIFY_WRITE, old_act, arg3, 0))
3929                     goto efault;
3930                 old_act->_sa_handler = oact._sa_handler;
3931                 old_act->sa_mask = oact.sa_mask.sig[0];
3932                 old_act->sa_flags = oact.sa_flags;
3933                 old_act->sa_restorer = oact.sa_restorer;
3934                 unlock_user_struct(old_act, arg3, 1);
3935             }
3936 #else
3937             struct target_sigaction act, oact, *pact, *old_act;
3938
3939             if (arg2) {
3940                 if (!lock_user_struct(VERIFY_READ, old_act, arg2, 1))
3941                     goto efault;
3942                 act._sa_handler = old_act->_sa_handler;
3943                 target_siginitset(&act.sa_mask, old_act->sa_mask.sig[0]);
3944                 act.sa_flags = old_act->sa_flags;
3945                 unlock_user_struct(old_act, arg2, 0);
3946                 pact = &act;
3947             } else {
3948                 pact = NULL;
3949             }
3950
3951             ret = get_errno(do_sigaction(arg1, pact, &oact));
3952
3953             if (!is_error(ret) && arg3) {
3954                 if (!lock_user_struct(VERIFY_WRITE, old_act, arg3, 0))
3955                     goto efault;
3956                 old_act->_sa_handler = oact._sa_handler;
3957                 old_act->sa_flags = oact.sa_flags;
3958                 old_act->sa_mask.sig[0] = oact.sa_mask.sig[0];
3959                 old_act->sa_mask.sig[1] = 0;
3960                 old_act->sa_mask.sig[2] = 0;
3961                 old_act->sa_mask.sig[3] = 0;
3962                 unlock_user_struct(old_act, arg3, 1);
3963             }
3964 #endif
3965         }
3966         break;
3967 #endif
3968     case TARGET_NR_rt_sigaction:
3969         {
3970             struct target_sigaction *act;
3971             struct target_sigaction *oact;
3972
3973             if (arg2) {
3974                 if (!lock_user_struct(VERIFY_READ, act, arg2, 1))
3975                     goto efault;
3976             } else
3977                 act = NULL;
3978             if (arg3) {
3979                 if (!lock_user_struct(VERIFY_WRITE, oact, arg3, 0)) {
3980                     ret = -TARGET_EFAULT;
3981                     goto rt_sigaction_fail;
3982                 }
3983             } else
3984                 oact = NULL;
3985             ret = get_errno(do_sigaction(arg1, act, oact));
3986         rt_sigaction_fail:
3987             if (act)
3988                 unlock_user_struct(act, arg2, 0);
3989             if (oact)
3990                 unlock_user_struct(oact, arg3, 1);
3991         }
3992         break;
3993 #ifdef TARGET_NR_sgetmask /* not on alpha */
3994     case TARGET_NR_sgetmask:
3995         {
3996             sigset_t cur_set;
3997             abi_ulong target_set;
3998             sigprocmask(0, NULL, &cur_set);
3999             host_to_target_old_sigset(&target_set, &cur_set);
4000             ret = target_set;
4001         }
4002         break;
4003 #endif
4004 #ifdef TARGET_NR_ssetmask /* not on alpha */
4005     case TARGET_NR_ssetmask:
4006         {
4007             sigset_t set, oset, cur_set;
4008             abi_ulong target_set = arg1;
4009             sigprocmask(0, NULL, &cur_set);
4010             target_to_host_old_sigset(&set, &target_set);
4011             sigorset(&set, &set, &cur_set);
4012             sigprocmask(SIG_SETMASK, &set, &oset);
4013             host_to_target_old_sigset(&target_set, &oset);
4014             ret = target_set;
4015         }
4016         break;
4017 #endif
4018 #ifdef TARGET_NR_sigprocmask
4019     case TARGET_NR_sigprocmask:
4020         {
4021             int how = arg1;
4022             sigset_t set, oldset, *set_ptr;
4023
4024             if (arg2) {
4025                 switch(how) {
4026                 case TARGET_SIG_BLOCK:
4027                     how = SIG_BLOCK;
4028                     break;
4029                 case TARGET_SIG_UNBLOCK:
4030                     how = SIG_UNBLOCK;
4031                     break;
4032                 case TARGET_SIG_SETMASK:
4033                     how = SIG_SETMASK;
4034                     break;
4035                 default:
4036                     ret = -TARGET_EINVAL;
4037                     goto fail;
4038                 }
4039                 if (!(p = lock_user(VERIFY_READ, arg2, sizeof(target_sigset_t), 1)))
4040                     goto efault;
4041                 target_to_host_old_sigset(&set, p);
4042                 unlock_user(p, arg2, 0);
4043                 set_ptr = &set;
4044             } else {
4045                 how = 0;
4046                 set_ptr = NULL;
4047             }
4048             ret = get_errno(sigprocmask(arg1, set_ptr, &oldset));
4049             if (!is_error(ret) && arg3) {
4050                 if (!(p = lock_user(VERIFY_WRITE, arg3, sizeof(target_sigset_t), 0)))
4051                     goto efault;
4052                 host_to_target_old_sigset(p, &oldset);
4053                 unlock_user(p, arg3, sizeof(target_sigset_t));
4054             }
4055         }
4056         break;
4057 #endif
4058     case TARGET_NR_rt_sigprocmask:
4059         {
4060             int how = arg1;
4061             sigset_t set, oldset, *set_ptr;
4062
4063             if (arg2) {
4064                 switch(how) {
4065                 case TARGET_SIG_BLOCK:
4066                     how = SIG_BLOCK;
4067                     break;
4068                 case TARGET_SIG_UNBLOCK:
4069                     how = SIG_UNBLOCK;
4070                     break;
4071                 case TARGET_SIG_SETMASK:
4072                     how = SIG_SETMASK;
4073                     break;
4074                 default:
4075                     ret = -TARGET_EINVAL;
4076                     goto fail;
4077                 }
4078                 if (!(p = lock_user(VERIFY_READ, arg2, sizeof(target_sigset_t), 1)))
4079                     goto efault;
4080                 target_to_host_sigset(&set, p);
4081                 unlock_user(p, arg2, 0);
4082                 set_ptr = &set;
4083             } else {
4084                 how = 0;
4085                 set_ptr = NULL;
4086             }
4087             ret = get_errno(sigprocmask(how, set_ptr, &oldset));
4088             if (!is_error(ret) && arg3) {
4089                 if (!(p = lock_user(VERIFY_WRITE, arg3, sizeof(target_sigset_t), 0)))
4090                     goto efault;
4091                 host_to_target_sigset(p, &oldset);
4092                 unlock_user(p, arg3, sizeof(target_sigset_t));
4093             }
4094         }
4095         break;
4096 #ifdef TARGET_NR_sigpending
4097     case TARGET_NR_sigpending:
4098         {
4099             sigset_t set;
4100             ret = get_errno(sigpending(&set));
4101             if (!is_error(ret)) {
4102                 if (!(p = lock_user(VERIFY_WRITE, arg1, sizeof(target_sigset_t), 0)))
4103                     goto efault;
4104                 host_to_target_old_sigset(p, &set);
4105                 unlock_user(p, arg1, sizeof(target_sigset_t));
4106             }
4107         }
4108         break;
4109 #endif
4110     case TARGET_NR_rt_sigpending:
4111         {
4112             sigset_t set;
4113             ret = get_errno(sigpending(&set));
4114             if (!is_error(ret)) {
4115                 if (!(p = lock_user(VERIFY_WRITE, arg1, sizeof(target_sigset_t), 0)))
4116                     goto efault;
4117                 host_to_target_sigset(p, &set);
4118                 unlock_user(p, arg1, sizeof(target_sigset_t));
4119             }
4120         }
4121         break;
4122 #ifdef TARGET_NR_sigsuspend
4123     case TARGET_NR_sigsuspend:
4124         {
4125             sigset_t set;
4126             if (!(p = lock_user(VERIFY_READ, arg1, sizeof(target_sigset_t), 1)))
4127                 goto efault;
4128             target_to_host_old_sigset(&set, p);
4129             unlock_user(p, arg1, 0);
4130             ret = get_errno(sigsuspend(&set));
4131         }
4132         break;
4133 #endif
4134     case TARGET_NR_rt_sigsuspend:
4135         {
4136             sigset_t set;
4137             if (!(p = lock_user(VERIFY_READ, arg1, sizeof(target_sigset_t), 1)))
4138                 goto efault;
4139             target_to_host_sigset(&set, p);
4140             unlock_user(p, arg1, 0);
4141             ret = get_errno(sigsuspend(&set));
4142         }
4143         break;
4144     case TARGET_NR_rt_sigtimedwait:
4145         {
4146             sigset_t set;
4147             struct timespec uts, *puts;
4148             siginfo_t uinfo;
4149
4150             if (!(p = lock_user(VERIFY_READ, arg1, sizeof(target_sigset_t), 1)))
4151                 goto efault;
4152             target_to_host_sigset(&set, p);
4153             unlock_user(p, arg1, 0);
4154             if (arg3) {
4155                 puts = &uts;
4156                 target_to_host_timespec(puts, arg3);
4157             } else {
4158                 puts = NULL;
4159             }
4160             ret = get_errno(sigtimedwait(&set, &uinfo, puts));
4161             if (!is_error(ret) && arg2) {
4162                 if (!(p = lock_user(VERIFY_WRITE, arg2, sizeof(target_siginfo_t), 0)))
4163                     goto efault;
4164                 host_to_target_siginfo(p, &uinfo);
4165                 unlock_user(p, arg2, sizeof(target_siginfo_t));
4166             }
4167         }
4168         break;
4169     case TARGET_NR_rt_sigqueueinfo:
4170         {
4171             siginfo_t uinfo;
4172             if (!(p = lock_user(VERIFY_READ, arg3, sizeof(target_sigset_t), 1)))
4173                 goto efault;
4174             target_to_host_siginfo(&uinfo, p);
4175             unlock_user(p, arg1, 0);
4176             ret = get_errno(sys_rt_sigqueueinfo(arg1, arg2, &uinfo));
4177         }
4178         break;
4179 #ifdef TARGET_NR_sigreturn
4180     case TARGET_NR_sigreturn:
4181         /* NOTE: ret is eax, so not transcoding must be done */
4182         ret = do_sigreturn(cpu_env);
4183         break;
4184 #endif
4185     case TARGET_NR_rt_sigreturn:
4186         /* NOTE: ret is eax, so not transcoding must be done */
4187         ret = do_rt_sigreturn(cpu_env);
4188         break;
4189     case TARGET_NR_sethostname:
4190         if (!(p = lock_user_string(arg1)))
4191             goto efault;
4192         ret = get_errno(sethostname(p, arg2));
4193         unlock_user(p, arg1, 0);
4194         break;
4195     case TARGET_NR_setrlimit:
4196         {
4197             /* XXX: convert resource ? */
4198             int resource = arg1;
4199             struct target_rlimit *target_rlim;
4200             struct rlimit rlim;
4201             if (!lock_user_struct(VERIFY_READ, target_rlim, arg2, 1))
4202                 goto efault;
4203             rlim.rlim_cur = tswapl(target_rlim->rlim_cur);
4204             rlim.rlim_max = tswapl(target_rlim->rlim_max);
4205             unlock_user_struct(target_rlim, arg2, 0);
4206             ret = get_errno(setrlimit(resource, &rlim));
4207         }
4208         break;
4209     case TARGET_NR_getrlimit:
4210         {
4211             /* XXX: convert resource ? */
4212             int resource = arg1;
4213             struct target_rlimit *target_rlim;
4214             struct rlimit rlim;
4215
4216             ret = get_errno(getrlimit(resource, &rlim));
4217             if (!is_error(ret)) {
4218                 if (!lock_user_struct(VERIFY_WRITE, target_rlim, arg2, 0))
4219                     goto efault;
4220                 rlim.rlim_cur = tswapl(target_rlim->rlim_cur);
4221                 rlim.rlim_max = tswapl(target_rlim->rlim_max);
4222                 unlock_user_struct(target_rlim, arg2, 1);
4223             }
4224         }
4225         break;
4226     case TARGET_NR_getrusage:
4227         {
4228             struct rusage rusage;
4229             ret = get_errno(getrusage(arg1, &rusage));
4230             if (!is_error(ret)) {
4231                 host_to_target_rusage(arg2, &rusage);
4232             }
4233         }
4234         break;
4235     case TARGET_NR_gettimeofday:
4236         {
4237             struct timeval tv;
4238             ret = get_errno(gettimeofday(&tv, NULL));
4239             if (!is_error(ret)) {
4240                 if (copy_to_user_timeval(arg1, &tv))
4241                     goto efault;
4242             }
4243         }
4244         break;
4245     case TARGET_NR_settimeofday:
4246         {
4247             struct timeval tv;
4248             if (copy_from_user_timeval(&tv, arg1))
4249                 goto efault;
4250             ret = get_errno(settimeofday(&tv, NULL));
4251         }
4252         break;
4253 #ifdef TARGET_NR_select
4254     case TARGET_NR_select:
4255         {
4256             struct target_sel_arg_struct *sel;
4257             abi_ulong inp, outp, exp, tvp;
4258             long nsel;
4259
4260             if (!lock_user_struct(VERIFY_READ, sel, arg1, 1))
4261                 goto efault;
4262             nsel = tswapl(sel->n);
4263             inp = tswapl(sel->inp);
4264             outp = tswapl(sel->outp);
4265             exp = tswapl(sel->exp);
4266             tvp = tswapl(sel->tvp);
4267             unlock_user_struct(sel, arg1, 0);
4268             ret = do_select(nsel, inp, outp, exp, tvp);
4269         }
4270         break;
4271 #endif
4272     case TARGET_NR_symlink:
4273         {
4274             void *p2;
4275             p = lock_user_string(arg1);
4276             p2 = lock_user_string(arg2);
4277             if (!p || !p2)
4278                 ret = -TARGET_EFAULT;
4279             else
4280                 ret = get_errno(symlink(p, p2));
4281             unlock_user(p2, arg2, 0);
4282             unlock_user(p, arg1, 0);
4283         }
4284         break;
4285 #if defined(TARGET_NR_symlinkat) && defined(__NR_symlinkat)
4286     case TARGET_NR_symlinkat:
4287         {
4288             void *p2;
4289             p  = lock_user_string(arg1);
4290             p2 = lock_user_string(arg3);
4291             if (!p || !p2)
4292                 ret = -TARGET_EFAULT;
4293             else
4294                 ret = get_errno(sys_symlinkat(p, arg2, p2));
4295             unlock_user(p2, arg3, 0);
4296             unlock_user(p, arg1, 0);
4297         }
4298         break;
4299 #endif
4300 #ifdef TARGET_NR_oldlstat
4301     case TARGET_NR_oldlstat:
4302         goto unimplemented;
4303 #endif
4304     case TARGET_NR_readlink:
4305         {
4306             void *p2;
4307             p = lock_user_string(arg1);
4308             p2 = lock_user(VERIFY_WRITE, arg2, arg3, 0);
4309             if (!p || !p2)
4310                 ret = -TARGET_EFAULT;
4311             else
4312                 ret = get_errno(readlink(path(p), p2, arg3));
4313             unlock_user(p2, arg2, ret);
4314             unlock_user(p, arg1, 0);
4315         }
4316         break;
4317 #if defined(TARGET_NR_readlinkat) && defined(__NR_readlinkat)
4318     case TARGET_NR_readlinkat:
4319         {
4320             void *p2;
4321             p  = lock_user_string(arg2);
4322             p2 = lock_user(VERIFY_WRITE, arg3, arg4, 0);
4323             if (!p || !p2)
4324                 ret = -TARGET_EFAULT;
4325             else
4326                 ret = get_errno(sys_readlinkat(arg1, path(p), p2, arg4));
4327             unlock_user(p2, arg3, ret);
4328             unlock_user(p, arg2, 0);
4329         }
4330         break;
4331 #endif
4332 #ifdef TARGET_NR_uselib
4333     case TARGET_NR_uselib:
4334         goto unimplemented;
4335 #endif
4336 #ifdef TARGET_NR_swapon
4337     case TARGET_NR_swapon:
4338         if (!(p = lock_user_string(arg1)))
4339             goto efault;
4340         ret = get_errno(swapon(p, arg2));
4341         unlock_user(p, arg1, 0);
4342         break;
4343 #endif
4344     case TARGET_NR_reboot:
4345         goto unimplemented;
4346 #ifdef TARGET_NR_readdir
4347     case TARGET_NR_readdir:
4348         goto unimplemented;
4349 #endif
4350 #ifdef TARGET_NR_mmap
4351     case TARGET_NR_mmap:
4352 #if (defined(TARGET_I386) && defined(TARGET_ABI32)) || defined(TARGET_ARM) || defined(TARGET_M68K) || defined(TARGET_CRIS)
4353         {
4354             abi_ulong *v;
4355             abi_ulong v1, v2, v3, v4, v5, v6;
4356             if (!(v = lock_user(VERIFY_READ, arg1, 6 * sizeof(abi_ulong), 1)))
4357                 goto efault;
4358             v1 = tswapl(v[0]);
4359             v2 = tswapl(v[1]);
4360             v3 = tswapl(v[2]);
4361             v4 = tswapl(v[3]);
4362             v5 = tswapl(v[4]);
4363             v6 = tswapl(v[5]);
4364             unlock_user(v, arg1, 0);
4365             ret = get_errno(target_mmap(v1, v2, v3,
4366                                         target_to_host_bitmask(v4, mmap_flags_tbl),
4367                                         v5, v6));
4368         }
4369 #else
4370         ret = get_errno(target_mmap(arg1, arg2, arg3,
4371                                     target_to_host_bitmask(arg4, mmap_flags_tbl),
4372                                     arg5,
4373                                     arg6));
4374 #endif
4375         break;
4376 #endif
4377 #ifdef TARGET_NR_mmap2
4378     case TARGET_NR_mmap2:
4379 #ifndef MMAP_SHIFT
4380 #define MMAP_SHIFT 12
4381 #endif
4382         ret = get_errno(target_mmap(arg1, arg2, arg3,
4383                                     target_to_host_bitmask(arg4, mmap_flags_tbl),
4384                                     arg5,
4385                                     arg6 << MMAP_SHIFT));
4386         break;
4387 #endif
4388     case TARGET_NR_munmap:
4389         ret = get_errno(target_munmap(arg1, arg2));
4390         break;
4391     case TARGET_NR_mprotect:
4392         ret = get_errno(target_mprotect(arg1, arg2, arg3));
4393         break;
4394 #ifdef TARGET_NR_mremap
4395     case TARGET_NR_mremap:
4396         ret = get_errno(target_mremap(arg1, arg2, arg3, arg4, arg5));
4397         break;
4398 #endif
4399         /* ??? msync/mlock/munlock are broken for softmmu.  */
4400 #ifdef TARGET_NR_msync
4401     case TARGET_NR_msync:
4402         ret = get_errno(msync(g2h(arg1), arg2, arg3));
4403         break;
4404 #endif
4405 #ifdef TARGET_NR_mlock
4406     case TARGET_NR_mlock:
4407         ret = get_errno(mlock(g2h(arg1), arg2));
4408         break;
4409 #endif
4410 #ifdef TARGET_NR_munlock
4411     case TARGET_NR_munlock:
4412         ret = get_errno(munlock(g2h(arg1), arg2));
4413         break;
4414 #endif
4415 #ifdef TARGET_NR_mlockall
4416     case TARGET_NR_mlockall:
4417         ret = get_errno(mlockall(arg1));
4418         break;
4419 #endif
4420 #ifdef TARGET_NR_munlockall
4421     case TARGET_NR_munlockall:
4422         ret = get_errno(munlockall());
4423         break;
4424 #endif
4425     case TARGET_NR_truncate:
4426         if (!(p = lock_user_string(arg1)))
4427             goto efault;
4428         ret = get_errno(truncate(p, arg2));
4429         unlock_user(p, arg1, 0);
4430         break;
4431     case TARGET_NR_ftruncate:
4432         ret = get_errno(ftruncate(arg1, arg2));
4433         break;
4434     case TARGET_NR_fchmod:
4435         ret = get_errno(fchmod(arg1, arg2));
4436         break;
4437 #if defined(TARGET_NR_fchmodat) && defined(__NR_fchmodat)
4438     case TARGET_NR_fchmodat:
4439         if (!(p = lock_user_string(arg2)))
4440             goto efault;
4441         ret = get_errno(sys_fchmodat(arg1, p, arg3, arg4));
4442         unlock_user(p, arg2, 0);
4443         break;
4444 #endif
4445     case TARGET_NR_getpriority:
4446         /* libc does special remapping of the return value of
4447          * sys_getpriority() so it's just easiest to call
4448          * sys_getpriority() directly rather than through libc. */
4449         ret = sys_getpriority(arg1, arg2);
4450         break;
4451     case TARGET_NR_setpriority:
4452         ret = get_errno(setpriority(arg1, arg2, arg3));
4453         break;
4454 #ifdef TARGET_NR_profil
4455     case TARGET_NR_profil:
4456         goto unimplemented;
4457 #endif
4458     case TARGET_NR_statfs:
4459         if (!(p = lock_user_string(arg1)))
4460             goto efault;
4461         ret = get_errno(statfs(path(p), &stfs));
4462         unlock_user(p, arg1, 0);
4463     convert_statfs:
4464         if (!is_error(ret)) {
4465             struct target_statfs *target_stfs;
4466
4467             if (!lock_user_struct(VERIFY_WRITE, target_stfs, arg2, 0))
4468                 goto efault;
4469             __put_user(stfs.f_type, &target_stfs->f_type);
4470             __put_user(stfs.f_bsize, &target_stfs->f_bsize);
4471             __put_user(stfs.f_blocks, &target_stfs->f_blocks);
4472             __put_user(stfs.f_bfree, &target_stfs->f_bfree);
4473             __put_user(stfs.f_bavail, &target_stfs->f_bavail);
4474             __put_user(stfs.f_files, &target_stfs->f_files);
4475             __put_user(stfs.f_ffree, &target_stfs->f_ffree);
4476             __put_user(stfs.f_fsid.__val[0], &target_stfs->f_fsid.val[0]);
4477             __put_user(stfs.f_fsid.__val[1], &target_stfs->f_fsid.val[1]);
4478             __put_user(stfs.f_namelen, &target_stfs->f_namelen);
4479             unlock_user_struct(target_stfs, arg2, 1);
4480         }
4481         break;
4482     case TARGET_NR_fstatfs:
4483         ret = get_errno(fstatfs(arg1, &stfs));
4484         goto convert_statfs;
4485 #ifdef TARGET_NR_statfs64
4486     case TARGET_NR_statfs64:
4487         if (!(p = lock_user_string(arg1)))
4488             goto efault;
4489         ret = get_errno(statfs(path(p), &stfs));
4490         unlock_user(p, arg1, 0);
4491     convert_statfs64:
4492         if (!is_error(ret)) {
4493             struct target_statfs64 *target_stfs;
4494
4495             if (!lock_user_struct(VERIFY_WRITE, target_stfs, arg3, 0))
4496                 goto efault;
4497             __put_user(stfs.f_type, &target_stfs->f_type);
4498             __put_user(stfs.f_bsize, &target_stfs->f_bsize);
4499             __put_user(stfs.f_blocks, &target_stfs->f_blocks);
4500             __put_user(stfs.f_bfree, &target_stfs->f_bfree);
4501             __put_user(stfs.f_bavail, &target_stfs->f_bavail);
4502             __put_user(stfs.f_files, &target_stfs->f_files);
4503             __put_user(stfs.f_ffree, &target_stfs->f_ffree);
4504             __put_user(stfs.f_fsid.__val[0], &target_stfs->f_fsid.val[0]);
4505             __put_user(stfs.f_fsid.__val[1], &target_stfs->f_fsid.val[1]);
4506             __put_user(stfs.f_namelen, &target_stfs->f_namelen);
4507             unlock_user_struct(target_stfs, arg3, 1);
4508         }
4509         break;
4510     case TARGET_NR_fstatfs64:
4511         ret = get_errno(fstatfs(arg1, &stfs));
4512         goto convert_statfs64;
4513 #endif
4514 #ifdef TARGET_NR_ioperm
4515     case TARGET_NR_ioperm:
4516         goto unimplemented;
4517 #endif
4518 #ifdef TARGET_NR_socketcall
4519     case TARGET_NR_socketcall:
4520         ret = do_socketcall(arg1, arg2);
4521         break;
4522 #endif
4523 #ifdef TARGET_NR_accept
4524     case TARGET_NR_accept:
4525         ret = do_accept(arg1, arg2, arg3);
4526         break;
4527 #endif
4528 #ifdef TARGET_NR_bind
4529     case TARGET_NR_bind:
4530         ret = do_bind(arg1, arg2, arg3);
4531         break;
4532 #endif
4533 #ifdef TARGET_NR_connect
4534     case TARGET_NR_connect:
4535         ret = do_connect(arg1, arg2, arg3);
4536         break;
4537 #endif
4538 #ifdef TARGET_NR_getpeername
4539     case TARGET_NR_getpeername:
4540         ret = do_getpeername(arg1, arg2, arg3);
4541         break;
4542 #endif
4543 #ifdef TARGET_NR_getsockname
4544     case TARGET_NR_getsockname:
4545         ret = do_getsockname(arg1, arg2, arg3);
4546         break;
4547 #endif
4548 #ifdef TARGET_NR_getsockopt
4549     case TARGET_NR_getsockopt:
4550         ret = do_getsockopt(arg1, arg2, arg3, arg4, arg5);
4551         break;
4552 #endif
4553 #ifdef TARGET_NR_listen
4554     case TARGET_NR_listen:
4555         ret = get_errno(listen(arg1, arg2));
4556         break;
4557 #endif
4558 #ifdef TARGET_NR_recv
4559     case TARGET_NR_recv:
4560         ret = do_recvfrom(arg1, arg2, arg3, arg4, 0, 0);
4561         break;
4562 #endif
4563 #ifdef TARGET_NR_recvfrom
4564     case TARGET_NR_recvfrom:
4565         ret = do_recvfrom(arg1, arg2, arg3, arg4, arg5, arg6);
4566         break;
4567 #endif
4568 #ifdef TARGET_NR_recvmsg
4569     case TARGET_NR_recvmsg:
4570         ret = do_sendrecvmsg(arg1, arg2, arg3, 0);
4571         break;
4572 #endif
4573 #ifdef TARGET_NR_send
4574     case TARGET_NR_send:
4575         ret = do_sendto(arg1, arg2, arg3, arg4, 0, 0);
4576         break;
4577 #endif
4578 #ifdef TARGET_NR_sendmsg
4579     case TARGET_NR_sendmsg:
4580         ret = do_sendrecvmsg(arg1, arg2, arg3, 1);
4581         break;
4582 #endif
4583 #ifdef TARGET_NR_sendto
4584     case TARGET_NR_sendto:
4585         ret = do_sendto(arg1, arg2, arg3, arg4, arg5, arg6);
4586         break;
4587 #endif
4588 #ifdef TARGET_NR_shutdown
4589     case TARGET_NR_shutdown:
4590         ret = get_errno(shutdown(arg1, arg2));
4591         break;
4592 #endif
4593 #ifdef TARGET_NR_socket
4594     case TARGET_NR_socket:
4595         ret = do_socket(arg1, arg2, arg3);
4596         break;
4597 #endif
4598 #ifdef TARGET_NR_socketpair
4599     case TARGET_NR_socketpair:
4600         ret = do_socketpair(arg1, arg2, arg3, arg4);
4601         break;
4602 #endif
4603 #ifdef TARGET_NR_setsockopt
4604     case TARGET_NR_setsockopt:
4605         ret = do_setsockopt(arg1, arg2, arg3, arg4, (socklen_t) arg5);
4606         break;
4607 #endif
4608
4609     case TARGET_NR_syslog:
4610         if (!(p = lock_user_string(arg2)))
4611             goto efault;
4612         ret = get_errno(sys_syslog((int)arg1, p, (int)arg3));
4613         unlock_user(p, arg2, 0);
4614         break;
4615
4616     case TARGET_NR_setitimer:
4617         {
4618             struct itimerval value, ovalue, *pvalue;
4619
4620             if (arg2) {
4621                 pvalue = &value;
4622                 if (copy_from_user_timeval(&pvalue->it_interval, arg2)
4623                     || copy_from_user_timeval(&pvalue->it_value,
4624                                               arg2 + sizeof(struct target_timeval)))
4625                     goto efault;
4626             } else {
4627                 pvalue = NULL;
4628             }
4629             ret = get_errno(setitimer(arg1, pvalue, &ovalue));
4630             if (!is_error(ret) && arg3) {
4631                 if (copy_to_user_timeval(arg3,
4632                                          &ovalue.it_interval)
4633                     || copy_to_user_timeval(arg3 + sizeof(struct target_timeval),
4634                                             &ovalue.it_value))
4635                     goto efault;
4636             }
4637         }
4638         break;
4639     case TARGET_NR_getitimer:
4640         {
4641             struct itimerval value;
4642
4643             ret = get_errno(getitimer(arg1, &value));
4644             if (!is_error(ret) && arg2) {
4645                 if (copy_to_user_timeval(arg2,
4646                                          &value.it_interval)
4647                     || copy_to_user_timeval(arg2 + sizeof(struct target_timeval),
4648                                             &value.it_value))
4649                     goto efault;
4650             }
4651         }
4652         break;
4653     case TARGET_NR_stat:
4654         if (!(p = lock_user_string(arg1)))
4655             goto efault;
4656         ret = get_errno(stat(path(p), &st));
4657         unlock_user(p, arg1, 0);
4658         goto do_stat;
4659     case TARGET_NR_lstat:
4660         if (!(p = lock_user_string(arg1)))
4661             goto efault;
4662         ret = get_errno(lstat(path(p), &st));
4663         unlock_user(p, arg1, 0);
4664         goto do_stat;
4665     case TARGET_NR_fstat:
4666         {
4667             ret = get_errno(fstat(arg1, &st));
4668         do_stat:
4669             if (!is_error(ret)) {
4670                 struct target_stat *target_st;
4671
4672                 if (!lock_user_struct(VERIFY_WRITE, target_st, arg2, 0))
4673                     goto efault;
4674                 __put_user(st.st_dev, &target_st->st_dev);
4675                 __put_user(st.st_ino, &target_st->st_ino);
4676                 __put_user(st.st_mode, &target_st->st_mode);
4677                 __put_user(st.st_uid, &target_st->st_uid);
4678                 __put_user(st.st_gid, &target_st->st_gid);
4679                 __put_user(st.st_nlink, &target_st->st_nlink);
4680                 __put_user(st.st_rdev, &target_st->st_rdev);
4681                 __put_user(st.st_size, &target_st->st_size);
4682                 __put_user(st.st_blksize, &target_st->st_blksize);
4683                 __put_user(st.st_blocks, &target_st->st_blocks);
4684                 __put_user(st.st_atime, &target_st->target_st_atime);
4685                 __put_user(st.st_mtime, &target_st->target_st_mtime);
4686                 __put_user(st.st_ctime, &target_st->target_st_ctime);
4687                 unlock_user_struct(target_st, arg2, 1);
4688             }
4689         }
4690         break;
4691 #ifdef TARGET_NR_olduname
4692     case TARGET_NR_olduname:
4693         goto unimplemented;
4694 #endif
4695 #ifdef TARGET_NR_iopl
4696     case TARGET_NR_iopl:
4697         goto unimplemented;
4698 #endif
4699     case TARGET_NR_vhangup:
4700         ret = get_errno(vhangup());
4701         break;
4702 #ifdef TARGET_NR_idle
4703     case TARGET_NR_idle:
4704         goto unimplemented;
4705 #endif
4706 #ifdef TARGET_NR_syscall
4707     case TARGET_NR_syscall:
4708         ret = do_syscall(cpu_env,arg1 & 0xffff,arg2,arg3,arg4,arg5,arg6,0);
4709         break;
4710 #endif
4711     case TARGET_NR_wait4:
4712         {
4713             int status;
4714             abi_long status_ptr = arg2;
4715             struct rusage rusage, *rusage_ptr;
4716             abi_ulong target_rusage = arg4;
4717             if (target_rusage)
4718                 rusage_ptr = &rusage;
4719             else
4720                 rusage_ptr = NULL;
4721             ret = get_errno(wait4(arg1, &status, arg3, rusage_ptr));
4722             if (!is_error(ret)) {
4723                 if (status_ptr) {
4724                     if (put_user_s32(status, status_ptr))
4725                         goto efault;
4726                 }
4727                 if (target_rusage)
4728                     host_to_target_rusage(target_rusage, &rusage);
4729             }
4730         }
4731         break;
4732 #ifdef TARGET_NR_swapoff
4733     case TARGET_NR_swapoff:
4734         if (!(p = lock_user_string(arg1)))
4735             goto efault;
4736         ret = get_errno(swapoff(p));
4737         unlock_user(p, arg1, 0);
4738         break;
4739 #endif
4740     case TARGET_NR_sysinfo:
4741         {
4742             struct target_sysinfo *target_value;
4743             struct sysinfo value;
4744             ret = get_errno(sysinfo(&value));
4745             if (!is_error(ret) && arg1)
4746             {
4747                 if (!lock_user_struct(VERIFY_WRITE, target_value, arg1, 0))
4748                     goto efault;
4749                 __put_user(value.uptime, &target_value->uptime);
4750                 __put_user(value.loads[0], &target_value->loads[0]);
4751                 __put_user(value.loads[1], &target_value->loads[1]);
4752                 __put_user(value.loads[2], &target_value->loads[2]);
4753                 __put_user(value.totalram, &target_value->totalram);
4754                 __put_user(value.freeram, &target_value->freeram);
4755                 __put_user(value.sharedram, &target_value->sharedram);
4756                 __put_user(value.bufferram, &target_value->bufferram);
4757                 __put_user(value.totalswap, &target_value->totalswap);
4758                 __put_user(value.freeswap, &target_value->freeswap);
4759                 __put_user(value.procs, &target_value->procs);
4760                 __put_user(value.totalhigh, &target_value->totalhigh);
4761                 __put_user(value.freehigh, &target_value->freehigh);
4762                 __put_user(value.mem_unit, &target_value->mem_unit);
4763                 unlock_user_struct(target_value, arg1, 1);
4764             }
4765         }
4766         break;
4767 #ifdef TARGET_NR_ipc
4768     case TARGET_NR_ipc:
4769         ret = do_ipc(arg1, arg2, arg3, arg4, arg5, arg6);
4770         break;
4771 #endif
4772     case TARGET_NR_fsync:
4773         ret = get_errno(fsync(arg1));
4774         break;
4775     case TARGET_NR_clone:
4776 #if defined(TARGET_SH4)
4777         ret = get_errno(do_fork(cpu_env, arg1, arg2, arg3, arg5, arg4));
4778 #else
4779         ret = get_errno(do_fork(cpu_env, arg1, arg2, arg3, arg4, arg5));
4780 #endif
4781         break;
4782 #ifdef __NR_exit_group
4783         /* new thread calls */
4784     case TARGET_NR_exit_group:
4785         gdb_exit(cpu_env, arg1);
4786         ret = get_errno(exit_group(arg1));
4787         break;
4788 #endif
4789     case TARGET_NR_setdomainname:
4790         if (!(p = lock_user_string(arg1)))
4791             goto efault;
4792         ret = get_errno(setdomainname(p, arg2));
4793         unlock_user(p, arg1, 0);
4794         break;
4795     case TARGET_NR_uname:
4796         /* no need to transcode because we use the linux syscall */
4797         {
4798             struct new_utsname * buf;
4799
4800             if (!lock_user_struct(VERIFY_WRITE, buf, arg1, 0))
4801                 goto efault;
4802             ret = get_errno(sys_uname(buf));
4803             if (!is_error(ret)) {
4804                 /* Overrite the native machine name with whatever is being
4805                    emulated. */
4806                 strcpy (buf->machine, UNAME_MACHINE);
4807                 /* Allow the user to override the reported release.  */
4808                 if (qemu_uname_release && *qemu_uname_release)
4809                   strcpy (buf->release, qemu_uname_release);
4810             }
4811             unlock_user_struct(buf, arg1, 1);
4812         }
4813         break;
4814 #ifdef TARGET_I386
4815     case TARGET_NR_modify_ldt:
4816         ret = do_modify_ldt(cpu_env, arg1, arg2, arg3);
4817         break;
4818 #if !defined(TARGET_X86_64)
4819     case TARGET_NR_vm86old:
4820         goto unimplemented;
4821     case TARGET_NR_vm86:
4822         ret = do_vm86(cpu_env, arg1, arg2);
4823         break;
4824 #endif
4825 #endif
4826     case TARGET_NR_adjtimex:
4827         goto unimplemented;
4828 #ifdef TARGET_NR_create_module
4829     case TARGET_NR_create_module:
4830 #endif
4831     case TARGET_NR_init_module:
4832     case TARGET_NR_delete_module:
4833 #ifdef TARGET_NR_get_kernel_syms
4834     case TARGET_NR_get_kernel_syms:
4835 #endif
4836         goto unimplemented;
4837     case TARGET_NR_quotactl:
4838         goto unimplemented;
4839     case TARGET_NR_getpgid:
4840         ret = get_errno(getpgid(arg1));
4841         break;
4842     case TARGET_NR_fchdir:
4843         ret = get_errno(fchdir(arg1));
4844         break;
4845 #ifdef TARGET_NR_bdflush /* not on x86_64 */
4846     case TARGET_NR_bdflush:
4847         goto unimplemented;
4848 #endif
4849 #ifdef TARGET_NR_sysfs
4850     case TARGET_NR_sysfs:
4851         goto unimplemented;
4852 #endif
4853     case TARGET_NR_personality:
4854         ret = get_errno(personality(arg1));
4855         break;
4856 #ifdef TARGET_NR_afs_syscall
4857     case TARGET_NR_afs_syscall:
4858         goto unimplemented;
4859 #endif
4860 #ifdef TARGET_NR__llseek /* Not on alpha */
4861     case TARGET_NR__llseek:
4862         {
4863 #if defined (__x86_64__)
4864             ret = get_errno(lseek(arg1, ((uint64_t )arg2 << 32) | arg3, arg5));
4865             if (put_user_s64(ret, arg4))
4866                 goto efault;
4867 #else
4868             int64_t res;
4869             ret = get_errno(_llseek(arg1, arg2, arg3, &res, arg5));
4870             if (put_user_s64(res, arg4))
4871                 goto efault;
4872 #endif
4873         }
4874         break;
4875 #endif
4876     case TARGET_NR_getdents:
4877 #if TARGET_ABI_BITS != 32
4878         goto unimplemented;
4879 #elif TARGET_ABI_BITS == 32 && HOST_LONG_BITS == 64
4880         {
4881             struct target_dirent *target_dirp;
4882             struct dirent *dirp;
4883             abi_long count = arg3;
4884
4885             dirp = malloc(count);
4886             if (!dirp) {
4887                 ret = -TARGET_ENOMEM;
4888                 goto fail;
4889             }
4890
4891             ret = get_errno(sys_getdents(arg1, dirp, count));
4892             if (!is_error(ret)) {
4893                 struct dirent *de;
4894                 struct target_dirent *tde;
4895                 int len = ret;
4896                 int reclen, treclen;
4897                 int count1, tnamelen;
4898
4899                 count1 = 0;
4900                 de = dirp;
4901                 if (!(target_dirp = lock_user(VERIFY_WRITE, arg2, count, 0)))
4902                     goto efault;
4903                 tde = target_dirp;
4904                 while (len > 0) {
4905                     reclen = de->d_reclen;
4906                     treclen = reclen - (2 * (sizeof(long) - sizeof(abi_long)));
4907                     tde->d_reclen = tswap16(treclen);
4908                     tde->d_ino = tswapl(de->d_ino);
4909                     tde->d_off = tswapl(de->d_off);
4910                     tnamelen = treclen - (2 * sizeof(abi_long) + 2);
4911                     if (tnamelen > 256)
4912                         tnamelen = 256;
4913                     /* XXX: may not be correct */
4914                     strncpy(tde->d_name, de->d_name, tnamelen);
4915                     de = (struct dirent *)((char *)de + reclen);
4916                     len -= reclen;
4917                     tde = (struct target_dirent *)((char *)tde + treclen);
4918                     count1 += treclen;
4919                 }
4920                 ret = count1;
4921                 unlock_user(target_dirp, arg2, ret);
4922             }
4923             free(dirp);
4924         }
4925 #else
4926         {
4927             struct dirent *dirp;
4928             abi_long count = arg3;
4929
4930             if (!(dirp = lock_user(VERIFY_WRITE, arg2, count, 0)))
4931                 goto efault;
4932             ret = get_errno(sys_getdents(arg1, dirp, count));
4933             if (!is_error(ret)) {
4934                 struct dirent *de;
4935                 int len = ret;
4936                 int reclen;
4937                 de = dirp;
4938                 while (len > 0) {
4939                     reclen = de->d_reclen;
4940                     if (reclen > len)
4941                         break;
4942                     de->d_reclen = tswap16(reclen);
4943                     tswapls(&de->d_ino);
4944                     tswapls(&de->d_off);
4945                     de = (struct dirent *)((char *)de + reclen);
4946                     len -= reclen;
4947                 }
4948             }
4949             unlock_user(dirp, arg2, ret);
4950         }
4951 #endif
4952         break;
4953 #if defined(TARGET_NR_getdents64) && defined(__NR_getdents64)
4954     case TARGET_NR_getdents64:
4955         {
4956             struct dirent64 *dirp;
4957             abi_long count = arg3;
4958             if (!(dirp = lock_user(VERIFY_WRITE, arg2, count, 0)))
4959                 goto efault;
4960             ret = get_errno(sys_getdents64(arg1, dirp, count));
4961             if (!is_error(ret)) {
4962                 struct dirent64 *de;
4963                 int len = ret;
4964                 int reclen;
4965                 de = dirp;
4966                 while (len > 0) {
4967                     reclen = de->d_reclen;
4968                     if (reclen > len)
4969                         break;
4970                     de->d_reclen = tswap16(reclen);
4971                     tswap64s((uint64_t *)&de->d_ino);
4972                     tswap64s((uint64_t *)&de->d_off);
4973                     de = (struct dirent64 *)((char *)de + reclen);
4974                     len -= reclen;
4975                 }
4976             }
4977             unlock_user(dirp, arg2, ret);
4978         }
4979         break;
4980 #endif /* TARGET_NR_getdents64 */
4981 #ifdef TARGET_NR__newselect
4982     case TARGET_NR__newselect:
4983         ret = do_select(arg1, arg2, arg3, arg4, arg5);
4984         break;
4985 #endif
4986 #ifdef TARGET_NR_poll
4987     case TARGET_NR_poll:
4988         {
4989             struct target_pollfd *target_pfd;
4990             unsigned int nfds = arg2;
4991             int timeout = arg3;
4992             struct pollfd *pfd;
4993             unsigned int i;
4994
4995             target_pfd = lock_user(VERIFY_WRITE, arg1, sizeof(struct target_pollfd) * nfds, 1);
4996             if (!target_pfd)
4997                 goto efault;
4998             pfd = alloca(sizeof(struct pollfd) * nfds);
4999             for(i = 0; i < nfds; i++) {
5000                 pfd[i].fd = tswap32(target_pfd[i].fd);
5001                 pfd[i].events = tswap16(target_pfd[i].events);
5002             }
5003             ret = get_errno(poll(pfd, nfds, timeout));
5004             if (!is_error(ret)) {
5005                 for(i = 0; i < nfds; i++) {
5006                     target_pfd[i].revents = tswap16(pfd[i].revents);
5007                 }
5008                 ret += nfds * (sizeof(struct target_pollfd)
5009                                - sizeof(struct pollfd));
5010             }
5011             unlock_user(target_pfd, arg1, ret);
5012         }
5013         break;
5014 #endif
5015     case TARGET_NR_flock:
5016         /* NOTE: the flock constant seems to be the same for every
5017            Linux platform */
5018         ret = get_errno(flock(arg1, arg2));
5019         break;
5020     case TARGET_NR_readv:
5021         {
5022             int count = arg3;
5023             struct iovec *vec;
5024
5025             vec = alloca(count * sizeof(struct iovec));
5026             if (lock_iovec(VERIFY_WRITE, vec, arg2, count, 0) < 0)
5027                 goto efault;
5028             ret = get_errno(readv(arg1, vec, count));
5029             unlock_iovec(vec, arg2, count, 1);
5030         }
5031         break;
5032     case TARGET_NR_writev:
5033         {
5034             int count = arg3;
5035             struct iovec *vec;
5036
5037             vec = alloca(count * sizeof(struct iovec));
5038             if (lock_iovec(VERIFY_READ, vec, arg2, count, 1) < 0)
5039                 goto efault;
5040             ret = get_errno(writev(arg1, vec, count));
5041             unlock_iovec(vec, arg2, count, 0);
5042         }
5043         break;
5044     case TARGET_NR_getsid:
5045         ret = get_errno(getsid(arg1));
5046         break;
5047 #if defined(TARGET_NR_fdatasync) /* Not on alpha (osf_datasync ?) */
5048     case TARGET_NR_fdatasync:
5049         ret = get_errno(fdatasync(arg1));
5050         break;
5051 #endif
5052     case TARGET_NR__sysctl:
5053         /* We don't implement this, but ENOTDIR is always a safe
5054            return value. */
5055         ret = -TARGET_ENOTDIR;
5056         break;
5057     case TARGET_NR_sched_setparam:
5058         {
5059             struct sched_param *target_schp;
5060             struct sched_param schp;
5061
5062             if (!lock_user_struct(VERIFY_READ, target_schp, arg2, 1))
5063                 goto efault;
5064             schp.sched_priority = tswap32(target_schp->sched_priority);
5065             unlock_user_struct(target_schp, arg2, 0);
5066             ret = get_errno(sched_setparam(arg1, &schp));
5067         }
5068         break;
5069     case TARGET_NR_sched_getparam:
5070         {
5071             struct sched_param *target_schp;
5072             struct sched_param schp;
5073             ret = get_errno(sched_getparam(arg1, &schp));
5074             if (!is_error(ret)) {
5075                 if (!lock_user_struct(VERIFY_WRITE, target_schp, arg2, 0))
5076                     goto efault;
5077                 target_schp->sched_priority = tswap32(schp.sched_priority);
5078                 unlock_user_struct(target_schp, arg2, 1);
5079             }
5080         }
5081         break;
5082     case TARGET_NR_sched_setscheduler:
5083         {
5084             struct sched_param *target_schp;
5085             struct sched_param schp;
5086             if (!lock_user_struct(VERIFY_READ, target_schp, arg3, 1))
5087                 goto efault;
5088             schp.sched_priority = tswap32(target_schp->sched_priority);
5089             unlock_user_struct(target_schp, arg3, 0);
5090             ret = get_errno(sched_setscheduler(arg1, arg2, &schp));
5091         }
5092         break;
5093     case TARGET_NR_sched_getscheduler:
5094         ret = get_errno(sched_getscheduler(arg1));
5095         break;
5096     case TARGET_NR_sched_yield:
5097         ret = get_errno(sched_yield());
5098         break;
5099     case TARGET_NR_sched_get_priority_max:
5100         ret = get_errno(sched_get_priority_max(arg1));
5101         break;
5102     case TARGET_NR_sched_get_priority_min:
5103         ret = get_errno(sched_get_priority_min(arg1));
5104         break;
5105     case TARGET_NR_sched_rr_get_interval:
5106         {
5107             struct timespec ts;
5108             ret = get_errno(sched_rr_get_interval(arg1, &ts));
5109             if (!is_error(ret)) {
5110                 host_to_target_timespec(arg2, &ts);
5111             }
5112         }
5113         break;
5114     case TARGET_NR_nanosleep:
5115         {
5116             struct timespec req, rem;
5117             target_to_host_timespec(&req, arg1);
5118             ret = get_errno(nanosleep(&req, &rem));
5119             if (is_error(ret) && arg2) {
5120                 host_to_target_timespec(arg2, &rem);
5121             }
5122         }
5123         break;
5124 #ifdef TARGET_NR_query_module
5125     case TARGET_NR_query_module:
5126         goto unimplemented;
5127 #endif
5128 #ifdef TARGET_NR_nfsservctl
5129     case TARGET_NR_nfsservctl:
5130         goto unimplemented;
5131 #endif
5132     case TARGET_NR_prctl:
5133         switch (arg1)
5134             {
5135             case PR_GET_PDEATHSIG:
5136                 {
5137                     int deathsig;
5138                     ret = get_errno(prctl(arg1, &deathsig, arg3, arg4, arg5));
5139                     if (!is_error(ret) && arg2
5140                         && put_user_ual(deathsig, arg2))
5141                         goto efault;
5142                 }
5143                 break;
5144             default:
5145                 ret = get_errno(prctl(arg1, arg2, arg3, arg4, arg5));
5146                 break;
5147             }
5148         break;
5149 #ifdef TARGET_NR_arch_prctl
5150     case TARGET_NR_arch_prctl:
5151 #if defined(TARGET_I386) && !defined(TARGET_ABI32)
5152         ret = do_arch_prctl(cpu_env, arg1, arg2);
5153         break;
5154 #else
5155         goto unimplemented;
5156 #endif
5157 #endif
5158 #ifdef TARGET_NR_pread
5159     case TARGET_NR_pread:
5160 #ifdef TARGET_ARM
5161         if (((CPUARMState *)cpu_env)->eabi)
5162             arg4 = arg5;
5163 #endif
5164         if (!(p = lock_user(VERIFY_WRITE, arg2, arg3, 0)))
5165             goto efault;
5166         ret = get_errno(pread(arg1, p, arg3, arg4));
5167         unlock_user(p, arg2, ret);
5168         break;
5169     case TARGET_NR_pwrite:
5170 #ifdef TARGET_ARM
5171         if (((CPUARMState *)cpu_env)->eabi)
5172             arg4 = arg5;
5173 #endif
5174         if (!(p = lock_user(VERIFY_READ, arg2, arg3, 1)))
5175             goto efault;
5176         ret = get_errno(pwrite(arg1, p, arg3, arg4));
5177         unlock_user(p, arg2, 0);
5178         break;
5179 #endif
5180 #ifdef TARGET_NR_pread64
5181     case TARGET_NR_pread64:
5182         if (!(p = lock_user(VERIFY_WRITE, arg2, arg3, 0)))
5183             goto efault;
5184         ret = get_errno(pread64(arg1, p, arg3, target_offset64(arg4, arg5)));
5185         unlock_user(p, arg2, ret);
5186         break;
5187     case TARGET_NR_pwrite64:
5188         if (!(p = lock_user(VERIFY_READ, arg2, arg3, 1)))
5189             goto efault;
5190         ret = get_errno(pwrite64(arg1, p, arg3, target_offset64(arg4, arg5)));
5191         unlock_user(p, arg2, 0);
5192         break;
5193 #endif
5194     case TARGET_NR_getcwd:
5195         if (!(p = lock_user(VERIFY_WRITE, arg1, arg2, 0)))
5196             goto efault;
5197         ret = get_errno(sys_getcwd1(p, arg2));
5198         unlock_user(p, arg1, ret);
5199         break;
5200     case TARGET_NR_capget:
5201         goto unimplemented;
5202     case TARGET_NR_capset:
5203         goto unimplemented;
5204     case TARGET_NR_sigaltstack:
5205 #if defined(TARGET_I386) || defined(TARGET_ARM) || defined(TARGET_MIPS) || \
5206     defined(TARGET_SPARC) || defined(TARGET_PPC) || defined(TARGET_ALPHA)
5207         ret = do_sigaltstack(arg1, arg2, get_sp_from_cpustate((CPUState *)cpu_env));
5208         break;
5209 #else
5210         goto unimplemented;
5211 #endif
5212     case TARGET_NR_sendfile:
5213         goto unimplemented;
5214 #ifdef TARGET_NR_getpmsg
5215     case TARGET_NR_getpmsg:
5216         goto unimplemented;
5217 #endif
5218 #ifdef TARGET_NR_putpmsg
5219     case TARGET_NR_putpmsg:
5220         goto unimplemented;
5221 #endif
5222 #ifdef TARGET_NR_vfork
5223     case TARGET_NR_vfork:
5224         ret = get_errno(do_fork(cpu_env, CLONE_VFORK | CLONE_VM | SIGCHLD,
5225                         0, 0, 0, 0));
5226         break;
5227 #endif
5228 #ifdef TARGET_NR_ugetrlimit
5229     case TARGET_NR_ugetrlimit:
5230     {
5231         struct rlimit rlim;
5232         ret = get_errno(getrlimit(arg1, &rlim));
5233         if (!is_error(ret)) {
5234             struct target_rlimit *target_rlim;
5235             if (!lock_user_struct(VERIFY_WRITE, target_rlim, arg2, 0))
5236                 goto efault;
5237             target_rlim->rlim_cur = tswapl(rlim.rlim_cur);
5238             target_rlim->rlim_max = tswapl(rlim.rlim_max);
5239             unlock_user_struct(target_rlim, arg2, 1);
5240         }
5241         break;
5242     }
5243 #endif
5244 #ifdef TARGET_NR_truncate64
5245     case TARGET_NR_truncate64:
5246         if (!(p = lock_user_string(arg1)))
5247             goto efault;
5248         ret = target_truncate64(cpu_env, p, arg2, arg3, arg4);
5249         unlock_user(p, arg1, 0);
5250         break;
5251 #endif
5252 #ifdef TARGET_NR_ftruncate64
5253     case TARGET_NR_ftruncate64:
5254         ret = target_ftruncate64(cpu_env, arg1, arg2, arg3, arg4);
5255         break;
5256 #endif
5257 #ifdef TARGET_NR_stat64
5258     case TARGET_NR_stat64:
5259         if (!(p = lock_user_string(arg1)))
5260             goto efault;
5261         ret = get_errno(stat(path(p), &st));
5262         unlock_user(p, arg1, 0);
5263         if (!is_error(ret))
5264             ret = host_to_target_stat64(cpu_env, arg2, &st);
5265         break;
5266 #endif
5267 #ifdef TARGET_NR_lstat64
5268     case TARGET_NR_lstat64:
5269         if (!(p = lock_user_string(arg1)))
5270             goto efault;
5271         ret = get_errno(lstat(path(p), &st));
5272         unlock_user(p, arg1, 0);
5273         if (!is_error(ret))
5274             ret = host_to_target_stat64(cpu_env, arg2, &st);
5275         break;
5276 #endif
5277 #ifdef TARGET_NR_fstat64
5278     case TARGET_NR_fstat64:
5279         ret = get_errno(fstat(arg1, &st));
5280         if (!is_error(ret))
5281             ret = host_to_target_stat64(cpu_env, arg2, &st);
5282         break;
5283 #endif
5284 #if defined(TARGET_NR_fstatat64) && defined(__NR_fstatat64)
5285     case TARGET_NR_fstatat64:
5286         if (!(p = lock_user_string(arg2)))
5287             goto efault;
5288         ret = get_errno(sys_fstatat64(arg1, path(p), &st, arg4));
5289         if (!is_error(ret))
5290             ret = host_to_target_stat64(cpu_env, arg3, &st);
5291         break;
5292 #endif
5293 #ifdef USE_UID16
5294     case TARGET_NR_lchown:
5295         if (!(p = lock_user_string(arg1)))
5296             goto efault;
5297         ret = get_errno(lchown(p, low2highuid(arg2), low2highgid(arg3)));
5298         unlock_user(p, arg1, 0);
5299         break;
5300     case TARGET_NR_getuid:
5301         ret = get_errno(high2lowuid(getuid()));
5302         break;
5303     case TARGET_NR_getgid:
5304         ret = get_errno(high2lowgid(getgid()));
5305         break;
5306     case TARGET_NR_geteuid:
5307         ret = get_errno(high2lowuid(geteuid()));
5308         break;
5309     case TARGET_NR_getegid:
5310         ret = get_errno(high2lowgid(getegid()));
5311         break;
5312     case TARGET_NR_setreuid:
5313         ret = get_errno(setreuid(low2highuid(arg1), low2highuid(arg2)));
5314         break;
5315     case TARGET_NR_setregid:
5316         ret = get_errno(setregid(low2highgid(arg1), low2highgid(arg2)));
5317         break;
5318     case TARGET_NR_getgroups:
5319         {
5320             int gidsetsize = arg1;
5321             uint16_t *target_grouplist;
5322             gid_t *grouplist;
5323             int i;
5324
5325             grouplist = alloca(gidsetsize * sizeof(gid_t));
5326             ret = get_errno(getgroups(gidsetsize, grouplist));
5327             if (gidsetsize == 0)
5328                 break;
5329             if (!is_error(ret)) {
5330                 target_grouplist = lock_user(VERIFY_WRITE, arg2, gidsetsize * 2, 0);
5331                 if (!target_grouplist)
5332                     goto efault;
5333                 for(i = 0;i < ret; i++)
5334                     target_grouplist[i] = tswap16(grouplist[i]);
5335                 unlock_user(target_grouplist, arg2, gidsetsize * 2);
5336             }
5337         }
5338         break;
5339     case TARGET_NR_setgroups:
5340         {
5341             int gidsetsize = arg1;
5342             uint16_t *target_grouplist;
5343             gid_t *grouplist;
5344             int i;
5345
5346             grouplist = alloca(gidsetsize * sizeof(gid_t));
5347             target_grouplist = lock_user(VERIFY_READ, arg2, gidsetsize * 2, 1);
5348             if (!target_grouplist) {
5349                 ret = -TARGET_EFAULT;
5350                 goto fail;
5351             }
5352             for(i = 0;i < gidsetsize; i++)
5353                 grouplist[i] = tswap16(target_grouplist[i]);
5354             unlock_user(target_grouplist, arg2, 0);
5355             ret = get_errno(setgroups(gidsetsize, grouplist));
5356         }
5357         break;
5358     case TARGET_NR_fchown:
5359         ret = get_errno(fchown(arg1, low2highuid(arg2), low2highgid(arg3)));
5360         break;
5361 #if defined(TARGET_NR_fchownat) && defined(__NR_fchownat)
5362     case TARGET_NR_fchownat:
5363         if (!(p = lock_user_string(arg2))) 
5364             goto efault;
5365         ret = get_errno(sys_fchownat(arg1, p, low2highuid(arg3), low2highgid(arg4), arg5));
5366         unlock_user(p, arg2, 0);
5367         break;
5368 #endif
5369 #ifdef TARGET_NR_setresuid
5370     case TARGET_NR_setresuid:
5371         ret = get_errno(setresuid(low2highuid(arg1),
5372                                   low2highuid(arg2),
5373                                   low2highuid(arg3)));
5374         break;
5375 #endif
5376 #ifdef TARGET_NR_getresuid
5377     case TARGET_NR_getresuid:
5378         {
5379             uid_t ruid, euid, suid;
5380             ret = get_errno(getresuid(&ruid, &euid, &suid));
5381             if (!is_error(ret)) {
5382                 if (put_user_u16(high2lowuid(ruid), arg1)
5383                     || put_user_u16(high2lowuid(euid), arg2)
5384                     || put_user_u16(high2lowuid(suid), arg3))
5385                     goto efault;
5386             }
5387         }
5388         break;
5389 #endif
5390 #ifdef TARGET_NR_getresgid
5391     case TARGET_NR_setresgid:
5392         ret = get_errno(setresgid(low2highgid(arg1),
5393                                   low2highgid(arg2),
5394                                   low2highgid(arg3)));
5395         break;
5396 #endif
5397 #ifdef TARGET_NR_getresgid
5398     case TARGET_NR_getresgid:
5399         {
5400             gid_t rgid, egid, sgid;
5401             ret = get_errno(getresgid(&rgid, &egid, &sgid));
5402             if (!is_error(ret)) {
5403                 if (put_user_u16(high2lowgid(rgid), arg1)
5404                     || put_user_u16(high2lowgid(egid), arg2)
5405                     || put_user_u16(high2lowgid(sgid), arg3))
5406                     goto efault;
5407             }
5408         }
5409         break;
5410 #endif
5411     case TARGET_NR_chown:
5412         if (!(p = lock_user_string(arg1)))
5413             goto efault;
5414         ret = get_errno(chown(p, low2highuid(arg2), low2highgid(arg3)));
5415         unlock_user(p, arg1, 0);
5416         break;
5417     case TARGET_NR_setuid:
5418         ret = get_errno(setuid(low2highuid(arg1)));
5419         break;
5420     case TARGET_NR_setgid:
5421         ret = get_errno(setgid(low2highgid(arg1)));
5422         break;
5423     case TARGET_NR_setfsuid:
5424         ret = get_errno(setfsuid(arg1));
5425         break;
5426     case TARGET_NR_setfsgid:
5427         ret = get_errno(setfsgid(arg1));
5428         break;
5429 #endif /* USE_UID16 */
5430
5431 #ifdef TARGET_NR_lchown32
5432     case TARGET_NR_lchown32:
5433         if (!(p = lock_user_string(arg1)))
5434             goto efault;
5435         ret = get_errno(lchown(p, arg2, arg3));
5436         unlock_user(p, arg1, 0);
5437         break;
5438 #endif
5439 #ifdef TARGET_NR_getuid32
5440     case TARGET_NR_getuid32:
5441         ret = get_errno(getuid());
5442         break;
5443 #endif
5444 #ifdef TARGET_NR_getgid32
5445     case TARGET_NR_getgid32:
5446         ret = get_errno(getgid());
5447         break;
5448 #endif
5449 #ifdef TARGET_NR_geteuid32
5450     case TARGET_NR_geteuid32:
5451         ret = get_errno(geteuid());
5452         break;
5453 #endif
5454 #ifdef TARGET_NR_getegid32
5455     case TARGET_NR_getegid32:
5456         ret = get_errno(getegid());
5457         break;
5458 #endif
5459 #ifdef TARGET_NR_setreuid32
5460     case TARGET_NR_setreuid32:
5461         ret = get_errno(setreuid(arg1, arg2));
5462         break;
5463 #endif
5464 #ifdef TARGET_NR_setregid32
5465     case TARGET_NR_setregid32:
5466         ret = get_errno(setregid(arg1, arg2));
5467         break;
5468 #endif
5469 #ifdef TARGET_NR_getgroups32
5470     case TARGET_NR_getgroups32:
5471         {
5472             int gidsetsize = arg1;
5473             uint32_t *target_grouplist;
5474             gid_t *grouplist;
5475             int i;
5476
5477             grouplist = alloca(gidsetsize * sizeof(gid_t));
5478             ret = get_errno(getgroups(gidsetsize, grouplist));
5479             if (gidsetsize == 0)
5480                 break;
5481             if (!is_error(ret)) {
5482                 target_grouplist = lock_user(VERIFY_WRITE, arg2, gidsetsize * 4, 0);
5483                 if (!target_grouplist) {
5484                     ret = -TARGET_EFAULT;
5485                     goto fail;
5486                 }
5487                 for(i = 0;i < ret; i++)
5488                     target_grouplist[i] = tswap32(grouplist[i]);
5489                 unlock_user(target_grouplist, arg2, gidsetsize * 4);
5490             }
5491         }
5492         break;
5493 #endif
5494 #ifdef TARGET_NR_setgroups32
5495     case TARGET_NR_setgroups32:
5496         {
5497             int gidsetsize = arg1;
5498             uint32_t *target_grouplist;
5499             gid_t *grouplist;
5500             int i;
5501
5502             grouplist = alloca(gidsetsize * sizeof(gid_t));
5503             target_grouplist = lock_user(VERIFY_READ, arg2, gidsetsize * 4, 1);
5504             if (!target_grouplist) {
5505                 ret = -TARGET_EFAULT;
5506                 goto fail;
5507             }
5508             for(i = 0;i < gidsetsize; i++)
5509                 grouplist[i] = tswap32(target_grouplist[i]);
5510             unlock_user(target_grouplist, arg2, 0);
5511             ret = get_errno(setgroups(gidsetsize, grouplist));
5512         }
5513         break;
5514 #endif
5515 #ifdef TARGET_NR_fchown32
5516     case TARGET_NR_fchown32:
5517         ret = get_errno(fchown(arg1, arg2, arg3));
5518         break;
5519 #endif
5520 #ifdef TARGET_NR_setresuid32
5521     case TARGET_NR_setresuid32:
5522         ret = get_errno(setresuid(arg1, arg2, arg3));
5523         break;
5524 #endif
5525 #ifdef TARGET_NR_getresuid32
5526     case TARGET_NR_getresuid32:
5527         {
5528             uid_t ruid, euid, suid;
5529             ret = get_errno(getresuid(&ruid, &euid, &suid));
5530             if (!is_error(ret)) {
5531                 if (put_user_u32(ruid, arg1)
5532                     || put_user_u32(euid, arg2)
5533                     || put_user_u32(suid, arg3))
5534                     goto efault;
5535             }
5536         }
5537         break;
5538 #endif
5539 #ifdef TARGET_NR_setresgid32
5540     case TARGET_NR_setresgid32:
5541         ret = get_errno(setresgid(arg1, arg2, arg3));
5542         break;
5543 #endif
5544 #ifdef TARGET_NR_getresgid32
5545     case TARGET_NR_getresgid32:
5546         {
5547             gid_t rgid, egid, sgid;
5548             ret = get_errno(getresgid(&rgid, &egid, &sgid));
5549             if (!is_error(ret)) {
5550                 if (put_user_u32(rgid, arg1)
5551                     || put_user_u32(egid, arg2)
5552                     || put_user_u32(sgid, arg3))
5553                     goto efault;
5554             }
5555         }
5556         break;
5557 #endif
5558 #ifdef TARGET_NR_chown32
5559     case TARGET_NR_chown32:
5560         if (!(p = lock_user_string(arg1)))
5561             goto efault;
5562         ret = get_errno(chown(p, arg2, arg3));
5563         unlock_user(p, arg1, 0);
5564         break;
5565 #endif
5566 #ifdef TARGET_NR_setuid32
5567     case TARGET_NR_setuid32:
5568         ret = get_errno(setuid(arg1));
5569         break;
5570 #endif
5571 #ifdef TARGET_NR_setgid32
5572     case TARGET_NR_setgid32:
5573         ret = get_errno(setgid(arg1));
5574         break;
5575 #endif
5576 #ifdef TARGET_NR_setfsuid32
5577     case TARGET_NR_setfsuid32:
5578         ret = get_errno(setfsuid(arg1));
5579         break;
5580 #endif
5581 #ifdef TARGET_NR_setfsgid32
5582     case TARGET_NR_setfsgid32:
5583         ret = get_errno(setfsgid(arg1));
5584         break;
5585 #endif
5586
5587     case TARGET_NR_pivot_root:
5588         goto unimplemented;
5589 #ifdef TARGET_NR_mincore
5590     case TARGET_NR_mincore:
5591         {
5592             void *a;
5593             ret = -TARGET_EFAULT;
5594             if (!(a = lock_user(VERIFY_READ, arg1,arg2, 0)))
5595                 goto efault;
5596             if (!(p = lock_user_string(arg3)))
5597                 goto mincore_fail;
5598             ret = get_errno(mincore(a, arg2, p));
5599             unlock_user(p, arg3, ret);
5600             mincore_fail:
5601             unlock_user(a, arg1, 0);
5602         }
5603         break;
5604 #endif
5605 #ifdef TARGET_NR_arm_fadvise64_64
5606     case TARGET_NR_arm_fadvise64_64:
5607         {
5608                 /*
5609                  * arm_fadvise64_64 looks like fadvise64_64 but
5610                  * with different argument order
5611                  */
5612                 abi_long temp;
5613                 temp = arg3;
5614                 arg3 = arg4;
5615                 arg4 = temp;
5616         }
5617 #endif
5618 #if defined(TARGET_NR_fadvise64_64) || defined(TARGET_NR_arm_fadvise64_64)
5619 #ifdef TARGET_NR_fadvise64_64
5620     case TARGET_NR_fadvise64_64:
5621 #endif
5622         /* This is a hint, so ignoring and returning success is ok.  */
5623         ret = get_errno(0);
5624         break;
5625 #endif
5626 #ifdef TARGET_NR_madvise
5627     case TARGET_NR_madvise:
5628         /* A straight passthrough may not be safe because qemu sometimes
5629            turns private flie-backed mappings into anonymous mappings.
5630            This will break MADV_DONTNEED.
5631            This is a hint, so ignoring and returning success is ok.  */
5632         ret = get_errno(0);
5633         break;
5634 #endif
5635 #if TARGET_ABI_BITS == 32
5636     case TARGET_NR_fcntl64:
5637     {
5638         int cmd;
5639         struct flock64 fl;
5640         struct target_flock64 *target_fl;
5641 #ifdef TARGET_ARM
5642         struct target_eabi_flock64 *target_efl;
5643 #endif
5644
5645         switch(arg2){
5646         case TARGET_F_GETLK64:
5647             cmd = F_GETLK64;
5648             break;
5649         case TARGET_F_SETLK64:
5650             cmd = F_SETLK64;
5651             break;
5652         case TARGET_F_SETLKW64:
5653             cmd = F_SETLK64;
5654             break;
5655         default:
5656             cmd = arg2;
5657             break;
5658         }
5659
5660         switch(arg2) {
5661         case TARGET_F_GETLK64:
5662 #ifdef TARGET_ARM
5663             if (((CPUARMState *)cpu_env)->eabi) {
5664                 if (!lock_user_struct(VERIFY_READ, target_efl, arg3, 1)) 
5665                     goto efault;
5666                 fl.l_type = tswap16(target_efl->l_type);
5667                 fl.l_whence = tswap16(target_efl->l_whence);
5668                 fl.l_start = tswap64(target_efl->l_start);
5669                 fl.l_len = tswap64(target_efl->l_len);
5670                 fl.l_pid = tswapl(target_efl->l_pid);
5671                 unlock_user_struct(target_efl, arg3, 0);
5672             } else
5673 #endif
5674             {
5675                 if (!lock_user_struct(VERIFY_READ, target_fl, arg3, 1)) 
5676                     goto efault;
5677                 fl.l_type = tswap16(target_fl->l_type);
5678                 fl.l_whence = tswap16(target_fl->l_whence);
5679                 fl.l_start = tswap64(target_fl->l_start);
5680                 fl.l_len = tswap64(target_fl->l_len);
5681                 fl.l_pid = tswapl(target_fl->l_pid);
5682                 unlock_user_struct(target_fl, arg3, 0);
5683             }
5684             ret = get_errno(fcntl(arg1, cmd, &fl));
5685             if (ret == 0) {
5686 #ifdef TARGET_ARM
5687                 if (((CPUARMState *)cpu_env)->eabi) {
5688                     if (!lock_user_struct(VERIFY_WRITE, target_efl, arg3, 0)) 
5689                         goto efault;
5690                     target_efl->l_type = tswap16(fl.l_type);
5691                     target_efl->l_whence = tswap16(fl.l_whence);
5692                     target_efl->l_start = tswap64(fl.l_start);
5693                     target_efl->l_len = tswap64(fl.l_len);
5694                     target_efl->l_pid = tswapl(fl.l_pid);
5695                     unlock_user_struct(target_efl, arg3, 1);
5696                 } else
5697 #endif
5698                 {
5699                     if (!lock_user_struct(VERIFY_WRITE, target_fl, arg3, 0)) 
5700                         goto efault;
5701                     target_fl->l_type = tswap16(fl.l_type);
5702                     target_fl->l_whence = tswap16(fl.l_whence);
5703                     target_fl->l_start = tswap64(fl.l_start);
5704                     target_fl->l_len = tswap64(fl.l_len);
5705                     target_fl->l_pid = tswapl(fl.l_pid);
5706                     unlock_user_struct(target_fl, arg3, 1);
5707                 }
5708             }
5709             break;
5710
5711         case TARGET_F_SETLK64:
5712         case TARGET_F_SETLKW64:
5713 #ifdef TARGET_ARM
5714             if (((CPUARMState *)cpu_env)->eabi) {
5715                 if (!lock_user_struct(VERIFY_READ, target_efl, arg3, 1)) 
5716                     goto efault;
5717                 fl.l_type = tswap16(target_efl->l_type);
5718                 fl.l_whence = tswap16(target_efl->l_whence);
5719                 fl.l_start = tswap64(target_efl->l_start);
5720                 fl.l_len = tswap64(target_efl->l_len);
5721                 fl.l_pid = tswapl(target_efl->l_pid);
5722                 unlock_user_struct(target_efl, arg3, 0);
5723             } else
5724 #endif
5725             {
5726                 if (!lock_user_struct(VERIFY_READ, target_fl, arg3, 1)) 
5727                     goto efault;
5728                 fl.l_type = tswap16(target_fl->l_type);
5729                 fl.l_whence = tswap16(target_fl->l_whence);
5730                 fl.l_start = tswap64(target_fl->l_start);
5731                 fl.l_len = tswap64(target_fl->l_len);
5732                 fl.l_pid = tswapl(target_fl->l_pid);
5733                 unlock_user_struct(target_fl, arg3, 0);
5734             }
5735             ret = get_errno(fcntl(arg1, cmd, &fl));
5736             break;
5737         default:
5738             ret = do_fcntl(arg1, cmd, arg3);
5739             break;
5740         }
5741         break;
5742     }
5743 #endif
5744 #ifdef TARGET_NR_cacheflush
5745     case TARGET_NR_cacheflush:
5746         /* self-modifying code is handled automatically, so nothing needed */
5747         ret = 0;
5748         break;
5749 #endif
5750 #ifdef TARGET_NR_security
5751     case TARGET_NR_security:
5752         goto unimplemented;
5753 #endif
5754 #ifdef TARGET_NR_getpagesize
5755     case TARGET_NR_getpagesize:
5756         ret = TARGET_PAGE_SIZE;
5757         break;
5758 #endif
5759     case TARGET_NR_gettid:
5760         ret = get_errno(gettid());
5761         break;
5762 #ifdef TARGET_NR_readahead
5763     case TARGET_NR_readahead:
5764         goto unimplemented;
5765 #endif
5766 #ifdef TARGET_NR_setxattr
5767     case TARGET_NR_setxattr:
5768     case TARGET_NR_lsetxattr:
5769     case TARGET_NR_fsetxattr:
5770     case TARGET_NR_getxattr:
5771     case TARGET_NR_lgetxattr:
5772     case TARGET_NR_fgetxattr:
5773     case TARGET_NR_listxattr:
5774     case TARGET_NR_llistxattr:
5775     case TARGET_NR_flistxattr:
5776     case TARGET_NR_removexattr:
5777     case TARGET_NR_lremovexattr:
5778     case TARGET_NR_fremovexattr:
5779         goto unimplemented_nowarn;
5780 #endif
5781 #ifdef TARGET_NR_set_thread_area
5782     case TARGET_NR_set_thread_area:
5783 #if defined(TARGET_MIPS)
5784       ((CPUMIPSState *) cpu_env)->tls_value = arg1;
5785       ret = 0;
5786       break;
5787 #elif defined(TARGET_I386) && defined(TARGET_ABI32)
5788       ret = do_set_thread_area(cpu_env, arg1);
5789       break;
5790 #else
5791       goto unimplemented_nowarn;
5792 #endif
5793 #endif
5794 #ifdef TARGET_NR_get_thread_area
5795     case TARGET_NR_get_thread_area:
5796 #if defined(TARGET_I386) && defined(TARGET_ABI32)
5797         ret = do_get_thread_area(cpu_env, arg1);
5798 #else
5799         goto unimplemented_nowarn;
5800 #endif
5801 #endif
5802 #ifdef TARGET_NR_getdomainname
5803     case TARGET_NR_getdomainname:
5804         goto unimplemented_nowarn;
5805 #endif
5806
5807 #ifdef TARGET_NR_clock_gettime
5808     case TARGET_NR_clock_gettime:
5809     {
5810         struct timespec ts;
5811         ret = get_errno(clock_gettime(arg1, &ts));
5812         if (!is_error(ret)) {
5813             host_to_target_timespec(arg2, &ts);
5814         }
5815         break;
5816     }
5817 #endif
5818 #ifdef TARGET_NR_clock_getres
5819     case TARGET_NR_clock_getres:
5820     {
5821         struct timespec ts;
5822         ret = get_errno(clock_getres(arg1, &ts));
5823         if (!is_error(ret)) {
5824             host_to_target_timespec(arg2, &ts);
5825         }
5826         break;
5827     }
5828 #endif
5829 #ifdef TARGET_NR_clock_nanosleep
5830     case TARGET_NR_clock_nanosleep:
5831     {
5832         struct timespec ts;
5833         target_to_host_timespec(&ts, arg3);
5834         ret = get_errno(clock_nanosleep(arg1, arg2, &ts, arg4 ? &ts : NULL));
5835         if (arg4)
5836             host_to_target_timespec(arg4, &ts);
5837         break;
5838     }
5839 #endif
5840
5841 #if defined(TARGET_NR_set_tid_address) && defined(__NR_set_tid_address)
5842     case TARGET_NR_set_tid_address:
5843         ret = get_errno(set_tid_address((int *)g2h(arg1)));
5844         break;
5845 #endif
5846
5847 #if defined(TARGET_NR_tkill) && defined(__NR_tkill)
5848     case TARGET_NR_tkill:
5849         ret = get_errno(sys_tkill((int)arg1, target_to_host_signal(arg2)));
5850         break;
5851 #endif
5852
5853 #if defined(TARGET_NR_tgkill) && defined(__NR_tgkill)
5854     case TARGET_NR_tgkill:
5855         ret = get_errno(sys_tgkill((int)arg1, (int)arg2,
5856                         target_to_host_signal(arg3)));
5857         break;
5858 #endif
5859
5860 #ifdef TARGET_NR_set_robust_list
5861     case TARGET_NR_set_robust_list:
5862         goto unimplemented_nowarn;
5863 #endif
5864
5865 #if defined(TARGET_NR_utimensat) && defined(__NR_utimensat)
5866     case TARGET_NR_utimensat:
5867         {
5868             struct timespec ts[2];
5869             target_to_host_timespec(ts, arg3);
5870             target_to_host_timespec(ts+1, arg3+sizeof(struct target_timespec));
5871             if (!arg2)
5872                 ret = get_errno(sys_utimensat(arg1, NULL, ts, arg4));
5873             else {
5874                 if (!(p = lock_user_string(arg2))) {
5875                     ret = -TARGET_EFAULT;
5876                     goto fail;
5877                 }
5878                 ret = get_errno(sys_utimensat(arg1, path(p), ts, arg4));
5879                 unlock_user(p, arg2, 0);
5880             }
5881         }
5882         break;
5883 #endif
5884 #if defined(USE_NPTL)
5885     case TARGET_NR_futex:
5886         ret = do_futex(arg1, arg2, arg3, arg4, arg5, arg6);
5887         break;
5888 #endif
5889 #ifdef TARGET_NR_inotify_init
5890     case TARGET_NR_inotify_init:
5891         ret = get_errno(sys_inotify_init());
5892         break;
5893 #endif
5894 #ifdef TARGET_NR_inotify_add_watch
5895     case TARGET_NR_inotify_add_watch:
5896         p = lock_user_string(arg2);
5897         ret = get_errno(sys_inotify_add_watch(arg1, path(p), arg3));
5898         unlock_user(p, arg2, 0);
5899         break;
5900 #endif
5901 #ifdef TARGET_NR_inotify_rm_watch
5902     case TARGET_NR_inotify_rm_watch:
5903         ret = get_errno(sys_inotify_rm_watch(arg1, arg2));
5904         break;
5905 #endif
5906
5907     default:
5908     unimplemented:
5909         gemu_log("qemu: Unsupported syscall: %d\n", num);
5910 #if defined(TARGET_NR_setxattr) || defined(TARGET_NR_get_thread_area) || defined(TARGET_NR_getdomainname) || defined(TARGET_NR_set_robust_list)
5911     unimplemented_nowarn:
5912 #endif
5913         ret = -TARGET_ENOSYS;
5914         break;
5915     }
5916 fail:
5917 #ifdef DEBUG
5918     gemu_log(" = %ld\n", ret);
5919 #endif
5920     if(do_strace)
5921         print_syscall_ret(num, ret);
5922     return ret;
5923 efault:
5924     ret = -TARGET_EFAULT;
5925     goto fail;
5926 }