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