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