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