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