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