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