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