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