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