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