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