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