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