first vm86 support
[qemu] / linux-user / syscall.c
1 /*
2  *  Linux syscalls
3  * 
4  *  Copyright (c) 2003 Fabrice Bellard
5  *
6  *  This program is free software; you can redistribute it and/or modify
7  *  it under the terms of the GNU General Public License as published by
8  *  the Free Software Foundation; either version 2 of the License, or
9  *  (at your option) any later version.
10  *
11  *  This program is distributed in the hope that it will be useful,
12  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
13  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14  *  GNU General Public License for more details.
15  *
16  *  You should have received a copy of the GNU General Public License
17  *  along with this program; if not, write to the Free Software
18  *  Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
19  */
20 #include <stdlib.h>
21 #include <stdio.h>
22 #include <stdarg.h>
23 #include <string.h>
24 #include <elf.h>
25 #include <endian.h>
26 #include <errno.h>
27 #include <unistd.h>
28 #include <fcntl.h>
29 #include <sys/types.h>
30 #include <sys/wait.h>
31 #include <sys/time.h>
32 #include <sys/stat.h>
33 #include <sys/mount.h>
34 #include <sys/resource.h>
35 #include <sys/mman.h>
36 #include <sys/swap.h>
37 #include <signal.h>
38 #include <sched.h>
39 #include <sys/socket.h>
40 #include <sys/uio.h>
41 #include <sys/poll.h>
42 //#include <sys/user.h>
43
44 #define termios host_termios
45 #define winsize host_winsize
46 #define termio host_termio
47 #define sgttyb host_sgttyb /* same as target */
48 #define tchars host_tchars /* same as target */
49 #define ltchars host_ltchars /* same as target */
50
51 #include <linux/termios.h>
52 #include <linux/unistd.h>
53 #include <linux/utsname.h>
54 #include <linux/cdrom.h>
55 #include <linux/hdreg.h>
56 #include <linux/soundcard.h>
57 #include <linux/dirent.h>
58
59 #include "qemu.h"
60
61 //#define DEBUG
62
63 #ifndef PAGE_SIZE
64 #define PAGE_SIZE 4096
65 #define PAGE_MASK ~(PAGE_SIZE - 1)
66 #endif
67
68 //#include <linux/msdos_fs.h>
69 #define VFAT_IOCTL_READDIR_BOTH         _IOR('r', 1, struct dirent [2])
70 #define VFAT_IOCTL_READDIR_SHORT        _IOR('r', 2, struct dirent [2])
71
72 void host_to_target_siginfo(target_siginfo_t *tinfo, const siginfo_t *info);
73 void target_to_host_siginfo(siginfo_t *info, const target_siginfo_t *tinfo);
74 long do_sigreturn(CPUX86State *env);
75 long do_rt_sigreturn(CPUX86State *env);
76
77 #define __NR_sys_uname __NR_uname
78 #define __NR_sys_getcwd1 __NR_getcwd
79 #define __NR_sys_statfs __NR_statfs
80 #define __NR_sys_fstatfs __NR_fstatfs
81 #define __NR_sys_getdents __NR_getdents
82 #define __NR_sys_getdents64 __NR_getdents64
83 #define __NR_sys_rt_sigqueueinfo __NR_rt_sigqueueinfo
84
85 #ifdef __NR_gettid
86 _syscall0(int, gettid)
87 #else
88 static int gettid(void) {
89     return -ENOSYS;
90 }
91 #endif
92 _syscall1(int,sys_uname,struct new_utsname *,buf)
93 _syscall2(int,sys_getcwd1,char *,buf,size_t,size)
94 _syscall3(int, sys_getdents, uint, fd, struct dirent *, dirp, uint, count);
95 _syscall3(int, sys_getdents64, uint, fd, struct dirent64 *, dirp, uint, count);
96 _syscall5(int, _llseek,  uint,  fd, ulong, hi, ulong, lo,
97           loff_t *, res, uint, wh);
98 _syscall2(int,sys_statfs,const char *,path,struct kernel_statfs *,buf)
99 _syscall2(int,sys_fstatfs,int,fd,struct kernel_statfs *,buf)
100 _syscall3(int,sys_rt_sigqueueinfo,int,pid,int,sig,siginfo_t *,uinfo)
101
102 extern int personality(int);
103 extern int flock(int, int);
104 extern int setfsuid(int);
105 extern int setfsgid(int);
106 extern int setresuid(uid_t, uid_t, uid_t);
107 extern int getresuid(uid_t *, uid_t *, uid_t *);
108 extern int setresgid(gid_t, gid_t, gid_t);
109 extern int getresgid(gid_t *, gid_t *, gid_t *);
110
111 static inline long get_errno(long ret)
112 {
113     if (ret == -1)
114         return -errno;
115     else
116         return ret;
117 }
118
119 static inline int is_error(long ret)
120 {
121     return (unsigned long)ret >= (unsigned long)(-4096);
122 }
123
124 static char *target_brk;
125 static char *target_original_brk;
126
127 void target_set_brk(char *new_brk)
128 {
129     target_brk = new_brk;
130     target_original_brk = new_brk;
131 }
132
133 static long do_brk(char *new_brk)
134 {
135     char *brk_page;
136     long mapped_addr;
137     int new_alloc_size;
138
139     if (!new_brk)
140         return (long)target_brk;
141     if (new_brk < target_original_brk)
142         return -ENOMEM;
143     
144     brk_page = (char *)(((unsigned long)target_brk + PAGE_SIZE - 1) & PAGE_MASK);
145
146     /* If the new brk is less than this, set it and we're done... */
147     if (new_brk < brk_page) {
148         target_brk = new_brk;
149         return (long)target_brk;
150     }
151
152     /* We need to allocate more memory after the brk... */
153     new_alloc_size = ((new_brk - brk_page + 1)+(PAGE_SIZE-1)) & PAGE_MASK;
154     mapped_addr = get_errno((long)mmap((caddr_t)brk_page, new_alloc_size, 
155                                        PROT_READ|PROT_WRITE,
156                                        MAP_ANON|MAP_FIXED|MAP_PRIVATE, 0, 0));
157     
158     if (is_error(mapped_addr)) {
159         return mapped_addr;
160     } else {
161         target_brk = new_brk;
162         return (long)target_brk;
163     }
164 }
165
166 static inline fd_set *target_to_host_fds(fd_set *fds, 
167                                          target_long *target_fds, int n)
168 {
169 #if !defined(BSWP_NEEDED) && !defined(WORD_BIGENDIAN)
170     return (fd_set *)target_fds;
171 #else
172     int i, b;
173     if (target_fds) {
174         FD_ZERO(fds);
175         for(i = 0;i < n; i++) {
176             b = (tswapl(target_fds[i / TARGET_LONG_BITS]) >>
177                  (i & (TARGET_LONG_BITS - 1))) & 1;
178             if (b)
179                 FD_SET(i, fds);
180         }
181         return fds;
182     } else {
183         return NULL;
184     }
185 #endif
186 }
187
188 static inline void host_to_target_fds(target_long *target_fds, 
189                                       fd_set *fds, int n)
190 {
191 #if !defined(BSWP_NEEDED) && !defined(WORD_BIGENDIAN)
192     /* nothing to do */
193 #else
194     int i, nw, j, k;
195     target_long v;
196
197     if (target_fds) {
198         nw = n / TARGET_LONG_BITS;
199         k = 0;
200         for(i = 0;i < nw; i++) {
201             v = 0;
202             for(j = 0; j < TARGET_LONG_BITS; j++) {
203                 v |= ((FD_ISSET(k, fds) != 0) << j);
204                 k++;
205             }
206             target_fds[i] = tswapl(v);
207         }
208     }
209 #endif
210 }
211
212 static inline void target_to_host_timeval(struct timeval *tv, 
213                                           const struct target_timeval *target_tv)
214 {
215     tv->tv_sec = tswapl(target_tv->tv_sec);
216     tv->tv_usec = tswapl(target_tv->tv_usec);
217 }
218
219 static inline void host_to_target_timeval(struct target_timeval *target_tv, 
220                                           const struct timeval *tv)
221 {
222     target_tv->tv_sec = tswapl(tv->tv_sec);
223     target_tv->tv_usec = tswapl(tv->tv_usec);
224 }
225
226
227 static long do_select(long n, 
228                       target_long *target_rfds, target_long *target_wfds, 
229                       target_long *target_efds, struct target_timeval *target_tv)
230 {
231     fd_set rfds, wfds, efds;
232     fd_set *rfds_ptr, *wfds_ptr, *efds_ptr;
233     struct timeval tv, *tv_ptr;
234     long ret;
235
236     rfds_ptr = target_to_host_fds(&rfds, target_rfds, n);
237     wfds_ptr = target_to_host_fds(&wfds, target_wfds, n);
238     efds_ptr = target_to_host_fds(&efds, target_efds, n);
239             
240     if (target_tv) {
241         target_to_host_timeval(&tv, target_tv);
242         tv_ptr = &tv;
243     } else {
244         tv_ptr = NULL;
245     }
246     ret = get_errno(select(n, rfds_ptr, wfds_ptr, efds_ptr, tv_ptr));
247     if (!is_error(ret)) {
248         host_to_target_fds(target_rfds, rfds_ptr, n);
249         host_to_target_fds(target_wfds, wfds_ptr, n);
250         host_to_target_fds(target_efds, efds_ptr, n);
251
252         if (target_tv) {
253             host_to_target_timeval(target_tv, &tv);
254         }
255     }
256     return ret;
257 }
258
259 static long do_socketcall(int num, long *vptr)
260 {
261     long ret;
262
263     switch(num) {
264     case SOCKOP_socket:
265         ret = get_errno(socket(vptr[0], vptr[1], vptr[2]));
266         break;
267     case SOCKOP_bind:
268         ret = get_errno(bind(vptr[0], (struct sockaddr *)vptr[1], vptr[2]));
269         break;
270     case SOCKOP_connect:
271         ret = get_errno(connect(vptr[0], (struct sockaddr *)vptr[1], vptr[2]));
272         break;
273     case SOCKOP_listen:
274         ret = get_errno(listen(vptr[0], vptr[1]));
275         break;
276     case SOCKOP_accept:
277         {
278             socklen_t size;
279             size = tswap32(*(int32_t *)vptr[2]);
280             ret = get_errno(accept(vptr[0], (struct sockaddr *)vptr[1], &size));
281             if (!is_error(ret)) 
282                 *(int32_t *)vptr[2] = size;
283         }
284         break;
285     case SOCKOP_getsockname:
286         {
287             socklen_t size;
288             size = tswap32(*(int32_t *)vptr[2]);
289             ret = get_errno(getsockname(vptr[0], (struct sockaddr *)vptr[1], &size));
290             if (!is_error(ret)) 
291                 *(int32_t *)vptr[2] = size;
292         }
293         break;
294     case SOCKOP_getpeername:
295         {
296             socklen_t size;
297             size = tswap32(*(int32_t *)vptr[2]);
298             ret = get_errno(getpeername(vptr[0], (struct sockaddr *)vptr[1], &size));
299             if (!is_error(ret)) 
300                 *(int32_t *)vptr[2] = size;
301         }
302         break;
303     case SOCKOP_socketpair:
304         {
305             int tab[2];
306             int32_t *target_tab = (int32_t *)vptr[3];
307             ret = get_errno(socketpair(vptr[0], vptr[1], vptr[2], tab));
308             if (!is_error(ret)) {
309                 target_tab[0] = tswap32(tab[0]);
310                 target_tab[1] = tswap32(tab[1]);
311             }
312         }
313         break;
314     case SOCKOP_send:
315         ret = get_errno(send(vptr[0], (void *)vptr[1], vptr[2], vptr[3]));
316         break;
317     case SOCKOP_recv:
318         ret = get_errno(recv(vptr[0], (void *)vptr[1], vptr[2], vptr[3]));
319         break;
320     case SOCKOP_sendto:
321         ret = get_errno(sendto(vptr[0], (void *)vptr[1], vptr[2], vptr[3], 
322                                (struct sockaddr *)vptr[4], vptr[5]));
323         break;
324     case SOCKOP_recvfrom:
325         {
326             socklen_t size;
327             size = tswap32(*(int32_t *)vptr[5]);
328             ret = get_errno(recvfrom(vptr[0], (void *)vptr[1], vptr[2], 
329                                      vptr[3], (struct sockaddr *)vptr[4], &size));
330             if (!is_error(ret)) 
331                 *(int32_t *)vptr[5] = size;
332         }
333         break;
334     case SOCKOP_shutdown:
335         ret = get_errno(shutdown(vptr[0], vptr[1]));
336         break;
337     case SOCKOP_sendmsg:
338     case SOCKOP_recvmsg:
339         {
340             int fd;
341             struct target_msghdr *msgp;
342             struct msghdr msg;
343             int flags, count, i;
344             struct iovec *vec;
345             struct target_iovec *target_vec;
346
347             msgp = (void *)vptr[1];
348             msg.msg_name = (void *)tswapl(msgp->msg_name);
349             msg.msg_namelen = tswapl(msgp->msg_namelen);
350             msg.msg_control = (void *)tswapl(msgp->msg_control);
351             msg.msg_controllen = tswapl(msgp->msg_controllen);
352             msg.msg_flags = tswap32(msgp->msg_flags);
353
354             count = tswapl(msgp->msg_iovlen);
355             vec = alloca(count * sizeof(struct iovec));
356             target_vec = (void *)tswapl(msgp->msg_iov);
357             for(i = 0;i < count; i++) {
358                 vec[i].iov_base = (void *)tswapl(target_vec[i].iov_base);
359                 vec[i].iov_len = tswapl(target_vec[i].iov_len);
360             }
361             msg.msg_iovlen = count;
362             msg.msg_iov = vec;
363
364             fd = vptr[0];
365             flags = vptr[2];
366             if (num == SOCKOP_sendmsg)
367                 ret = sendmsg(fd, &msg, flags);
368             else
369                 ret = recvmsg(fd, &msg, flags);
370             ret = get_errno(ret);
371         }
372         break;
373     case SOCKOP_setsockopt:
374     case SOCKOP_getsockopt:
375     default:
376         gemu_log("Unsupported socketcall: %d\n", num);
377         ret = -ENOSYS;
378         break;
379     }
380     return ret;
381 }
382
383 /* kernel structure types definitions */
384 #define IFNAMSIZ        16
385
386 #define STRUCT(name, list...) STRUCT_ ## name,
387 #define STRUCT_SPECIAL(name) STRUCT_ ## name,
388 enum {
389 #include "syscall_types.h"
390 };
391 #undef STRUCT
392 #undef STRUCT_SPECIAL
393
394 #define STRUCT(name, list...) const argtype struct_ ## name ## _def[] = { list, TYPE_NULL };
395 #define STRUCT_SPECIAL(name)
396 #include "syscall_types.h"
397 #undef STRUCT
398 #undef STRUCT_SPECIAL
399
400 typedef struct IOCTLEntry {
401     int target_cmd;
402     int host_cmd;
403     const char *name;
404     int access;
405     const argtype arg_type[5];
406 } IOCTLEntry;
407
408 #define IOC_R 0x0001
409 #define IOC_W 0x0002
410 #define IOC_RW (IOC_R | IOC_W)
411
412 #define MAX_STRUCT_SIZE 4096
413
414 const IOCTLEntry ioctl_entries[] = {
415 #define IOCTL(cmd, access, types...) \
416     { TARGET_ ## cmd, cmd, #cmd, access, { types } },
417 #include "ioctls.h"
418     { 0, 0, },
419 };
420
421 static long do_ioctl(long fd, long cmd, long arg)
422 {
423     const IOCTLEntry *ie;
424     const argtype *arg_type;
425     long ret;
426     uint8_t buf_temp[MAX_STRUCT_SIZE];
427
428     ie = ioctl_entries;
429     for(;;) {
430         if (ie->target_cmd == 0) {
431             gemu_log("Unsupported ioctl: cmd=0x%04lx\n", cmd);
432             return -ENOSYS;
433         }
434         if (ie->target_cmd == cmd)
435             break;
436         ie++;
437     }
438     arg_type = ie->arg_type;
439 #if defined(DEBUG)
440     gemu_log("ioctl: cmd=0x%04lx (%s)\n", cmd, ie->name);
441 #endif
442     switch(arg_type[0]) {
443     case TYPE_NULL:
444         /* no argument */
445         ret = get_errno(ioctl(fd, ie->host_cmd));
446         break;
447     case TYPE_PTRVOID:
448     case TYPE_INT:
449         /* int argment */
450         ret = get_errno(ioctl(fd, ie->host_cmd, arg));
451         break;
452     case TYPE_PTR:
453         arg_type++;
454         switch(ie->access) {
455         case IOC_R:
456             ret = get_errno(ioctl(fd, ie->host_cmd, buf_temp));
457             if (!is_error(ret)) {
458                 thunk_convert((void *)arg, buf_temp, arg_type, THUNK_TARGET);
459             }
460             break;
461         case IOC_W:
462             thunk_convert(buf_temp, (void *)arg, arg_type, THUNK_HOST);
463             ret = get_errno(ioctl(fd, ie->host_cmd, buf_temp));
464             break;
465         default:
466         case IOC_RW:
467             thunk_convert(buf_temp, (void *)arg, arg_type, THUNK_HOST);
468             ret = get_errno(ioctl(fd, ie->host_cmd, buf_temp));
469             if (!is_error(ret)) {
470                 thunk_convert((void *)arg, buf_temp, arg_type, THUNK_TARGET);
471             }
472             break;
473         }
474         break;
475     default:
476         gemu_log("Unsupported ioctl type: cmd=0x%04lx type=%d\n", cmd, arg_type[0]);
477         ret = -ENOSYS;
478         break;
479     }
480     return ret;
481 }
482
483 bitmask_transtbl iflag_tbl[] = {
484         { TARGET_IGNBRK, TARGET_IGNBRK, IGNBRK, IGNBRK },
485         { TARGET_BRKINT, TARGET_BRKINT, BRKINT, BRKINT },
486         { TARGET_IGNPAR, TARGET_IGNPAR, IGNPAR, IGNPAR },
487         { TARGET_PARMRK, TARGET_PARMRK, PARMRK, PARMRK },
488         { TARGET_INPCK, TARGET_INPCK, INPCK, INPCK },
489         { TARGET_ISTRIP, TARGET_ISTRIP, ISTRIP, ISTRIP },
490         { TARGET_INLCR, TARGET_INLCR, INLCR, INLCR },
491         { TARGET_IGNCR, TARGET_IGNCR, IGNCR, IGNCR },
492         { TARGET_ICRNL, TARGET_ICRNL, ICRNL, ICRNL },
493         { TARGET_IUCLC, TARGET_IUCLC, IUCLC, IUCLC },
494         { TARGET_IXON, TARGET_IXON, IXON, IXON },
495         { TARGET_IXANY, TARGET_IXANY, IXANY, IXANY },
496         { TARGET_IXOFF, TARGET_IXOFF, IXOFF, IXOFF },
497         { TARGET_IMAXBEL, TARGET_IMAXBEL, IMAXBEL, IMAXBEL },
498         { 0, 0, 0, 0 }
499 };
500
501 bitmask_transtbl oflag_tbl[] = {
502         { TARGET_OPOST, TARGET_OPOST, OPOST, OPOST },
503         { TARGET_OLCUC, TARGET_OLCUC, OLCUC, OLCUC },
504         { TARGET_ONLCR, TARGET_ONLCR, ONLCR, ONLCR },
505         { TARGET_OCRNL, TARGET_OCRNL, OCRNL, OCRNL },
506         { TARGET_ONOCR, TARGET_ONOCR, ONOCR, ONOCR },
507         { TARGET_ONLRET, TARGET_ONLRET, ONLRET, ONLRET },
508         { TARGET_OFILL, TARGET_OFILL, OFILL, OFILL },
509         { TARGET_OFDEL, TARGET_OFDEL, OFDEL, OFDEL },
510         { TARGET_NLDLY, TARGET_NL0, NLDLY, NL0 },
511         { TARGET_NLDLY, TARGET_NL1, NLDLY, NL1 },
512         { TARGET_CRDLY, TARGET_CR0, CRDLY, CR0 },
513         { TARGET_CRDLY, TARGET_CR1, CRDLY, CR1 },
514         { TARGET_CRDLY, TARGET_CR2, CRDLY, CR2 },
515         { TARGET_CRDLY, TARGET_CR3, CRDLY, CR3 },
516         { TARGET_TABDLY, TARGET_TAB0, TABDLY, TAB0 },
517         { TARGET_TABDLY, TARGET_TAB1, TABDLY, TAB1 },
518         { TARGET_TABDLY, TARGET_TAB2, TABDLY, TAB2 },
519         { TARGET_TABDLY, TARGET_TAB3, TABDLY, TAB3 },
520         { TARGET_BSDLY, TARGET_BS0, BSDLY, BS0 },
521         { TARGET_BSDLY, TARGET_BS1, BSDLY, BS1 },
522         { TARGET_VTDLY, TARGET_VT0, VTDLY, VT0 },
523         { TARGET_VTDLY, TARGET_VT1, VTDLY, VT1 },
524         { TARGET_FFDLY, TARGET_FF0, FFDLY, FF0 },
525         { TARGET_FFDLY, TARGET_FF1, FFDLY, FF1 },
526         { 0, 0, 0, 0 }
527 };
528
529 bitmask_transtbl cflag_tbl[] = {
530         { TARGET_CBAUD, TARGET_B0, CBAUD, B0 },
531         { TARGET_CBAUD, TARGET_B50, CBAUD, B50 },
532         { TARGET_CBAUD, TARGET_B75, CBAUD, B75 },
533         { TARGET_CBAUD, TARGET_B110, CBAUD, B110 },
534         { TARGET_CBAUD, TARGET_B134, CBAUD, B134 },
535         { TARGET_CBAUD, TARGET_B150, CBAUD, B150 },
536         { TARGET_CBAUD, TARGET_B200, CBAUD, B200 },
537         { TARGET_CBAUD, TARGET_B300, CBAUD, B300 },
538         { TARGET_CBAUD, TARGET_B600, CBAUD, B600 },
539         { TARGET_CBAUD, TARGET_B1200, CBAUD, B1200 },
540         { TARGET_CBAUD, TARGET_B1800, CBAUD, B1800 },
541         { TARGET_CBAUD, TARGET_B2400, CBAUD, B2400 },
542         { TARGET_CBAUD, TARGET_B4800, CBAUD, B4800 },
543         { TARGET_CBAUD, TARGET_B9600, CBAUD, B9600 },
544         { TARGET_CBAUD, TARGET_B19200, CBAUD, B19200 },
545         { TARGET_CBAUD, TARGET_B38400, CBAUD, B38400 },
546         { TARGET_CBAUD, TARGET_B57600, CBAUD, B57600 },
547         { TARGET_CBAUD, TARGET_B115200, CBAUD, B115200 },
548         { TARGET_CBAUD, TARGET_B230400, CBAUD, B230400 },
549         { TARGET_CBAUD, TARGET_B460800, CBAUD, B460800 },
550         { TARGET_CSIZE, TARGET_CS5, CSIZE, CS5 },
551         { TARGET_CSIZE, TARGET_CS6, CSIZE, CS6 },
552         { TARGET_CSIZE, TARGET_CS7, CSIZE, CS7 },
553         { TARGET_CSIZE, TARGET_CS8, CSIZE, CS8 },
554         { TARGET_CSTOPB, TARGET_CSTOPB, CSTOPB, CSTOPB },
555         { TARGET_CREAD, TARGET_CREAD, CREAD, CREAD },
556         { TARGET_PARENB, TARGET_PARENB, PARENB, PARENB },
557         { TARGET_PARODD, TARGET_PARODD, PARODD, PARODD },
558         { TARGET_HUPCL, TARGET_HUPCL, HUPCL, HUPCL },
559         { TARGET_CLOCAL, TARGET_CLOCAL, CLOCAL, CLOCAL },
560         { TARGET_CRTSCTS, TARGET_CRTSCTS, CRTSCTS, CRTSCTS },
561         { 0, 0, 0, 0 }
562 };
563
564 bitmask_transtbl lflag_tbl[] = {
565         { TARGET_ISIG, TARGET_ISIG, ISIG, ISIG },
566         { TARGET_ICANON, TARGET_ICANON, ICANON, ICANON },
567         { TARGET_XCASE, TARGET_XCASE, XCASE, XCASE },
568         { TARGET_ECHO, TARGET_ECHO, ECHO, ECHO },
569         { TARGET_ECHOE, TARGET_ECHOE, ECHOE, ECHOE },
570         { TARGET_ECHOK, TARGET_ECHOK, ECHOK, ECHOK },
571         { TARGET_ECHONL, TARGET_ECHONL, ECHONL, ECHONL },
572         { TARGET_NOFLSH, TARGET_NOFLSH, NOFLSH, NOFLSH },
573         { TARGET_TOSTOP, TARGET_TOSTOP, TOSTOP, TOSTOP },
574         { TARGET_ECHOCTL, TARGET_ECHOCTL, ECHOCTL, ECHOCTL },
575         { TARGET_ECHOPRT, TARGET_ECHOPRT, ECHOPRT, ECHOPRT },
576         { TARGET_ECHOKE, TARGET_ECHOKE, ECHOKE, ECHOKE },
577         { TARGET_FLUSHO, TARGET_FLUSHO, FLUSHO, FLUSHO },
578         { TARGET_PENDIN, TARGET_PENDIN, PENDIN, PENDIN },
579         { TARGET_IEXTEN, TARGET_IEXTEN, IEXTEN, IEXTEN },
580         { 0, 0, 0, 0 }
581 };
582
583 static void target_to_host_termios (void *dst, const void *src)
584 {
585     struct host_termios *host = dst;
586     const struct target_termios *target = src;
587     
588     host->c_iflag = 
589         target_to_host_bitmask(tswap32(target->c_iflag), iflag_tbl);
590     host->c_oflag = 
591         target_to_host_bitmask(tswap32(target->c_oflag), oflag_tbl);
592     host->c_cflag = 
593         target_to_host_bitmask(tswap32(target->c_cflag), cflag_tbl);
594     host->c_lflag = 
595         target_to_host_bitmask(tswap32(target->c_lflag), lflag_tbl);
596     host->c_line = target->c_line;
597     
598     host->c_cc[VINTR] = target->c_cc[TARGET_VINTR]; 
599     host->c_cc[VQUIT] = target->c_cc[TARGET_VQUIT]; 
600     host->c_cc[VERASE] = target->c_cc[TARGET_VERASE];       
601     host->c_cc[VKILL] = target->c_cc[TARGET_VKILL]; 
602     host->c_cc[VEOF] = target->c_cc[TARGET_VEOF];   
603     host->c_cc[VTIME] = target->c_cc[TARGET_VTIME]; 
604     host->c_cc[VMIN] = target->c_cc[TARGET_VMIN];   
605     host->c_cc[VSWTC] = target->c_cc[TARGET_VSWTC]; 
606     host->c_cc[VSTART] = target->c_cc[TARGET_VSTART];       
607     host->c_cc[VSTOP] = target->c_cc[TARGET_VSTOP]; 
608     host->c_cc[VSUSP] = target->c_cc[TARGET_VSUSP]; 
609     host->c_cc[VEOL] = target->c_cc[TARGET_VEOL];   
610     host->c_cc[VREPRINT] = target->c_cc[TARGET_VREPRINT];   
611     host->c_cc[VDISCARD] = target->c_cc[TARGET_VDISCARD];   
612     host->c_cc[VWERASE] = target->c_cc[TARGET_VWERASE];     
613     host->c_cc[VLNEXT] = target->c_cc[TARGET_VLNEXT];       
614     host->c_cc[VEOL2] = target->c_cc[TARGET_VEOL2]; 
615 }
616   
617 static void host_to_target_termios (void *dst, const void *src)
618 {
619     struct target_termios *target = dst;
620     const struct host_termios *host = src;
621
622     target->c_iflag = 
623         tswap32(host_to_target_bitmask(host->c_iflag, iflag_tbl));
624     target->c_oflag = 
625         tswap32(host_to_target_bitmask(host->c_oflag, oflag_tbl));
626     target->c_cflag = 
627         tswap32(host_to_target_bitmask(host->c_cflag, cflag_tbl));
628     target->c_lflag = 
629         tswap32(host_to_target_bitmask(host->c_lflag, lflag_tbl));
630     target->c_line = host->c_line;
631   
632     target->c_cc[TARGET_VINTR] = host->c_cc[VINTR];
633     target->c_cc[TARGET_VQUIT] = host->c_cc[VQUIT];
634     target->c_cc[TARGET_VERASE] = host->c_cc[VERASE];
635     target->c_cc[TARGET_VKILL] = host->c_cc[VKILL];
636     target->c_cc[TARGET_VEOF] = host->c_cc[VEOF];
637     target->c_cc[TARGET_VTIME] = host->c_cc[VTIME];
638     target->c_cc[TARGET_VMIN] = host->c_cc[VMIN];
639     target->c_cc[TARGET_VSWTC] = host->c_cc[VSWTC];
640     target->c_cc[TARGET_VSTART] = host->c_cc[VSTART];
641     target->c_cc[TARGET_VSTOP] = host->c_cc[VSTOP];
642     target->c_cc[TARGET_VSUSP] = host->c_cc[VSUSP];
643     target->c_cc[TARGET_VEOL] = host->c_cc[VEOL];
644     target->c_cc[TARGET_VREPRINT] = host->c_cc[VREPRINT];
645     target->c_cc[TARGET_VDISCARD] = host->c_cc[VDISCARD];
646     target->c_cc[TARGET_VWERASE] = host->c_cc[VWERASE];
647     target->c_cc[TARGET_VLNEXT] = host->c_cc[VLNEXT];
648     target->c_cc[TARGET_VEOL2] = host->c_cc[VEOL2];
649 }
650
651 StructEntry struct_termios_def = {
652     .convert = { host_to_target_termios, target_to_host_termios },
653     .size = { sizeof(struct target_termios), sizeof(struct host_termios) },
654     .align = { __alignof__(struct target_termios), __alignof__(struct host_termios) },
655 };
656
657 #ifdef TARGET_I386
658
659 /* NOTE: there is really one LDT for all the threads */
660 uint8_t *ldt_table;
661
662 static int read_ldt(void *ptr, unsigned long bytecount)
663 {
664     int size;
665
666     if (!ldt_table)
667         return 0;
668     size = TARGET_LDT_ENTRIES * TARGET_LDT_ENTRY_SIZE;
669     if (size > bytecount)
670         size = bytecount;
671     memcpy(ptr, ldt_table, size);
672     return size;
673 }
674
675 /* XXX: add locking support */
676 static int write_ldt(CPUX86State *env, 
677                      void *ptr, unsigned long bytecount, int oldmode)
678 {
679     struct target_modify_ldt_ldt_s ldt_info;
680     int seg_32bit, contents, read_exec_only, limit_in_pages;
681     int seg_not_present, useable;
682     uint32_t *lp, entry_1, entry_2;
683
684     if (bytecount != sizeof(ldt_info))
685         return -EINVAL;
686     memcpy(&ldt_info, ptr, sizeof(ldt_info));
687     tswap32s(&ldt_info.entry_number);
688     tswapls((long *)&ldt_info.base_addr);
689     tswap32s(&ldt_info.limit);
690     tswap32s(&ldt_info.flags);
691     
692     if (ldt_info.entry_number >= TARGET_LDT_ENTRIES)
693         return -EINVAL;
694     seg_32bit = ldt_info.flags & 1;
695     contents = (ldt_info.flags >> 1) & 3;
696     read_exec_only = (ldt_info.flags >> 3) & 1;
697     limit_in_pages = (ldt_info.flags >> 4) & 1;
698     seg_not_present = (ldt_info.flags >> 5) & 1;
699     useable = (ldt_info.flags >> 6) & 1;
700
701     if (contents == 3) {
702         if (oldmode)
703             return -EINVAL;
704         if (seg_not_present == 0)
705             return -EINVAL;
706     }
707     /* allocate the LDT */
708     if (!ldt_table) {
709         ldt_table = malloc(TARGET_LDT_ENTRIES * TARGET_LDT_ENTRY_SIZE);
710         if (!ldt_table)
711             return -ENOMEM;
712         memset(ldt_table, 0, TARGET_LDT_ENTRIES * TARGET_LDT_ENTRY_SIZE);
713         env->ldt.base = ldt_table;
714         env->ldt.limit = 0xffff;
715     }
716
717     /* NOTE: same code as Linux kernel */
718     /* Allow LDTs to be cleared by the user. */
719     if (ldt_info.base_addr == 0 && ldt_info.limit == 0) {
720         if (oldmode ||
721             (contents == 0              &&
722              read_exec_only == 1        &&
723              seg_32bit == 0             &&
724              limit_in_pages == 0        &&
725              seg_not_present == 1       &&
726              useable == 0 )) {
727             entry_1 = 0;
728             entry_2 = 0;
729             goto install;
730         }
731     }
732     
733     entry_1 = ((ldt_info.base_addr & 0x0000ffff) << 16) |
734         (ldt_info.limit & 0x0ffff);
735     entry_2 = (ldt_info.base_addr & 0xff000000) |
736         ((ldt_info.base_addr & 0x00ff0000) >> 16) |
737         (ldt_info.limit & 0xf0000) |
738         ((read_exec_only ^ 1) << 9) |
739         (contents << 10) |
740         ((seg_not_present ^ 1) << 15) |
741         (seg_32bit << 22) |
742         (limit_in_pages << 23) |
743         0x7000;
744     if (!oldmode)
745         entry_2 |= (useable << 20);
746     
747     /* Install the new entry ...  */
748 install:
749     lp = (uint32_t *)(ldt_table + (ldt_info.entry_number << 3));
750     lp[0] = tswap32(entry_1);
751     lp[1] = tswap32(entry_2);
752     return 0;
753 }
754
755 /* specific and weird i386 syscalls */
756 int do_modify_ldt(CPUX86State *env, int func, void *ptr, unsigned long bytecount)
757 {
758     int ret = -ENOSYS;
759     
760     switch (func) {
761     case 0:
762         ret = read_ldt(ptr, bytecount);
763         break;
764     case 1:
765         ret = write_ldt(env, ptr, bytecount, 1);
766         break;
767     case 0x11:
768         ret = write_ldt(env, ptr, bytecount, 0);
769         break;
770     }
771     return ret;
772 }
773
774 /* vm86 emulation */
775
776 #define SAFE_MASK  (0xDD5)
777
778 int do_vm86(CPUX86State *env, long subfunction, 
779             struct target_vm86plus_struct * target_v86)
780 {
781     TaskState *ts = env->opaque;
782     int ret;
783     
784     switch (subfunction) {
785     case TARGET_VM86_REQUEST_IRQ:
786     case TARGET_VM86_FREE_IRQ:
787     case TARGET_VM86_GET_IRQ_BITS:
788     case TARGET_VM86_GET_AND_RESET_IRQ:
789         gemu_log("qemu: unsupported vm86 subfunction (%ld)\n", subfunction);
790         ret = -EINVAL;
791         goto out;
792     case TARGET_VM86_PLUS_INSTALL_CHECK:
793         /* NOTE: on old vm86 stuff this will return the error
794            from verify_area(), because the subfunction is
795            interpreted as (invalid) address to vm86_struct.
796            So the installation check works.
797             */
798         ret = 0;
799         goto out;
800     }
801
802     ts->target_v86 = target_v86;
803
804     /* save current CPU regs */
805     ts->vm86_saved_regs.eax = 0; /* default vm86 syscall return code */
806     ts->vm86_saved_regs.ebx = env->regs[R_EBX];
807     ts->vm86_saved_regs.ecx = env->regs[R_ECX];
808     ts->vm86_saved_regs.edx = env->regs[R_EDX];
809     ts->vm86_saved_regs.esi = env->regs[R_ESI];
810     ts->vm86_saved_regs.edi = env->regs[R_EDI];
811     ts->vm86_saved_regs.ebp = env->regs[R_EBP];
812     ts->vm86_saved_regs.esp = env->regs[R_ESP];
813     ts->vm86_saved_regs.eflags = env->eflags;
814     ts->vm86_saved_regs.eip  = env->eip;
815     ts->vm86_saved_regs.cs = env->segs[R_CS];
816     ts->vm86_saved_regs.ss = env->segs[R_SS];
817     ts->vm86_saved_regs.ds = env->segs[R_DS];
818     ts->vm86_saved_regs.es = env->segs[R_ES];
819     ts->vm86_saved_regs.fs = env->segs[R_FS];
820     ts->vm86_saved_regs.gs = env->segs[R_GS];
821
822     /* build vm86 CPU state */
823     env->eflags = (env->eflags & ~SAFE_MASK) | 
824         (tswap32(target_v86->regs.eflags) & SAFE_MASK) | VM_MASK;
825
826     env->regs[R_EBX] = tswap32(target_v86->regs.ebx);
827     env->regs[R_ECX] = tswap32(target_v86->regs.ecx);
828     env->regs[R_EDX] = tswap32(target_v86->regs.edx);
829     env->regs[R_ESI] = tswap32(target_v86->regs.esi);
830     env->regs[R_EDI] = tswap32(target_v86->regs.edi);
831     env->regs[R_EBP] = tswap32(target_v86->regs.ebp);
832     env->regs[R_ESP] = tswap32(target_v86->regs.esp);
833     env->eip = tswap32(target_v86->regs.eip);
834     cpu_x86_load_seg(env, R_CS, tswap16(target_v86->regs.cs));
835     cpu_x86_load_seg(env, R_SS, tswap16(target_v86->regs.ss));
836     cpu_x86_load_seg(env, R_DS, tswap16(target_v86->regs.ds));
837     cpu_x86_load_seg(env, R_ES, tswap16(target_v86->regs.es));
838     cpu_x86_load_seg(env, R_FS, tswap16(target_v86->regs.fs));
839     cpu_x86_load_seg(env, R_GS, tswap16(target_v86->regs.gs));
840     ret = tswap32(target_v86->regs.eax); /* eax will be restored at
841                                             the end of the syscall */
842     /* now the virtual CPU is ready for vm86 execution ! */
843  out:
844     return ret;
845 }
846
847 /* this stack is the equivalent of the kernel stack associated with a
848    thread/process */
849 #define NEW_STACK_SIZE 8192
850
851 static int clone_func(void *arg)
852 {
853     CPUX86State *env = arg;
854     cpu_loop(env);
855     /* never exits */
856     return 0;
857 }
858
859 int do_fork(CPUX86State *env, unsigned int flags, unsigned long newsp)
860 {
861     int ret;
862     TaskState *ts;
863     uint8_t *new_stack;
864     CPUX86State *new_env;
865     
866     if (flags & CLONE_VM) {
867         if (!newsp)
868             newsp = env->regs[R_ESP];
869         ts = malloc(sizeof(TaskState) + NEW_STACK_SIZE);
870         memset(ts, 0, sizeof(TaskState));
871         new_stack = ts->stack;
872         ts->used = 1;
873         /* add in task state list */
874         ts->next = first_task_state;
875         first_task_state = ts;
876         /* we create a new CPU instance. */
877         new_env = cpu_x86_init();
878         memcpy(new_env, env, sizeof(CPUX86State));
879         new_env->regs[R_ESP] = newsp;
880         new_env->regs[R_EAX] = 0;
881         new_env->opaque = ts;
882         ret = clone(clone_func, new_stack + NEW_STACK_SIZE, flags, new_env);
883     } else {
884         /* if no CLONE_VM, we consider it is a fork */
885         if ((flags & ~CSIGNAL) != 0)
886             return -EINVAL;
887         ret = fork();
888     }
889     return ret;
890 }
891
892 #endif
893
894 #define high2lowuid(x) (x)
895 #define high2lowgid(x) (x)
896 #define low2highuid(x) (x)
897 #define low2highgid(x) (x)
898
899 void syscall_init(void)
900 {
901 #define STRUCT(name, list...) thunk_register_struct(STRUCT_ ## name, #name, struct_ ## name ## _def); 
902 #define STRUCT_SPECIAL(name) thunk_register_struct_direct(STRUCT_ ## name, #name, &struct_ ## name ## _def); 
903 #include "syscall_types.h"
904 #undef STRUCT
905 #undef STRUCT_SPECIAL
906 }
907                                  
908 long do_syscall(void *cpu_env, int num, long arg1, long arg2, long arg3, 
909                 long arg4, long arg5, long arg6)
910 {
911     long ret;
912     struct stat st;
913     struct kernel_statfs *stfs;
914     
915 #ifdef DEBUG
916     gemu_log("syscall %d\n", num);
917 #endif
918     switch(num) {
919     case TARGET_NR_exit:
920 #ifdef HAVE_GPROF
921         _mcleanup();
922 #endif
923         /* XXX: should free thread stack and CPU env */
924         _exit(arg1);
925         ret = 0; /* avoid warning */
926         break;
927     case TARGET_NR_read:
928         ret = get_errno(read(arg1, (void *)arg2, arg3));
929         break;
930     case TARGET_NR_write:
931         ret = get_errno(write(arg1, (void *)arg2, arg3));
932         break;
933     case TARGET_NR_open:
934         ret = get_errno(open((const char *)arg1, arg2, arg3));
935         break;
936     case TARGET_NR_close:
937         ret = get_errno(close(arg1));
938         break;
939     case TARGET_NR_brk:
940         ret = do_brk((char *)arg1);
941         break;
942     case TARGET_NR_fork:
943         ret = get_errno(do_fork(cpu_env, SIGCHLD, 0));
944         break;
945     case TARGET_NR_waitpid:
946         {
947             int *status = (int *)arg2;
948             ret = get_errno(waitpid(arg1, status, arg3));
949             if (!is_error(ret) && status)
950                 tswapls((long *)&status);
951         }
952         break;
953     case TARGET_NR_creat:
954         ret = get_errno(creat((const char *)arg1, arg2));
955         break;
956     case TARGET_NR_link:
957         ret = get_errno(link((const char *)arg1, (const char *)arg2));
958         break;
959     case TARGET_NR_unlink:
960         ret = get_errno(unlink((const char *)arg1));
961         break;
962     case TARGET_NR_execve:
963         ret = get_errno(execve((const char *)arg1, (void *)arg2, (void *)arg3));
964         break;
965     case TARGET_NR_chdir:
966         ret = get_errno(chdir((const char *)arg1));
967         break;
968     case TARGET_NR_time:
969         {
970             int *time_ptr = (int *)arg1;
971             ret = get_errno(time((time_t *)time_ptr));
972             if (!is_error(ret) && time_ptr)
973                 tswap32s(time_ptr);
974         }
975         break;
976     case TARGET_NR_mknod:
977         ret = get_errno(mknod((const char *)arg1, arg2, arg3));
978         break;
979     case TARGET_NR_chmod:
980         ret = get_errno(chmod((const char *)arg1, arg2));
981         break;
982     case TARGET_NR_lchown:
983         ret = get_errno(chown((const char *)arg1, arg2, arg3));
984         break;
985     case TARGET_NR_break:
986         goto unimplemented;
987     case TARGET_NR_oldstat:
988         goto unimplemented;
989     case TARGET_NR_lseek:
990         ret = get_errno(lseek(arg1, arg2, arg3));
991         break;
992     case TARGET_NR_getpid:
993         ret = get_errno(getpid());
994         break;
995     case TARGET_NR_mount:
996         /* need to look at the data field */
997         goto unimplemented;
998     case TARGET_NR_umount:
999         ret = get_errno(umount((const char *)arg1));
1000         break;
1001     case TARGET_NR_setuid:
1002         ret = get_errno(setuid(low2highuid(arg1)));
1003         break;
1004     case TARGET_NR_getuid:
1005         ret = get_errno(getuid());
1006         break;
1007     case TARGET_NR_stime:
1008         {
1009             int *time_ptr = (int *)arg1;
1010             if (time_ptr)
1011                 tswap32s(time_ptr);
1012             ret = get_errno(stime((time_t *)time_ptr));
1013         }
1014         break;
1015     case TARGET_NR_ptrace:
1016         goto unimplemented;
1017     case TARGET_NR_alarm:
1018         ret = alarm(arg1);
1019         break;
1020     case TARGET_NR_oldfstat:
1021         goto unimplemented;
1022     case TARGET_NR_pause:
1023         ret = get_errno(pause());
1024         break;
1025     case TARGET_NR_utime:
1026         goto unimplemented;
1027     case TARGET_NR_stty:
1028         goto unimplemented;
1029     case TARGET_NR_gtty:
1030         goto unimplemented;
1031     case TARGET_NR_access:
1032         ret = get_errno(access((const char *)arg1, arg2));
1033         break;
1034     case TARGET_NR_nice:
1035         ret = get_errno(nice(arg1));
1036         break;
1037     case TARGET_NR_ftime:
1038         goto unimplemented;
1039     case TARGET_NR_sync:
1040         sync();
1041         ret = 0;
1042         break;
1043     case TARGET_NR_kill:
1044         ret = get_errno(kill(arg1, arg2));
1045         break;
1046     case TARGET_NR_rename:
1047         ret = get_errno(rename((const char *)arg1, (const char *)arg2));
1048         break;
1049     case TARGET_NR_mkdir:
1050         ret = get_errno(mkdir((const char *)arg1, arg2));
1051         break;
1052     case TARGET_NR_rmdir:
1053         ret = get_errno(rmdir((const char *)arg1));
1054         break;
1055     case TARGET_NR_dup:
1056         ret = get_errno(dup(arg1));
1057         break;
1058     case TARGET_NR_pipe:
1059         {
1060             int *pipe_ptr = (int *)arg1;
1061             ret = get_errno(pipe(pipe_ptr));
1062             if (!is_error(ret)) {
1063                 tswap32s(&pipe_ptr[0]);
1064                 tswap32s(&pipe_ptr[1]);
1065             }
1066         }
1067         break;
1068     case TARGET_NR_times:
1069         goto unimplemented;
1070     case TARGET_NR_prof:
1071         goto unimplemented;
1072     case TARGET_NR_setgid:
1073         ret = get_errno(setgid(low2highgid(arg1)));
1074         break;
1075     case TARGET_NR_getgid:
1076         ret = get_errno(getgid());
1077         break;
1078     case TARGET_NR_signal:
1079         goto unimplemented;
1080     case TARGET_NR_geteuid:
1081         ret = get_errno(geteuid());
1082         break;
1083     case TARGET_NR_getegid:
1084         ret = get_errno(getegid());
1085         break;
1086     case TARGET_NR_acct:
1087         goto unimplemented;
1088     case TARGET_NR_umount2:
1089         ret = get_errno(umount2((const char *)arg1, arg2));
1090         break;
1091     case TARGET_NR_lock:
1092         goto unimplemented;
1093     case TARGET_NR_ioctl:
1094         ret = do_ioctl(arg1, arg2, arg3);
1095         break;
1096     case TARGET_NR_fcntl:
1097         switch(arg2) {
1098         case F_GETLK:
1099         case F_SETLK:
1100         case F_SETLKW:
1101             goto unimplemented;
1102         default:
1103             ret = get_errno(fcntl(arg1, arg2, arg3));
1104             break;
1105         }
1106         break;
1107     case TARGET_NR_mpx:
1108         goto unimplemented;
1109     case TARGET_NR_setpgid:
1110         ret = get_errno(setpgid(arg1, arg2));
1111         break;
1112     case TARGET_NR_ulimit:
1113         goto unimplemented;
1114     case TARGET_NR_oldolduname:
1115         goto unimplemented;
1116     case TARGET_NR_umask:
1117         ret = get_errno(umask(arg1));
1118         break;
1119     case TARGET_NR_chroot:
1120         ret = get_errno(chroot((const char *)arg1));
1121         break;
1122     case TARGET_NR_ustat:
1123         goto unimplemented;
1124     case TARGET_NR_dup2:
1125         ret = get_errno(dup2(arg1, arg2));
1126         break;
1127     case TARGET_NR_getppid:
1128         ret = get_errno(getppid());
1129         break;
1130     case TARGET_NR_getpgrp:
1131         ret = get_errno(getpgrp());
1132         break;
1133     case TARGET_NR_setsid:
1134         ret = get_errno(setsid());
1135         break;
1136     case TARGET_NR_sigaction:
1137         {
1138             struct target_old_sigaction *old_act = (void *)arg2;
1139             struct target_old_sigaction *old_oact = (void *)arg3;
1140             struct target_sigaction act, oact, *pact;
1141             if (old_act) {
1142                 act._sa_handler = old_act->_sa_handler;
1143                 target_siginitset(&act.sa_mask, old_act->sa_mask);
1144                 act.sa_flags = old_act->sa_flags;
1145                 act.sa_restorer = old_act->sa_restorer;
1146                 pact = &act;
1147             } else {
1148                 pact = NULL;
1149             }
1150             ret = get_errno(do_sigaction(arg1, pact, &oact));
1151             if (!is_error(ret) && old_oact) {
1152                 old_oact->_sa_handler = oact._sa_handler;
1153                 old_oact->sa_mask = oact.sa_mask.sig[0];
1154                 old_oact->sa_flags = oact.sa_flags;
1155                 old_oact->sa_restorer = oact.sa_restorer;
1156             }
1157         }
1158         break;
1159     case TARGET_NR_rt_sigaction:
1160         ret = get_errno(do_sigaction(arg1, (void *)arg2, (void *)arg3));
1161         break;
1162     case TARGET_NR_sgetmask:
1163         {
1164             sigset_t cur_set;
1165             target_ulong target_set;
1166             sigprocmask(0, NULL, &cur_set);
1167             host_to_target_old_sigset(&target_set, &cur_set);
1168             ret = target_set;
1169         }
1170         break;
1171     case TARGET_NR_ssetmask:
1172         {
1173             sigset_t set, oset, cur_set;
1174             target_ulong target_set = arg1;
1175             sigprocmask(0, NULL, &cur_set);
1176             target_to_host_old_sigset(&set, &target_set);
1177             sigorset(&set, &set, &cur_set);
1178             sigprocmask(SIG_SETMASK, &set, &oset);
1179             host_to_target_old_sigset(&target_set, &oset);
1180             ret = target_set;
1181         }
1182         break;
1183     case TARGET_NR_sigprocmask:
1184         {
1185             int how = arg1;
1186             sigset_t set, oldset, *set_ptr;
1187             target_ulong *pset = (void *)arg2, *poldset = (void *)arg3;
1188             
1189             if (pset) {
1190                 switch(how) {
1191                 case TARGET_SIG_BLOCK:
1192                     how = SIG_BLOCK;
1193                     break;
1194                 case TARGET_SIG_UNBLOCK:
1195                     how = SIG_UNBLOCK;
1196                     break;
1197                 case TARGET_SIG_SETMASK:
1198                     how = SIG_SETMASK;
1199                     break;
1200                 default:
1201                     ret = -EINVAL;
1202                     goto fail;
1203                 }
1204                 target_to_host_old_sigset(&set, pset);
1205                 set_ptr = &set;
1206             } else {
1207                 how = 0;
1208                 set_ptr = NULL;
1209             }
1210             ret = get_errno(sigprocmask(arg1, set_ptr, &oldset));
1211             if (!is_error(ret) && poldset) {
1212                 host_to_target_old_sigset(poldset, &oldset);
1213             }
1214         }
1215         break;
1216     case TARGET_NR_rt_sigprocmask:
1217         {
1218             int how = arg1;
1219             sigset_t set, oldset, *set_ptr;
1220             target_sigset_t *pset = (void *)arg2;
1221             target_sigset_t *poldset = (void *)arg3;
1222             
1223             if (pset) {
1224                 switch(how) {
1225                 case TARGET_SIG_BLOCK:
1226                     how = SIG_BLOCK;
1227                     break;
1228                 case TARGET_SIG_UNBLOCK:
1229                     how = SIG_UNBLOCK;
1230                     break;
1231                 case TARGET_SIG_SETMASK:
1232                     how = SIG_SETMASK;
1233                     break;
1234                 default:
1235                     ret = -EINVAL;
1236                     goto fail;
1237                 }
1238                 target_to_host_sigset(&set, pset);
1239                 set_ptr = &set;
1240             } else {
1241                 how = 0;
1242                 set_ptr = NULL;
1243             }
1244             ret = get_errno(sigprocmask(how, set_ptr, &oldset));
1245             if (!is_error(ret) && poldset) {
1246                 host_to_target_sigset(poldset, &oldset);
1247             }
1248         }
1249         break;
1250     case TARGET_NR_sigpending:
1251         {
1252             sigset_t set;
1253             ret = get_errno(sigpending(&set));
1254             if (!is_error(ret)) {
1255                 host_to_target_old_sigset((target_ulong *)arg1, &set);
1256             }
1257         }
1258         break;
1259     case TARGET_NR_rt_sigpending:
1260         {
1261             sigset_t set;
1262             ret = get_errno(sigpending(&set));
1263             if (!is_error(ret)) {
1264                 host_to_target_sigset((target_sigset_t *)arg1, &set);
1265             }
1266         }
1267         break;
1268     case TARGET_NR_sigsuspend:
1269         {
1270             sigset_t set;
1271             target_to_host_old_sigset(&set, (target_ulong *)arg1);
1272             ret = get_errno(sigsuspend(&set));
1273         }
1274         break;
1275     case TARGET_NR_rt_sigsuspend:
1276         {
1277             sigset_t set;
1278             target_to_host_sigset(&set, (target_sigset_t *)arg1);
1279             ret = get_errno(sigsuspend(&set));
1280         }
1281         break;
1282     case TARGET_NR_rt_sigtimedwait:
1283         {
1284             target_sigset_t *target_set = (void *)arg1;
1285             target_siginfo_t *target_uinfo = (void *)arg2;
1286             struct target_timespec *target_uts = (void *)arg3;
1287             sigset_t set;
1288             struct timespec uts, *puts;
1289             siginfo_t uinfo;
1290             
1291             target_to_host_sigset(&set, target_set);
1292             if (target_uts) {
1293                 puts = &uts;
1294                 puts->tv_sec = tswapl(target_uts->tv_sec);
1295                 puts->tv_nsec = tswapl(target_uts->tv_nsec);
1296             } else {
1297                 puts = NULL;
1298             }
1299             ret = get_errno(sigtimedwait(&set, &uinfo, puts));
1300             if (!is_error(ret) && target_uinfo) {
1301                 host_to_target_siginfo(target_uinfo, &uinfo);
1302             }
1303         }
1304         break;
1305     case TARGET_NR_rt_sigqueueinfo:
1306         {
1307             siginfo_t uinfo;
1308             target_to_host_siginfo(&uinfo, (target_siginfo_t *)arg3);
1309             ret = get_errno(sys_rt_sigqueueinfo(arg1, arg2, &uinfo));
1310         }
1311         break;
1312     case TARGET_NR_sigreturn:
1313         /* NOTE: ret is eax, so not transcoding must be done */
1314         ret = do_sigreturn(cpu_env);
1315         break;
1316     case TARGET_NR_rt_sigreturn:
1317         /* NOTE: ret is eax, so not transcoding must be done */
1318         ret = do_rt_sigreturn(cpu_env);
1319         break;
1320     case TARGET_NR_setreuid:
1321         ret = get_errno(setreuid(arg1, arg2));
1322         break;
1323     case TARGET_NR_setregid:
1324         ret = get_errno(setregid(arg1, arg2));
1325         break;
1326     case TARGET_NR_sethostname:
1327         ret = get_errno(sethostname((const char *)arg1, arg2));
1328         break;
1329     case TARGET_NR_setrlimit:
1330         {
1331             /* XXX: convert resource ? */
1332             int resource = arg1;
1333             struct target_rlimit *target_rlim = (void *)arg2;
1334             struct rlimit rlim;
1335             rlim.rlim_cur = tswapl(target_rlim->rlim_cur);
1336             rlim.rlim_max = tswapl(target_rlim->rlim_max);
1337             ret = get_errno(setrlimit(resource, &rlim));
1338         }
1339         break;
1340     case TARGET_NR_getrlimit:
1341         {
1342             /* XXX: convert resource ? */
1343             int resource = arg1;
1344             struct target_rlimit *target_rlim = (void *)arg2;
1345             struct rlimit rlim;
1346             
1347             ret = get_errno(getrlimit(resource, &rlim));
1348             if (!is_error(ret)) {
1349                 target_rlim->rlim_cur = tswapl(rlim.rlim_cur);
1350                 target_rlim->rlim_max = tswapl(rlim.rlim_max);
1351             }
1352         }
1353         break;
1354     case TARGET_NR_getrusage:
1355         goto unimplemented;
1356     case TARGET_NR_gettimeofday:
1357         {
1358             struct target_timeval *target_tv = (void *)arg1;
1359             struct timeval tv;
1360             ret = get_errno(gettimeofday(&tv, NULL));
1361             if (!is_error(ret)) {
1362                 host_to_target_timeval(target_tv, &tv);
1363             }
1364         }
1365         break;
1366     case TARGET_NR_settimeofday:
1367         {
1368             struct target_timeval *target_tv = (void *)arg1;
1369             struct timeval tv;
1370             target_to_host_timeval(&tv, target_tv);
1371             ret = get_errno(settimeofday(&tv, NULL));
1372         }
1373         break;
1374     case TARGET_NR_getgroups:
1375         goto unimplemented;
1376     case TARGET_NR_setgroups:
1377         goto unimplemented;
1378     case TARGET_NR_select:
1379         goto unimplemented;
1380     case TARGET_NR_symlink:
1381         ret = get_errno(symlink((const char *)arg1, (const char *)arg2));
1382         break;
1383     case TARGET_NR_oldlstat:
1384         goto unimplemented;
1385     case TARGET_NR_readlink:
1386         ret = get_errno(readlink((const char *)arg1, (char *)arg2, arg3));
1387         break;
1388     case TARGET_NR_uselib:
1389         goto unimplemented;
1390     case TARGET_NR_swapon:
1391         ret = get_errno(swapon((const char *)arg1, arg2));
1392         break;
1393     case TARGET_NR_reboot:
1394         goto unimplemented;
1395     case TARGET_NR_readdir:
1396         goto unimplemented;
1397 #ifdef TARGET_I386
1398     case TARGET_NR_mmap:
1399         {
1400             uint32_t v1, v2, v3, v4, v5, v6, *vptr;
1401             vptr = (uint32_t *)arg1;
1402             v1 = tswap32(vptr[0]);
1403             v2 = tswap32(vptr[1]);
1404             v3 = tswap32(vptr[2]);
1405             v4 = tswap32(vptr[3]);
1406             v5 = tswap32(vptr[4]);
1407             v6 = tswap32(vptr[5]);
1408             ret = get_errno((long)mmap((void *)v1, v2, v3, v4, v5, v6));
1409         }
1410         break;
1411 #endif
1412 #ifdef TARGET_I386
1413     case TARGET_NR_mmap2:
1414 #else
1415     case TARGET_NR_mmap:
1416 #endif
1417         ret = get_errno((long)mmap((void *)arg1, arg2, arg3, arg4, arg5, arg6));
1418         break;
1419     case TARGET_NR_munmap:
1420         ret = get_errno(munmap((void *)arg1, arg2));
1421         break;
1422     case TARGET_NR_mprotect:
1423         ret = get_errno(mprotect((void *)arg1, arg2, arg3));
1424         break;
1425     case TARGET_NR_mremap:
1426         ret = get_errno((long)mremap((void *)arg1, arg2, arg3, arg4));
1427         break;
1428     case TARGET_NR_msync:
1429         ret = get_errno(msync((void *)arg1, arg2, arg3));
1430         break;
1431     case TARGET_NR_mlock:
1432         ret = get_errno(mlock((void *)arg1, arg2));
1433         break;
1434     case TARGET_NR_munlock:
1435         ret = get_errno(munlock((void *)arg1, arg2));
1436         break;
1437     case TARGET_NR_mlockall:
1438         ret = get_errno(mlockall(arg1));
1439         break;
1440     case TARGET_NR_munlockall:
1441         ret = get_errno(munlockall());
1442         break;
1443     case TARGET_NR_truncate:
1444         ret = get_errno(truncate((const char *)arg1, arg2));
1445         break;
1446     case TARGET_NR_ftruncate:
1447         ret = get_errno(ftruncate(arg1, arg2));
1448         break;
1449     case TARGET_NR_fchmod:
1450         ret = get_errno(fchmod(arg1, arg2));
1451         break;
1452     case TARGET_NR_fchown:
1453         ret = get_errno(fchown(arg1, arg2, arg3));
1454         break;
1455     case TARGET_NR_getpriority:
1456         ret = get_errno(getpriority(arg1, arg2));
1457         break;
1458     case TARGET_NR_setpriority:
1459         ret = get_errno(setpriority(arg1, arg2, arg3));
1460         break;
1461     case TARGET_NR_profil:
1462         goto unimplemented;
1463     case TARGET_NR_statfs:
1464         stfs = (void *)arg2;
1465         ret = get_errno(sys_statfs((const char *)arg1, stfs));
1466     convert_statfs:
1467         if (!is_error(ret)) {
1468             tswap32s(&stfs->f_type);
1469             tswap32s(&stfs->f_bsize);
1470             tswap32s(&stfs->f_blocks);
1471             tswap32s(&stfs->f_bfree);
1472             tswap32s(&stfs->f_bavail);
1473             tswap32s(&stfs->f_files);
1474             tswap32s(&stfs->f_ffree);
1475             tswap32s(&stfs->f_fsid.val[0]);
1476             tswap32s(&stfs->f_fsid.val[1]);
1477             tswap32s(&stfs->f_namelen);
1478         }
1479         break;
1480     case TARGET_NR_fstatfs:
1481         stfs = (void *)arg2;
1482         ret = get_errno(sys_fstatfs(arg1, stfs));
1483         goto convert_statfs;
1484     case TARGET_NR_ioperm:
1485         goto unimplemented;
1486     case TARGET_NR_socketcall:
1487         ret = do_socketcall(arg1, (long *)arg2);
1488         break;
1489     case TARGET_NR_syslog:
1490         goto unimplemented;
1491     case TARGET_NR_setitimer:
1492         {
1493             struct target_itimerval *target_value = (void *)arg2;
1494             struct target_itimerval *target_ovalue = (void *)arg3;
1495             struct itimerval value, ovalue, *pvalue;
1496
1497             if (target_value) {
1498                 pvalue = &value;
1499                 target_to_host_timeval(&pvalue->it_interval, 
1500                                        &target_value->it_interval);
1501                 target_to_host_timeval(&pvalue->it_value, 
1502                                        &target_value->it_value);
1503             } else {
1504                 pvalue = NULL;
1505             }
1506             ret = get_errno(setitimer(arg1, pvalue, &ovalue));
1507             if (!is_error(ret) && target_ovalue) {
1508                 host_to_target_timeval(&target_ovalue->it_interval, 
1509                                        &ovalue.it_interval);
1510                 host_to_target_timeval(&target_ovalue->it_value, 
1511                                        &ovalue.it_value);
1512             }
1513         }
1514         break;
1515     case TARGET_NR_getitimer:
1516         {
1517             struct target_itimerval *target_value = (void *)arg2;
1518             struct itimerval value;
1519             
1520             ret = get_errno(getitimer(arg1, &value));
1521             if (!is_error(ret) && target_value) {
1522                 host_to_target_timeval(&target_value->it_interval, 
1523                                        &value.it_interval);
1524                 host_to_target_timeval(&target_value->it_value, 
1525                                        &value.it_value);
1526             }
1527         }
1528         break;
1529     case TARGET_NR_stat:
1530         ret = get_errno(stat((const char *)arg1, &st));
1531         goto do_stat;
1532     case TARGET_NR_lstat:
1533         ret = get_errno(lstat((const char *)arg1, &st));
1534         goto do_stat;
1535     case TARGET_NR_fstat:
1536         {
1537             ret = get_errno(fstat(arg1, &st));
1538         do_stat:
1539             if (!is_error(ret)) {
1540                 struct target_stat *target_st = (void *)arg2;
1541                 target_st->st_dev = tswap16(st.st_dev);
1542                 target_st->st_ino = tswapl(st.st_ino);
1543                 target_st->st_mode = tswap16(st.st_mode);
1544                 target_st->st_nlink = tswap16(st.st_nlink);
1545                 target_st->st_uid = tswap16(st.st_uid);
1546                 target_st->st_gid = tswap16(st.st_gid);
1547                 target_st->st_rdev = tswap16(st.st_rdev);
1548                 target_st->st_size = tswapl(st.st_size);
1549                 target_st->st_blksize = tswapl(st.st_blksize);
1550                 target_st->st_blocks = tswapl(st.st_blocks);
1551                 target_st->st_atime = tswapl(st.st_atime);
1552                 target_st->st_mtime = tswapl(st.st_mtime);
1553                 target_st->st_ctime = tswapl(st.st_ctime);
1554             }
1555         }
1556         break;
1557     case TARGET_NR_olduname:
1558         goto unimplemented;
1559     case TARGET_NR_iopl:
1560         goto unimplemented;
1561     case TARGET_NR_vhangup:
1562         ret = get_errno(vhangup());
1563         break;
1564     case TARGET_NR_idle:
1565         goto unimplemented;
1566     case TARGET_NR_wait4:
1567         {
1568             int status;
1569             target_long *status_ptr = (void *)arg2;
1570             struct rusage rusage, *rusage_ptr;
1571             struct target_rusage *target_rusage = (void *)arg4;
1572             if (target_rusage)
1573                 rusage_ptr = &rusage;
1574             else
1575                 rusage_ptr = NULL;
1576             ret = get_errno(wait4(arg1, &status, arg3, rusage_ptr));
1577             if (!is_error(ret)) {
1578                 if (status_ptr)
1579                     *status_ptr = tswap32(status);
1580                 if (target_rusage) {
1581                     target_rusage->ru_utime.tv_sec = tswapl(rusage.ru_utime.tv_sec);
1582                     target_rusage->ru_utime.tv_usec = tswapl(rusage.ru_utime.tv_usec);
1583                     target_rusage->ru_stime.tv_sec = tswapl(rusage.ru_stime.tv_sec);
1584                     target_rusage->ru_stime.tv_usec = tswapl(rusage.ru_stime.tv_usec);
1585                     target_rusage->ru_maxrss = tswapl(rusage.ru_maxrss);
1586                     target_rusage->ru_ixrss = tswapl(rusage.ru_ixrss);
1587                     target_rusage->ru_idrss = tswapl(rusage.ru_idrss);
1588                     target_rusage->ru_isrss = tswapl(rusage.ru_isrss);
1589                     target_rusage->ru_minflt = tswapl(rusage.ru_minflt);
1590                     target_rusage->ru_majflt = tswapl(rusage.ru_majflt);
1591                     target_rusage->ru_nswap = tswapl(rusage.ru_nswap);
1592                     target_rusage->ru_inblock = tswapl(rusage.ru_inblock);
1593                     target_rusage->ru_oublock = tswapl(rusage.ru_oublock);
1594                     target_rusage->ru_msgsnd = tswapl(rusage.ru_msgsnd);
1595                     target_rusage->ru_msgrcv = tswapl(rusage.ru_msgrcv);
1596                     target_rusage->ru_nsignals = tswapl(rusage.ru_nsignals);
1597                     target_rusage->ru_nvcsw = tswapl(rusage.ru_nvcsw);
1598                     target_rusage->ru_nivcsw = tswapl(rusage.ru_nivcsw);
1599                 }
1600             }
1601         }
1602         break;
1603     case TARGET_NR_swapoff:
1604         ret = get_errno(swapoff((const char *)arg1));
1605         break;
1606     case TARGET_NR_sysinfo:
1607         goto unimplemented;
1608     case TARGET_NR_ipc:
1609         goto unimplemented;
1610     case TARGET_NR_fsync:
1611         ret = get_errno(fsync(arg1));
1612         break;
1613     case TARGET_NR_clone:
1614         ret = get_errno(do_fork(cpu_env, arg1, arg2));
1615         break;
1616     case TARGET_NR_setdomainname:
1617         ret = get_errno(setdomainname((const char *)arg1, arg2));
1618         break;
1619     case TARGET_NR_uname:
1620         /* no need to transcode because we use the linux syscall */
1621         ret = get_errno(sys_uname((struct new_utsname *)arg1));
1622         break;
1623 #ifdef TARGET_I386
1624     case TARGET_NR_modify_ldt:
1625         ret = get_errno(do_modify_ldt(cpu_env, arg1, (void *)arg2, arg3));
1626         break;
1627     case TARGET_NR_vm86old:
1628         goto unimplemented;
1629     case TARGET_NR_vm86:
1630         ret = do_vm86(cpu_env, arg1, (void *)arg2);
1631         break;
1632 #endif
1633     case TARGET_NR_adjtimex:
1634         goto unimplemented;
1635     case TARGET_NR_create_module:
1636     case TARGET_NR_init_module:
1637     case TARGET_NR_delete_module:
1638     case TARGET_NR_get_kernel_syms:
1639         goto unimplemented;
1640     case TARGET_NR_quotactl:
1641         goto unimplemented;
1642     case TARGET_NR_getpgid:
1643         ret = get_errno(getpgid(arg1));
1644         break;
1645     case TARGET_NR_fchdir:
1646         ret = get_errno(fchdir(arg1));
1647         break;
1648     case TARGET_NR_bdflush:
1649         goto unimplemented;
1650     case TARGET_NR_sysfs:
1651         goto unimplemented;
1652     case TARGET_NR_personality:
1653         ret = get_errno(personality(arg1));
1654         break;
1655     case TARGET_NR_afs_syscall:
1656         goto unimplemented;
1657     case TARGET_NR_setfsuid:
1658         ret = get_errno(setfsuid(arg1));
1659         break;
1660     case TARGET_NR_setfsgid:
1661         ret = get_errno(setfsgid(arg1));
1662         break;
1663     case TARGET_NR__llseek:
1664         {
1665             int64_t res;
1666             ret = get_errno(_llseek(arg1, arg2, arg3, &res, arg5));
1667             *(int64_t *)arg4 = tswap64(res);
1668         }
1669         break;
1670     case TARGET_NR_getdents:
1671 #if TARGET_LONG_SIZE != 4
1672 #error not supported
1673 #endif
1674         {
1675             struct dirent *dirp = (void *)arg2;
1676             long count = arg3;
1677
1678             ret = get_errno(sys_getdents(arg1, dirp, count));
1679             if (!is_error(ret)) {
1680                 struct dirent *de;
1681                 int len = ret;
1682                 int reclen;
1683                 de = dirp;
1684                 while (len > 0) {
1685                     reclen = de->d_reclen;
1686                     if (reclen > len)
1687                         break;
1688                     de->d_reclen = tswap16(reclen);
1689                     tswapls(&de->d_ino);
1690                     tswapls(&de->d_off);
1691                     de = (struct dirent *)((char *)de + reclen);
1692                     len -= reclen;
1693                 }
1694             }
1695         }
1696         break;
1697     case TARGET_NR_getdents64:
1698         {
1699             struct dirent64 *dirp = (void *)arg2;
1700             long count = arg3;
1701             ret = get_errno(sys_getdents64(arg1, dirp, count));
1702             if (!is_error(ret)) {
1703                 struct dirent64 *de;
1704                 int len = ret;
1705                 int reclen;
1706                 de = dirp;
1707                 while (len > 0) {
1708                     reclen = de->d_reclen;
1709                     if (reclen > len)
1710                         break;
1711                     de->d_reclen = tswap16(reclen);
1712                     tswap64s(&de->d_ino);
1713                     tswap64s(&de->d_off);
1714                     de = (struct dirent64 *)((char *)de + reclen);
1715                     len -= reclen;
1716                 }
1717             }
1718         }
1719         break;
1720     case TARGET_NR__newselect:
1721         ret = do_select(arg1, (void *)arg2, (void *)arg3, (void *)arg4, 
1722                         (void *)arg5);
1723         break;
1724     case TARGET_NR_poll:
1725         {
1726             struct target_pollfd *target_pfd = (void *)arg1;
1727             unsigned int nfds = arg2;
1728             int timeout = arg3;
1729             struct pollfd *pfd;
1730             int i;
1731
1732             pfd = alloca(sizeof(struct pollfd) * nfds);
1733             for(i = 0; i < nfds; i++) {
1734                 pfd[i].fd = tswap32(target_pfd[i].fd);
1735                 pfd[i].events = tswap16(target_pfd[i].events);
1736             }
1737             ret = get_errno(poll(pfd, nfds, timeout));
1738             if (!is_error(ret)) {
1739                 for(i = 0; i < nfds; i++) {
1740                     target_pfd[i].revents = tswap16(pfd[i].revents);
1741                 }
1742             }
1743         }
1744         break;
1745     case TARGET_NR_flock:
1746         /* NOTE: the flock constant seems to be the same for every
1747            Linux platform */
1748         ret = get_errno(flock(arg1, arg2));
1749         break;
1750     case TARGET_NR_readv:
1751         {
1752             int count = arg3;
1753             int i;
1754             struct iovec *vec;
1755             struct target_iovec *target_vec = (void *)arg2;
1756
1757             vec = alloca(count * sizeof(struct iovec));
1758             for(i = 0;i < count; i++) {
1759                 vec[i].iov_base = (void *)tswapl(target_vec[i].iov_base);
1760                 vec[i].iov_len = tswapl(target_vec[i].iov_len);
1761             }
1762             ret = get_errno(readv(arg1, vec, count));
1763         }
1764         break;
1765     case TARGET_NR_writev:
1766         {
1767             int count = arg3;
1768             int i;
1769             struct iovec *vec;
1770             struct target_iovec *target_vec = (void *)arg2;
1771
1772             vec = alloca(count * sizeof(struct iovec));
1773             for(i = 0;i < count; i++) {
1774                 vec[i].iov_base = (void *)tswapl(target_vec[i].iov_base);
1775                 vec[i].iov_len = tswapl(target_vec[i].iov_len);
1776             }
1777             ret = get_errno(writev(arg1, vec, count));
1778         }
1779         break;
1780     case TARGET_NR_getsid:
1781         ret = get_errno(getsid(arg1));
1782         break;
1783     case TARGET_NR_fdatasync:
1784         ret = get_errno(fdatasync(arg1));
1785         break;
1786     case TARGET_NR__sysctl:
1787         goto unimplemented;
1788     case TARGET_NR_sched_setparam:
1789         {
1790             struct sched_param *target_schp = (void *)arg2;
1791             struct sched_param schp;
1792             schp.sched_priority = tswap32(target_schp->sched_priority);
1793             ret = get_errno(sched_setparam(arg1, &schp));
1794         }
1795         break;
1796     case TARGET_NR_sched_getparam:
1797         {
1798             struct sched_param *target_schp = (void *)arg2;
1799             struct sched_param schp;
1800             ret = get_errno(sched_getparam(arg1, &schp));
1801             if (!is_error(ret)) {
1802                 target_schp->sched_priority = tswap32(schp.sched_priority);
1803             }
1804         }
1805         break;
1806     case TARGET_NR_sched_setscheduler:
1807         {
1808             struct sched_param *target_schp = (void *)arg3;
1809             struct sched_param schp;
1810             schp.sched_priority = tswap32(target_schp->sched_priority);
1811             ret = get_errno(sched_setscheduler(arg1, arg2, &schp));
1812         }
1813         break;
1814     case TARGET_NR_sched_getscheduler:
1815         ret = get_errno(sched_getscheduler(arg1));
1816         break;
1817     case TARGET_NR_sched_yield:
1818         ret = get_errno(sched_yield());
1819         break;
1820     case TARGET_NR_sched_get_priority_max:
1821         ret = get_errno(sched_get_priority_max(arg1));
1822         break;
1823     case TARGET_NR_sched_get_priority_min:
1824         ret = get_errno(sched_get_priority_min(arg1));
1825         break;
1826     case TARGET_NR_sched_rr_get_interval:
1827         {
1828             struct target_timespec *target_ts = (void *)arg2;
1829             struct timespec ts;
1830             ret = get_errno(sched_rr_get_interval(arg1, &ts));
1831             if (!is_error(ret)) {
1832                 target_ts->tv_sec = tswapl(ts.tv_sec);
1833                 target_ts->tv_nsec = tswapl(ts.tv_nsec);
1834             }
1835         }
1836         break;
1837     case TARGET_NR_nanosleep:
1838         {
1839             struct target_timespec *target_req = (void *)arg1;
1840             struct target_timespec *target_rem = (void *)arg2;
1841             struct timespec req, rem;
1842             req.tv_sec = tswapl(target_req->tv_sec);
1843             req.tv_nsec = tswapl(target_req->tv_nsec);
1844             ret = get_errno(nanosleep(&req, &rem));
1845             if (target_rem) {
1846                 target_rem->tv_sec = tswapl(rem.tv_sec);
1847                 target_rem->tv_nsec = tswapl(rem.tv_nsec);
1848             }
1849         }
1850         break;
1851     case TARGET_NR_setresuid:
1852         ret = get_errno(setresuid(low2highuid(arg1), 
1853                                   low2highuid(arg2), 
1854                                   low2highuid(arg3)));
1855         break;
1856     case TARGET_NR_getresuid:
1857         {
1858             int ruid, euid, suid;
1859             ret = get_errno(getresuid(&ruid, &euid, &suid));
1860             if (!is_error(ret)) {
1861                 *(uint16_t *)arg1 = tswap16(high2lowuid(ruid));
1862                 *(uint16_t *)arg2 = tswap16(high2lowuid(euid));
1863                 *(uint16_t *)arg3 = tswap16(high2lowuid(suid));
1864             }
1865         }
1866         break;
1867     case TARGET_NR_setresgid:
1868         ret = get_errno(setresgid(low2highgid(arg1), 
1869                                   low2highgid(arg2), 
1870                                   low2highgid(arg3)));
1871         break;
1872     case TARGET_NR_getresgid:
1873         {
1874             int rgid, egid, sgid;
1875             ret = get_errno(getresgid(&rgid, &egid, &sgid));
1876             if (!is_error(ret)) {
1877                 *(uint16_t *)arg1 = high2lowgid(tswap16(rgid));
1878                 *(uint16_t *)arg2 = high2lowgid(tswap16(egid));
1879                 *(uint16_t *)arg3 = high2lowgid(tswap16(sgid));
1880             }
1881         }
1882         break;
1883     case TARGET_NR_query_module:
1884         goto unimplemented;
1885     case TARGET_NR_nfsservctl:
1886         goto unimplemented;
1887     case TARGET_NR_prctl:
1888         goto unimplemented;
1889     case TARGET_NR_pread:
1890         goto unimplemented;
1891     case TARGET_NR_pwrite:
1892         goto unimplemented;
1893     case TARGET_NR_chown:
1894         ret = get_errno(chown((const char *)arg1, arg2, arg3));
1895         break;
1896     case TARGET_NR_getcwd:
1897         ret = get_errno(sys_getcwd1((char *)arg1, arg2));
1898         break;
1899     case TARGET_NR_capget:
1900         goto unimplemented;
1901     case TARGET_NR_capset:
1902         goto unimplemented;
1903     case TARGET_NR_sigaltstack:
1904         goto unimplemented;
1905     case TARGET_NR_sendfile:
1906         goto unimplemented;
1907     case TARGET_NR_getpmsg:
1908         goto unimplemented;
1909     case TARGET_NR_putpmsg:
1910         goto unimplemented;
1911     case TARGET_NR_vfork:
1912         ret = get_errno(do_fork(cpu_env, CLONE_VFORK | CLONE_VM | SIGCHLD, 0));
1913         break;
1914     case TARGET_NR_ugetrlimit:
1915         goto unimplemented;
1916     case TARGET_NR_truncate64:
1917         goto unimplemented;
1918     case TARGET_NR_ftruncate64:
1919         goto unimplemented;
1920     case TARGET_NR_stat64:
1921         ret = get_errno(stat((const char *)arg1, &st));
1922         goto do_stat64;
1923     case TARGET_NR_lstat64:
1924         ret = get_errno(lstat((const char *)arg1, &st));
1925         goto do_stat64;
1926     case TARGET_NR_fstat64:
1927         {
1928             ret = get_errno(fstat(arg1, &st));
1929         do_stat64:
1930             if (!is_error(ret)) {
1931                 struct target_stat64 *target_st = (void *)arg2;
1932                 target_st->st_dev = tswap16(st.st_dev);
1933                 target_st->st_ino = tswapl(st.st_ino);
1934                 target_st->st_mode = tswap16(st.st_mode);
1935                 target_st->st_nlink = tswap16(st.st_nlink);
1936                 target_st->st_uid = tswap16(st.st_uid);
1937                 target_st->st_gid = tswap16(st.st_gid);
1938                 target_st->st_rdev = tswap16(st.st_rdev);
1939                 /* XXX: better use of kernel struct */
1940                 target_st->st_size = tswapl(st.st_size);
1941                 target_st->st_blksize = tswapl(st.st_blksize);
1942                 target_st->st_blocks = tswapl(st.st_blocks);
1943                 target_st->st_atime = tswapl(st.st_atime);
1944                 target_st->st_mtime = tswapl(st.st_mtime);
1945                 target_st->st_ctime = tswapl(st.st_ctime);
1946             }
1947         }
1948         break;
1949
1950     case TARGET_NR_lchown32:
1951         ret = get_errno(lchown((const char *)arg1, arg2, arg3));
1952         break;
1953     case TARGET_NR_getuid32:
1954         ret = get_errno(getuid());
1955         break;
1956     case TARGET_NR_getgid32:
1957         ret = get_errno(getgid());
1958         break;
1959     case TARGET_NR_geteuid32:
1960         ret = get_errno(geteuid());
1961         break;
1962     case TARGET_NR_getegid32:
1963         ret = get_errno(getegid());
1964         break;
1965     case TARGET_NR_setreuid32:
1966         ret = get_errno(setreuid(arg1, arg2));
1967         break;
1968     case TARGET_NR_setregid32:
1969         ret = get_errno(setregid(arg1, arg2));
1970         break;
1971     case TARGET_NR_getgroups32:
1972         goto unimplemented;
1973     case TARGET_NR_setgroups32:
1974         goto unimplemented;
1975     case TARGET_NR_fchown32:
1976         ret = get_errno(fchown(arg1, arg2, arg3));
1977         break;
1978     case TARGET_NR_setresuid32:
1979         ret = get_errno(setresuid(arg1, arg2, arg3));
1980         break;
1981     case TARGET_NR_getresuid32:
1982         {
1983             int ruid, euid, suid;
1984             ret = get_errno(getresuid(&ruid, &euid, &suid));
1985             if (!is_error(ret)) {
1986                 *(uint32_t *)arg1 = tswap32(ruid);
1987                 *(uint32_t *)arg2 = tswap32(euid);
1988                 *(uint32_t *)arg3 = tswap32(suid);
1989             }
1990         }
1991         break;
1992     case TARGET_NR_setresgid32:
1993         ret = get_errno(setresgid(arg1, arg2, arg3));
1994         break;
1995     case TARGET_NR_getresgid32:
1996         {
1997             int rgid, egid, sgid;
1998             ret = get_errno(getresgid(&rgid, &egid, &sgid));
1999             if (!is_error(ret)) {
2000                 *(uint32_t *)arg1 = tswap32(rgid);
2001                 *(uint32_t *)arg2 = tswap32(egid);
2002                 *(uint32_t *)arg3 = tswap32(sgid);
2003             }
2004         }
2005         break;
2006     case TARGET_NR_chown32:
2007         ret = get_errno(chown((const char *)arg1, arg2, arg3));
2008         break;
2009     case TARGET_NR_setuid32:
2010         ret = get_errno(setuid(arg1));
2011         break;
2012     case TARGET_NR_setgid32:
2013         ret = get_errno(setgid(arg1));
2014         break;
2015     case TARGET_NR_setfsuid32:
2016         ret = get_errno(setfsuid(arg1));
2017         break;
2018     case TARGET_NR_setfsgid32:
2019         ret = get_errno(setfsgid(arg1));
2020         break;
2021     case TARGET_NR_pivot_root:
2022         goto unimplemented;
2023     case TARGET_NR_mincore:
2024         goto unimplemented;
2025     case TARGET_NR_madvise:
2026         goto unimplemented;
2027 #if TARGET_LONG_BITS == 32
2028     case TARGET_NR_fcntl64:
2029         switch(arg2) {
2030         case F_GETLK64:
2031         case F_SETLK64:
2032         case F_SETLKW64:
2033             goto unimplemented;
2034         default:
2035             ret = get_errno(fcntl(arg1, arg2, arg3));
2036             break;
2037         }
2038         break;
2039 #endif
2040     case TARGET_NR_security:
2041         goto unimplemented;
2042     case TARGET_NR_gettid:
2043         ret = get_errno(gettid());
2044         break;
2045     case TARGET_NR_readahead:
2046         goto unimplemented;
2047     case TARGET_NR_setxattr:
2048     case TARGET_NR_lsetxattr:
2049     case TARGET_NR_fsetxattr:
2050     case TARGET_NR_getxattr:
2051     case TARGET_NR_lgetxattr:
2052     case TARGET_NR_fgetxattr:
2053     case TARGET_NR_listxattr:
2054     case TARGET_NR_llistxattr:
2055     case TARGET_NR_flistxattr:
2056     case TARGET_NR_removexattr:
2057     case TARGET_NR_lremovexattr:
2058     case TARGET_NR_fremovexattr:
2059         goto unimplemented_nowarn;
2060     case TARGET_NR_set_thread_area:
2061     case TARGET_NR_get_thread_area:
2062         goto unimplemented_nowarn;
2063     default:
2064     unimplemented:
2065         gemu_log("qemu: Unsupported syscall: %d\n", num);
2066     unimplemented_nowarn:
2067         ret = -ENOSYS;
2068         break;
2069     }
2070  fail:
2071     return ret;
2072 }
2073