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