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