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