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