Improved terminal emulation (Piotr Esden-Tempski).
[qemu/mini2440.git] / linux-user / syscall.c
blobab7846d7ac96f3746c69176daf22006db2ab0e54
1 /*
2 * Linux syscalls
3 *
4 * Copyright (c) 2003 Fabrice Bellard
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.
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.
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.
20 #include <stdlib.h>
21 #include <stdio.h>
22 #include <stdarg.h>
23 #include <string.h>
24 #include <elf.h>
25 #include <endian.h>
26 #include <errno.h>
27 #include <unistd.h>
28 #include <fcntl.h>
29 #include <time.h>
30 #include <sys/types.h>
31 #include <sys/wait.h>
32 #include <sys/time.h>
33 #include <sys/stat.h>
34 #include <sys/mount.h>
35 #include <sys/resource.h>
36 #include <sys/mman.h>
37 #include <sys/swap.h>
38 #include <signal.h>
39 #include <sched.h>
40 #include <sys/socket.h>
41 #include <sys/uio.h>
42 #include <sys/poll.h>
43 #include <sys/times.h>
44 #include <sys/shm.h>
45 #include <sys/statfs.h>
46 #include <utime.h>
47 #include <sys/sysinfo.h>
48 //#include <sys/user.h>
49 #include <netinet/ip.h>
50 #include <netinet/tcp.h>
52 #define termios host_termios
53 #define winsize host_winsize
54 #define termio host_termio
55 #define sgttyb host_sgttyb /* same as target */
56 #define tchars host_tchars /* same as target */
57 #define ltchars host_ltchars /* same as target */
59 #include <linux/termios.h>
60 #include <linux/unistd.h>
61 #include <linux/utsname.h>
62 #include <linux/cdrom.h>
63 #include <linux/hdreg.h>
64 #include <linux/soundcard.h>
65 #include <linux/dirent.h>
66 #include <linux/kd.h>
68 #include "qemu.h"
70 //#define DEBUG
72 #if defined(TARGET_I386) || defined(TARGET_ARM) || defined(TARGET_SPARC)
73 /* 16 bit uid wrappers emulation */
74 #define USE_UID16
75 #endif
77 //#include <linux/msdos_fs.h>
78 #define VFAT_IOCTL_READDIR_BOTH _IOR('r', 1, struct dirent [2])
79 #define VFAT_IOCTL_READDIR_SHORT _IOR('r', 2, struct dirent [2])
82 #if defined(__powerpc__)
83 #undef __syscall_nr
84 #undef __sc_loadargs_0
85 #undef __sc_loadargs_1
86 #undef __sc_loadargs_2
87 #undef __sc_loadargs_3
88 #undef __sc_loadargs_4
89 #undef __sc_loadargs_5
90 #undef __sc_asm_input_0
91 #undef __sc_asm_input_1
92 #undef __sc_asm_input_2
93 #undef __sc_asm_input_3
94 #undef __sc_asm_input_4
95 #undef __sc_asm_input_5
96 #undef _syscall0
97 #undef _syscall1
98 #undef _syscall2
99 #undef _syscall3
100 #undef _syscall4
101 #undef _syscall5
103 /* need to redefine syscalls as Linux kernel defines are incorrect for
104 the clobber list */
105 /* On powerpc a system call basically clobbers the same registers like a
106 * function call, with the exception of LR (which is needed for the
107 * "sc; bnslr" sequence) and CR (where only CR0.SO is clobbered to signal
108 * an error return status).
111 #define __syscall_nr(nr, type, name, args...) \
112 unsigned long __sc_ret, __sc_err; \
114 register unsigned long __sc_0 __asm__ ("r0"); \
115 register unsigned long __sc_3 __asm__ ("r3"); \
116 register unsigned long __sc_4 __asm__ ("r4"); \
117 register unsigned long __sc_5 __asm__ ("r5"); \
118 register unsigned long __sc_6 __asm__ ("r6"); \
119 register unsigned long __sc_7 __asm__ ("r7"); \
121 __sc_loadargs_##nr(name, args); \
122 __asm__ __volatile__ \
123 ("sc \n\t" \
124 "mfcr %0 " \
125 : "=&r" (__sc_0), \
126 "=&r" (__sc_3), "=&r" (__sc_4), \
127 "=&r" (__sc_5), "=&r" (__sc_6), \
128 "=&r" (__sc_7) \
129 : __sc_asm_input_##nr \
130 : "cr0", "ctr", "memory", \
131 "r8", "r9", "r10","r11", "r12"); \
132 __sc_ret = __sc_3; \
133 __sc_err = __sc_0; \
135 if (__sc_err & 0x10000000) \
137 errno = __sc_ret; \
138 __sc_ret = -1; \
140 return (type) __sc_ret
142 #define __sc_loadargs_0(name, dummy...) \
143 __sc_0 = __NR_##name
144 #define __sc_loadargs_1(name, arg1) \
145 __sc_loadargs_0(name); \
146 __sc_3 = (unsigned long) (arg1)
147 #define __sc_loadargs_2(name, arg1, arg2) \
148 __sc_loadargs_1(name, arg1); \
149 __sc_4 = (unsigned long) (arg2)
150 #define __sc_loadargs_3(name, arg1, arg2, arg3) \
151 __sc_loadargs_2(name, arg1, arg2); \
152 __sc_5 = (unsigned long) (arg3)
153 #define __sc_loadargs_4(name, arg1, arg2, arg3, arg4) \
154 __sc_loadargs_3(name, arg1, arg2, arg3); \
155 __sc_6 = (unsigned long) (arg4)
156 #define __sc_loadargs_5(name, arg1, arg2, arg3, arg4, arg5) \
157 __sc_loadargs_4(name, arg1, arg2, arg3, arg4); \
158 __sc_7 = (unsigned long) (arg5)
160 #define __sc_asm_input_0 "0" (__sc_0)
161 #define __sc_asm_input_1 __sc_asm_input_0, "1" (__sc_3)
162 #define __sc_asm_input_2 __sc_asm_input_1, "2" (__sc_4)
163 #define __sc_asm_input_3 __sc_asm_input_2, "3" (__sc_5)
164 #define __sc_asm_input_4 __sc_asm_input_3, "4" (__sc_6)
165 #define __sc_asm_input_5 __sc_asm_input_4, "5" (__sc_7)
167 #define _syscall0(type,name) \
168 type name(void) \
170 __syscall_nr(0, type, name); \
173 #define _syscall1(type,name,type1,arg1) \
174 type name(type1 arg1) \
176 __syscall_nr(1, type, name, arg1); \
179 #define _syscall2(type,name,type1,arg1,type2,arg2) \
180 type name(type1 arg1, type2 arg2) \
182 __syscall_nr(2, type, name, arg1, arg2); \
185 #define _syscall3(type,name,type1,arg1,type2,arg2,type3,arg3) \
186 type name(type1 arg1, type2 arg2, type3 arg3) \
188 __syscall_nr(3, type, name, arg1, arg2, arg3); \
191 #define _syscall4(type,name,type1,arg1,type2,arg2,type3,arg3,type4,arg4) \
192 type name(type1 arg1, type2 arg2, type3 arg3, type4 arg4) \
194 __syscall_nr(4, type, name, arg1, arg2, arg3, arg4); \
197 #define _syscall5(type,name,type1,arg1,type2,arg2,type3,arg3,type4,arg4,type5,arg5) \
198 type name(type1 arg1, type2 arg2, type3 arg3, type4 arg4, type5 arg5) \
200 __syscall_nr(5, type, name, arg1, arg2, arg3, arg4, arg5); \
202 #endif
204 #define __NR_sys_uname __NR_uname
205 #define __NR_sys_getcwd1 __NR_getcwd
206 #define __NR_sys_getdents __NR_getdents
207 #define __NR_sys_getdents64 __NR_getdents64
208 #define __NR_sys_rt_sigqueueinfo __NR_rt_sigqueueinfo
210 #if defined(__alpha__) || defined (__ia64__) || defined(__x86_64__)
211 #define __NR__llseek __NR_lseek
212 #endif
214 #ifdef __NR_gettid
215 _syscall0(int, gettid)
216 #else
217 static int gettid(void) {
218 return -ENOSYS;
220 #endif
221 _syscall1(int,sys_uname,struct new_utsname *,buf)
222 _syscall2(int,sys_getcwd1,char *,buf,size_t,size)
223 _syscall3(int, sys_getdents, uint, fd, struct dirent *, dirp, uint, count);
224 _syscall3(int, sys_getdents64, uint, fd, struct dirent64 *, dirp, uint, count);
225 _syscall5(int, _llseek, uint, fd, ulong, hi, ulong, lo,
226 loff_t *, res, uint, wh);
227 _syscall3(int,sys_rt_sigqueueinfo,int,pid,int,sig,siginfo_t *,uinfo)
228 #ifdef __NR_exit_group
229 _syscall1(int,exit_group,int,error_code)
230 #endif
232 extern int personality(int);
233 extern int flock(int, int);
234 extern int setfsuid(int);
235 extern int setfsgid(int);
236 extern int setresuid(uid_t, uid_t, uid_t);
237 extern int getresuid(uid_t *, uid_t *, uid_t *);
238 extern int setresgid(gid_t, gid_t, gid_t);
239 extern int getresgid(gid_t *, gid_t *, gid_t *);
240 extern int setgroups(int, gid_t *);
242 static inline long get_errno(long ret)
244 if (ret == -1)
245 return -errno;
246 else
247 return ret;
250 static inline int is_error(long ret)
252 return (unsigned long)ret >= (unsigned long)(-4096);
255 static char *target_brk;
256 static char *target_original_brk;
258 void target_set_brk(char *new_brk)
260 target_brk = new_brk;
261 target_original_brk = new_brk;
264 long do_brk(char *new_brk)
266 char *brk_page;
267 long mapped_addr;
268 int new_alloc_size;
270 if (!new_brk)
271 return (long)target_brk;
272 if (new_brk < target_original_brk)
273 return -ENOMEM;
275 brk_page = (char *)HOST_PAGE_ALIGN((unsigned long)target_brk);
277 /* If the new brk is less than this, set it and we're done... */
278 if (new_brk < brk_page) {
279 target_brk = new_brk;
280 return (long)target_brk;
283 /* We need to allocate more memory after the brk... */
284 new_alloc_size = HOST_PAGE_ALIGN(new_brk - brk_page + 1);
285 mapped_addr = get_errno(target_mmap((unsigned long)brk_page, new_alloc_size,
286 PROT_READ|PROT_WRITE,
287 MAP_ANON|MAP_FIXED|MAP_PRIVATE, 0, 0));
288 if (is_error(mapped_addr)) {
289 return mapped_addr;
290 } else {
291 target_brk = new_brk;
292 return (long)target_brk;
296 static inline fd_set *target_to_host_fds(fd_set *fds,
297 target_long *target_fds, int n)
299 #if !defined(BSWAP_NEEDED) && !defined(WORDS_BIGENDIAN)
300 return (fd_set *)target_fds;
301 #else
302 int i, b;
303 if (target_fds) {
304 FD_ZERO(fds);
305 for(i = 0;i < n; i++) {
306 b = (tswapl(target_fds[i / TARGET_LONG_BITS]) >>
307 (i & (TARGET_LONG_BITS - 1))) & 1;
308 if (b)
309 FD_SET(i, fds);
311 return fds;
312 } else {
313 return NULL;
315 #endif
318 static inline void host_to_target_fds(target_long *target_fds,
319 fd_set *fds, int n)
321 #if !defined(BSWAP_NEEDED) && !defined(WORDS_BIGENDIAN)
322 /* nothing to do */
323 #else
324 int i, nw, j, k;
325 target_long v;
327 if (target_fds) {
328 nw = (n + TARGET_LONG_BITS - 1) / TARGET_LONG_BITS;
329 k = 0;
330 for(i = 0;i < nw; i++) {
331 v = 0;
332 for(j = 0; j < TARGET_LONG_BITS; j++) {
333 v |= ((FD_ISSET(k, fds) != 0) << j);
334 k++;
336 target_fds[i] = tswapl(v);
339 #endif
342 #if defined(__alpha__)
343 #define HOST_HZ 1024
344 #else
345 #define HOST_HZ 100
346 #endif
348 static inline long host_to_target_clock_t(long ticks)
350 #if HOST_HZ == TARGET_HZ
351 return ticks;
352 #else
353 return ((int64_t)ticks * TARGET_HZ) / HOST_HZ;
354 #endif
357 static inline void host_to_target_rusage(struct target_rusage *target_rusage,
358 const struct rusage *rusage)
360 target_rusage->ru_utime.tv_sec = tswapl(rusage->ru_utime.tv_sec);
361 target_rusage->ru_utime.tv_usec = tswapl(rusage->ru_utime.tv_usec);
362 target_rusage->ru_stime.tv_sec = tswapl(rusage->ru_stime.tv_sec);
363 target_rusage->ru_stime.tv_usec = tswapl(rusage->ru_stime.tv_usec);
364 target_rusage->ru_maxrss = tswapl(rusage->ru_maxrss);
365 target_rusage->ru_ixrss = tswapl(rusage->ru_ixrss);
366 target_rusage->ru_idrss = tswapl(rusage->ru_idrss);
367 target_rusage->ru_isrss = tswapl(rusage->ru_isrss);
368 target_rusage->ru_minflt = tswapl(rusage->ru_minflt);
369 target_rusage->ru_majflt = tswapl(rusage->ru_majflt);
370 target_rusage->ru_nswap = tswapl(rusage->ru_nswap);
371 target_rusage->ru_inblock = tswapl(rusage->ru_inblock);
372 target_rusage->ru_oublock = tswapl(rusage->ru_oublock);
373 target_rusage->ru_msgsnd = tswapl(rusage->ru_msgsnd);
374 target_rusage->ru_msgrcv = tswapl(rusage->ru_msgrcv);
375 target_rusage->ru_nsignals = tswapl(rusage->ru_nsignals);
376 target_rusage->ru_nvcsw = tswapl(rusage->ru_nvcsw);
377 target_rusage->ru_nivcsw = tswapl(rusage->ru_nivcsw);
380 static inline void target_to_host_timeval(struct timeval *tv,
381 const struct target_timeval *target_tv)
383 tv->tv_sec = tswapl(target_tv->tv_sec);
384 tv->tv_usec = tswapl(target_tv->tv_usec);
387 static inline void host_to_target_timeval(struct target_timeval *target_tv,
388 const struct timeval *tv)
390 target_tv->tv_sec = tswapl(tv->tv_sec);
391 target_tv->tv_usec = tswapl(tv->tv_usec);
395 static long do_select(long n,
396 target_long *target_rfds, target_long *target_wfds,
397 target_long *target_efds, struct target_timeval *target_tv)
399 fd_set rfds, wfds, efds;
400 fd_set *rfds_ptr, *wfds_ptr, *efds_ptr;
401 struct timeval tv, *tv_ptr;
402 long ret;
404 rfds_ptr = target_to_host_fds(&rfds, target_rfds, n);
405 wfds_ptr = target_to_host_fds(&wfds, target_wfds, n);
406 efds_ptr = target_to_host_fds(&efds, target_efds, n);
408 if (target_tv) {
409 target_to_host_timeval(&tv, target_tv);
410 tv_ptr = &tv;
411 } else {
412 tv_ptr = NULL;
414 ret = get_errno(select(n, rfds_ptr, wfds_ptr, efds_ptr, tv_ptr));
415 if (!is_error(ret)) {
416 host_to_target_fds(target_rfds, rfds_ptr, n);
417 host_to_target_fds(target_wfds, wfds_ptr, n);
418 host_to_target_fds(target_efds, efds_ptr, n);
420 if (target_tv) {
421 host_to_target_timeval(target_tv, &tv);
424 return ret;
427 static inline void target_to_host_sockaddr(struct sockaddr *addr,
428 struct target_sockaddr *target_addr,
429 socklen_t len)
431 memcpy(addr, target_addr, len);
432 addr->sa_family = tswap16(target_addr->sa_family);
435 static inline void host_to_target_sockaddr(struct target_sockaddr *target_addr,
436 struct sockaddr *addr,
437 socklen_t len)
439 memcpy(target_addr, addr, len);
440 target_addr->sa_family = tswap16(addr->sa_family);
443 static inline void target_to_host_cmsg(struct msghdr *msgh,
444 struct target_msghdr *target_msgh)
446 struct cmsghdr *cmsg = CMSG_FIRSTHDR(msgh);
447 struct target_cmsghdr *target_cmsg = TARGET_CMSG_FIRSTHDR(target_msgh);
448 socklen_t space = 0;
450 while (cmsg && target_cmsg) {
451 void *data = CMSG_DATA(cmsg);
452 void *target_data = TARGET_CMSG_DATA(target_cmsg);
454 int len = tswapl(target_cmsg->cmsg_len)
455 - TARGET_CMSG_ALIGN(sizeof (struct target_cmsghdr));
457 space += CMSG_SPACE(len);
458 if (space > msgh->msg_controllen) {
459 space -= CMSG_SPACE(len);
460 gemu_log("Host cmsg overflow\n");
461 break;
464 cmsg->cmsg_level = tswap32(target_cmsg->cmsg_level);
465 cmsg->cmsg_type = tswap32(target_cmsg->cmsg_type);
466 cmsg->cmsg_len = CMSG_LEN(len);
468 if (cmsg->cmsg_level != SOL_SOCKET || cmsg->cmsg_type != SCM_RIGHTS) {
469 gemu_log("Unsupported ancillary data: %d/%d\n", cmsg->cmsg_level, cmsg->cmsg_type);
470 memcpy(data, target_data, len);
471 } else {
472 int *fd = (int *)data;
473 int *target_fd = (int *)target_data;
474 int i, numfds = len / sizeof(int);
476 for (i = 0; i < numfds; i++)
477 fd[i] = tswap32(target_fd[i]);
480 cmsg = CMSG_NXTHDR(msgh, cmsg);
481 target_cmsg = TARGET_CMSG_NXTHDR(target_msgh, target_cmsg);
484 msgh->msg_controllen = space;
487 static inline void host_to_target_cmsg(struct target_msghdr *target_msgh,
488 struct msghdr *msgh)
490 struct cmsghdr *cmsg = CMSG_FIRSTHDR(msgh);
491 struct target_cmsghdr *target_cmsg = TARGET_CMSG_FIRSTHDR(target_msgh);
492 socklen_t space = 0;
494 while (cmsg && target_cmsg) {
495 void *data = CMSG_DATA(cmsg);
496 void *target_data = TARGET_CMSG_DATA(target_cmsg);
498 int len = cmsg->cmsg_len - CMSG_ALIGN(sizeof (struct cmsghdr));
500 space += TARGET_CMSG_SPACE(len);
501 if (space > tswapl(target_msgh->msg_controllen)) {
502 space -= TARGET_CMSG_SPACE(len);
503 gemu_log("Target cmsg overflow\n");
504 break;
507 target_cmsg->cmsg_level = tswap32(cmsg->cmsg_level);
508 target_cmsg->cmsg_type = tswap32(cmsg->cmsg_type);
509 target_cmsg->cmsg_len = tswapl(TARGET_CMSG_LEN(len));
511 if (cmsg->cmsg_level != SOL_SOCKET || cmsg->cmsg_type != SCM_RIGHTS) {
512 gemu_log("Unsupported ancillary data: %d/%d\n", cmsg->cmsg_level, cmsg->cmsg_type);
513 memcpy(target_data, data, len);
514 } else {
515 int *fd = (int *)data;
516 int *target_fd = (int *)target_data;
517 int i, numfds = len / sizeof(int);
519 for (i = 0; i < numfds; i++)
520 target_fd[i] = tswap32(fd[i]);
523 cmsg = CMSG_NXTHDR(msgh, cmsg);
524 target_cmsg = TARGET_CMSG_NXTHDR(target_msgh, target_cmsg);
527 msgh->msg_controllen = tswapl(space);
530 static long do_setsockopt(int sockfd, int level, int optname,
531 void *optval, socklen_t optlen)
533 int val, ret;
535 switch(level) {
536 case SOL_TCP:
537 /* TCP options all take an 'int' value. */
538 if (optlen < sizeof(uint32_t))
539 return -EINVAL;
541 if (get_user(val, (uint32_t *)optval))
542 return -EFAULT;
543 ret = get_errno(setsockopt(sockfd, level, optname, &val, sizeof(val)));
544 break;
545 case SOL_IP:
546 switch(optname) {
547 case IP_TOS:
548 case IP_TTL:
549 case IP_HDRINCL:
550 case IP_ROUTER_ALERT:
551 case IP_RECVOPTS:
552 case IP_RETOPTS:
553 case IP_PKTINFO:
554 case IP_MTU_DISCOVER:
555 case IP_RECVERR:
556 case IP_RECVTOS:
557 #ifdef IP_FREEBIND
558 case IP_FREEBIND:
559 #endif
560 case IP_MULTICAST_TTL:
561 case IP_MULTICAST_LOOP:
562 val = 0;
563 if (optlen >= sizeof(uint32_t)) {
564 if (get_user(val, (uint32_t *)optval))
565 return -EFAULT;
566 } else if (optlen >= 1) {
567 if (get_user(val, (uint8_t *)optval))
568 return -EFAULT;
570 ret = get_errno(setsockopt(sockfd, level, optname, &val, sizeof(val)));
571 break;
572 default:
573 goto unimplemented;
575 break;
576 case SOL_SOCKET:
577 switch (optname) {
578 /* Options with 'int' argument. */
579 case SO_DEBUG:
580 case SO_REUSEADDR:
581 case SO_TYPE:
582 case SO_ERROR:
583 case SO_DONTROUTE:
584 case SO_BROADCAST:
585 case SO_SNDBUF:
586 case SO_RCVBUF:
587 case SO_KEEPALIVE:
588 case SO_OOBINLINE:
589 case SO_NO_CHECK:
590 case SO_PRIORITY:
591 #ifdef SO_BSDCOMPAT
592 case SO_BSDCOMPAT:
593 #endif
594 case SO_PASSCRED:
595 case SO_TIMESTAMP:
596 case SO_RCVLOWAT:
597 case SO_RCVTIMEO:
598 case SO_SNDTIMEO:
599 if (optlen < sizeof(uint32_t))
600 return -EINVAL;
601 if (get_user(val, (uint32_t *)optval))
602 return -EFAULT;
603 ret = get_errno(setsockopt(sockfd, level, optname, &val, sizeof(val)));
604 break;
605 default:
606 goto unimplemented;
608 break;
609 default:
610 unimplemented:
611 gemu_log("Unsupported setsockopt level=%d optname=%d \n", level, optname);
612 ret = -ENOSYS;
614 return ret;
617 static long do_getsockopt(int sockfd, int level, int optname,
618 void *optval, socklen_t *optlen)
620 int len, lv, val, ret;
622 switch(level) {
623 case SOL_SOCKET:
624 switch (optname) {
625 case SO_LINGER:
626 case SO_RCVTIMEO:
627 case SO_SNDTIMEO:
628 case SO_PEERCRED:
629 case SO_PEERNAME:
630 /* These don't just return a single integer */
631 goto unimplemented;
632 default:
633 goto int_case;
635 break;
636 case SOL_TCP:
637 /* TCP options all take an 'int' value. */
638 int_case:
639 if (get_user(len, optlen))
640 return -EFAULT;
641 if (len < 0)
642 return -EINVAL;
643 lv = sizeof(int);
644 ret = get_errno(getsockopt(sockfd, level, optname, &val, &lv));
645 if (ret < 0)
646 return ret;
647 val = tswap32(val);
648 if (len > lv)
649 len = lv;
650 if (copy_to_user(optval, &val, len))
651 return -EFAULT;
652 if (put_user(len, optlen))
653 return -EFAULT;
654 break;
655 case SOL_IP:
656 switch(optname) {
657 case IP_TOS:
658 case IP_TTL:
659 case IP_HDRINCL:
660 case IP_ROUTER_ALERT:
661 case IP_RECVOPTS:
662 case IP_RETOPTS:
663 case IP_PKTINFO:
664 case IP_MTU_DISCOVER:
665 case IP_RECVERR:
666 case IP_RECVTOS:
667 #ifdef IP_FREEBIND
668 case IP_FREEBIND:
669 #endif
670 case IP_MULTICAST_TTL:
671 case IP_MULTICAST_LOOP:
672 if (get_user(len, optlen))
673 return -EFAULT;
674 if (len < 0)
675 return -EINVAL;
676 lv = sizeof(int);
677 ret = get_errno(getsockopt(sockfd, level, optname, &val, &lv));
678 if (ret < 0)
679 return ret;
680 if (len < sizeof(int) && len > 0 && val >= 0 && val < 255) {
681 unsigned char ucval = val;
682 len = 1;
683 if (put_user(len, optlen))
684 return -EFAULT;
685 if (copy_to_user(optval,&ucval,1))
686 return -EFAULT;
687 } else {
688 val = tswap32(val);
689 if (len > sizeof(int))
690 len = sizeof(int);
691 if (put_user(len, optlen))
692 return -EFAULT;
693 if (copy_to_user(optval, &val, len))
694 return -EFAULT;
696 break;
697 default:
698 goto unimplemented;
700 break;
701 default:
702 unimplemented:
703 gemu_log("getsockopt level=%d optname=%d not yet supported\n",
704 level, optname);
705 ret = -ENOSYS;
706 break;
708 return ret;
711 static long do_socketcall(int num, int32_t *vptr)
713 long ret;
715 switch(num) {
716 case SOCKOP_socket:
718 int domain = tswap32(vptr[0]);
719 int type = tswap32(vptr[1]);
720 int protocol = tswap32(vptr[2]);
722 ret = get_errno(socket(domain, type, protocol));
724 break;
725 case SOCKOP_bind:
727 int sockfd = tswap32(vptr[0]);
728 void *target_addr = (void *)tswap32(vptr[1]);
729 socklen_t addrlen = tswap32(vptr[2]);
730 void *addr = alloca(addrlen);
732 target_to_host_sockaddr(addr, target_addr, addrlen);
733 ret = get_errno(bind(sockfd, addr, addrlen));
735 break;
736 case SOCKOP_connect:
738 int sockfd = tswap32(vptr[0]);
739 void *target_addr = (void *)tswap32(vptr[1]);
740 socklen_t addrlen = tswap32(vptr[2]);
741 void *addr = alloca(addrlen);
743 target_to_host_sockaddr(addr, target_addr, addrlen);
744 ret = get_errno(connect(sockfd, addr, addrlen));
746 break;
747 case SOCKOP_listen:
749 int sockfd = tswap32(vptr[0]);
750 int backlog = tswap32(vptr[1]);
752 ret = get_errno(listen(sockfd, backlog));
754 break;
755 case SOCKOP_accept:
757 int sockfd = tswap32(vptr[0]);
758 void *target_addr = (void *)tswap32(vptr[1]);
759 uint32_t *target_addrlen = (void *)tswap32(vptr[2]);
760 socklen_t addrlen = tswap32(*target_addrlen);
761 void *addr = alloca(addrlen);
763 ret = get_errno(accept(sockfd, addr, &addrlen));
764 if (!is_error(ret)) {
765 host_to_target_sockaddr(target_addr, addr, addrlen);
766 *target_addrlen = tswap32(addrlen);
769 break;
770 case SOCKOP_getsockname:
772 int sockfd = tswap32(vptr[0]);
773 void *target_addr = (void *)tswap32(vptr[1]);
774 uint32_t *target_addrlen = (void *)tswap32(vptr[2]);
775 socklen_t addrlen = tswap32(*target_addrlen);
776 void *addr = alloca(addrlen);
778 ret = get_errno(getsockname(sockfd, addr, &addrlen));
779 if (!is_error(ret)) {
780 host_to_target_sockaddr(target_addr, addr, addrlen);
781 *target_addrlen = tswap32(addrlen);
784 break;
785 case SOCKOP_getpeername:
787 int sockfd = tswap32(vptr[0]);
788 void *target_addr = (void *)tswap32(vptr[1]);
789 uint32_t *target_addrlen = (void *)tswap32(vptr[2]);
790 socklen_t addrlen = tswap32(*target_addrlen);
791 void *addr = alloca(addrlen);
793 ret = get_errno(getpeername(sockfd, addr, &addrlen));
794 if (!is_error(ret)) {
795 host_to_target_sockaddr(target_addr, addr, addrlen);
796 *target_addrlen = tswap32(addrlen);
799 break;
800 case SOCKOP_socketpair:
802 int domain = tswap32(vptr[0]);
803 int type = tswap32(vptr[1]);
804 int protocol = tswap32(vptr[2]);
805 int32_t *target_tab = (void *)tswap32(vptr[3]);
806 int tab[2];
808 ret = get_errno(socketpair(domain, type, protocol, tab));
809 if (!is_error(ret)) {
810 target_tab[0] = tswap32(tab[0]);
811 target_tab[1] = tswap32(tab[1]);
814 break;
815 case SOCKOP_send:
817 int sockfd = tswap32(vptr[0]);
818 void *msg = (void *)tswap32(vptr[1]);
819 size_t len = tswap32(vptr[2]);
820 int flags = tswap32(vptr[3]);
822 ret = get_errno(send(sockfd, msg, len, flags));
824 break;
825 case SOCKOP_recv:
827 int sockfd = tswap32(vptr[0]);
828 void *msg = (void *)tswap32(vptr[1]);
829 size_t len = tswap32(vptr[2]);
830 int flags = tswap32(vptr[3]);
832 ret = get_errno(recv(sockfd, msg, len, flags));
834 break;
835 case SOCKOP_sendto:
837 int sockfd = tswap32(vptr[0]);
838 void *msg = (void *)tswap32(vptr[1]);
839 size_t len = tswap32(vptr[2]);
840 int flags = tswap32(vptr[3]);
841 void *target_addr = (void *)tswap32(vptr[4]);
842 socklen_t addrlen = tswap32(vptr[5]);
843 void *addr = alloca(addrlen);
845 target_to_host_sockaddr(addr, target_addr, addrlen);
846 ret = get_errno(sendto(sockfd, msg, len, flags, addr, addrlen));
848 break;
849 case SOCKOP_recvfrom:
851 int sockfd = tswap32(vptr[0]);
852 void *msg = (void *)tswap32(vptr[1]);
853 size_t len = tswap32(vptr[2]);
854 int flags = tswap32(vptr[3]);
855 void *target_addr = (void *)tswap32(vptr[4]);
856 uint32_t *target_addrlen = (void *)tswap32(vptr[5]);
857 socklen_t addrlen = tswap32(*target_addrlen);
858 void *addr = alloca(addrlen);
860 ret = get_errno(recvfrom(sockfd, msg, len, flags, addr, &addrlen));
861 if (!is_error(ret)) {
862 host_to_target_sockaddr(target_addr, addr, addrlen);
863 *target_addrlen = tswap32(addrlen);
866 break;
867 case SOCKOP_shutdown:
869 int sockfd = tswap32(vptr[0]);
870 int how = tswap32(vptr[1]);
872 ret = get_errno(shutdown(sockfd, how));
874 break;
875 case SOCKOP_sendmsg:
876 case SOCKOP_recvmsg:
878 int fd;
879 struct target_msghdr *msgp;
880 struct msghdr msg;
881 int flags, count, i;
882 struct iovec *vec;
883 struct target_iovec *target_vec;
885 msgp = (void *)tswap32(vptr[1]);
886 msg.msg_name = (void *)tswapl(msgp->msg_name);
887 msg.msg_namelen = tswapl(msgp->msg_namelen);
888 msg.msg_controllen = 2 * tswapl(msgp->msg_controllen);
889 msg.msg_control = alloca(msg.msg_controllen);
890 msg.msg_flags = tswap32(msgp->msg_flags);
892 count = tswapl(msgp->msg_iovlen);
893 vec = alloca(count * sizeof(struct iovec));
894 target_vec = (void *)tswapl(msgp->msg_iov);
895 for(i = 0;i < count; i++) {
896 vec[i].iov_base = (void *)tswapl(target_vec[i].iov_base);
897 vec[i].iov_len = tswapl(target_vec[i].iov_len);
899 msg.msg_iovlen = count;
900 msg.msg_iov = vec;
902 fd = tswap32(vptr[0]);
903 flags = tswap32(vptr[2]);
904 if (num == SOCKOP_sendmsg) {
905 target_to_host_cmsg(&msg, msgp);
906 ret = get_errno(sendmsg(fd, &msg, flags));
907 } else {
908 ret = get_errno(recvmsg(fd, &msg, flags));
909 if (!is_error(ret))
910 host_to_target_cmsg(msgp, &msg);
913 break;
914 case SOCKOP_setsockopt:
916 int sockfd = tswap32(vptr[0]);
917 int level = tswap32(vptr[1]);
918 int optname = tswap32(vptr[2]);
919 void *optval = (void *)tswap32(vptr[3]);
920 socklen_t optlen = tswap32(vptr[4]);
922 ret = do_setsockopt(sockfd, level, optname, optval, optlen);
924 break;
925 case SOCKOP_getsockopt:
927 int sockfd = tswap32(vptr[0]);
928 int level = tswap32(vptr[1]);
929 int optname = tswap32(vptr[2]);
930 void *optval = (void *)tswap32(vptr[3]);
931 uint32_t *poptlen = (void *)tswap32(vptr[4]);
933 ret = do_getsockopt(sockfd, level, optname, optval, poptlen);
935 break;
936 default:
937 gemu_log("Unsupported socketcall: %d\n", num);
938 ret = -ENOSYS;
939 break;
941 return ret;
945 #define N_SHM_REGIONS 32
947 static struct shm_region {
948 uint32_t start;
949 uint32_t size;
950 } shm_regions[N_SHM_REGIONS];
952 static long do_ipc(long call, long first, long second, long third,
953 long ptr, long fifth)
955 int version;
956 long ret = 0;
957 unsigned long raddr;
958 struct shmid_ds shm_info;
959 int i;
961 version = call >> 16;
962 call &= 0xffff;
964 switch (call) {
965 case IPCOP_shmat:
966 /* SHM_* flags are the same on all linux platforms */
967 ret = get_errno((long) shmat(first, (void *) ptr, second));
968 if (is_error(ret))
969 break;
970 raddr = ret;
971 /* find out the length of the shared memory segment */
973 ret = get_errno(shmctl(first, IPC_STAT, &shm_info));
974 if (is_error(ret)) {
975 /* can't get length, bail out */
976 shmdt((void *) raddr);
977 break;
979 page_set_flags(raddr, raddr + shm_info.shm_segsz,
980 PAGE_VALID | PAGE_READ |
981 ((second & SHM_RDONLY)? 0: PAGE_WRITE));
982 for (i = 0; i < N_SHM_REGIONS; ++i) {
983 if (shm_regions[i].start == 0) {
984 shm_regions[i].start = raddr;
985 shm_regions[i].size = shm_info.shm_segsz;
986 break;
989 if (put_user(raddr, (uint32_t *)third))
990 return -EFAULT;
991 ret = 0;
992 break;
993 case IPCOP_shmdt:
994 for (i = 0; i < N_SHM_REGIONS; ++i) {
995 if (shm_regions[i].start == ptr) {
996 shm_regions[i].start = 0;
997 page_set_flags(ptr, shm_regions[i].size, 0);
998 break;
1001 ret = get_errno(shmdt((void *) ptr));
1002 break;
1004 case IPCOP_shmget:
1005 /* IPC_* flag values are the same on all linux platforms */
1006 ret = get_errno(shmget(first, second, third));
1007 break;
1009 /* IPC_* and SHM_* command values are the same on all linux platforms */
1010 case IPCOP_shmctl:
1011 switch(second) {
1012 case IPC_RMID:
1013 case SHM_LOCK:
1014 case SHM_UNLOCK:
1015 ret = get_errno(shmctl(first, second, NULL));
1016 break;
1017 default:
1018 goto unimplemented;
1020 break;
1021 default:
1022 unimplemented:
1023 gemu_log("Unsupported ipc call: %ld (version %d)\n", call, version);
1024 ret = -ENOSYS;
1025 break;
1027 return ret;
1030 /* kernel structure types definitions */
1031 #define IFNAMSIZ 16
1033 #define STRUCT(name, list...) STRUCT_ ## name,
1034 #define STRUCT_SPECIAL(name) STRUCT_ ## name,
1035 enum {
1036 #include "syscall_types.h"
1038 #undef STRUCT
1039 #undef STRUCT_SPECIAL
1041 #define STRUCT(name, list...) const argtype struct_ ## name ## _def[] = { list, TYPE_NULL };
1042 #define STRUCT_SPECIAL(name)
1043 #include "syscall_types.h"
1044 #undef STRUCT
1045 #undef STRUCT_SPECIAL
1047 typedef struct IOCTLEntry {
1048 unsigned int target_cmd;
1049 unsigned int host_cmd;
1050 const char *name;
1051 int access;
1052 const argtype arg_type[5];
1053 } IOCTLEntry;
1055 #define IOC_R 0x0001
1056 #define IOC_W 0x0002
1057 #define IOC_RW (IOC_R | IOC_W)
1059 #define MAX_STRUCT_SIZE 4096
1061 IOCTLEntry ioctl_entries[] = {
1062 #define IOCTL(cmd, access, types...) \
1063 { TARGET_ ## cmd, cmd, #cmd, access, { types } },
1064 #include "ioctls.h"
1065 { 0, 0, },
1068 static long do_ioctl(long fd, long cmd, long arg)
1070 const IOCTLEntry *ie;
1071 const argtype *arg_type;
1072 long ret;
1073 uint8_t buf_temp[MAX_STRUCT_SIZE];
1075 ie = ioctl_entries;
1076 for(;;) {
1077 if (ie->target_cmd == 0) {
1078 gemu_log("Unsupported ioctl: cmd=0x%04lx\n", cmd);
1079 return -ENOSYS;
1081 if (ie->target_cmd == cmd)
1082 break;
1083 ie++;
1085 arg_type = ie->arg_type;
1086 #if defined(DEBUG)
1087 gemu_log("ioctl: cmd=0x%04lx (%s)\n", cmd, ie->name);
1088 #endif
1089 switch(arg_type[0]) {
1090 case TYPE_NULL:
1091 /* no argument */
1092 ret = get_errno(ioctl(fd, ie->host_cmd));
1093 break;
1094 case TYPE_PTRVOID:
1095 case TYPE_INT:
1096 /* int argment */
1097 ret = get_errno(ioctl(fd, ie->host_cmd, arg));
1098 break;
1099 case TYPE_PTR:
1100 arg_type++;
1101 switch(ie->access) {
1102 case IOC_R:
1103 ret = get_errno(ioctl(fd, ie->host_cmd, buf_temp));
1104 if (!is_error(ret)) {
1105 thunk_convert((void *)arg, buf_temp, arg_type, THUNK_TARGET);
1107 break;
1108 case IOC_W:
1109 thunk_convert(buf_temp, (void *)arg, arg_type, THUNK_HOST);
1110 ret = get_errno(ioctl(fd, ie->host_cmd, buf_temp));
1111 break;
1112 default:
1113 case IOC_RW:
1114 thunk_convert(buf_temp, (void *)arg, arg_type, THUNK_HOST);
1115 ret = get_errno(ioctl(fd, ie->host_cmd, buf_temp));
1116 if (!is_error(ret)) {
1117 thunk_convert((void *)arg, buf_temp, arg_type, THUNK_TARGET);
1119 break;
1121 break;
1122 default:
1123 gemu_log("Unsupported ioctl type: cmd=0x%04lx type=%d\n", cmd, arg_type[0]);
1124 ret = -ENOSYS;
1125 break;
1127 return ret;
1130 bitmask_transtbl iflag_tbl[] = {
1131 { TARGET_IGNBRK, TARGET_IGNBRK, IGNBRK, IGNBRK },
1132 { TARGET_BRKINT, TARGET_BRKINT, BRKINT, BRKINT },
1133 { TARGET_IGNPAR, TARGET_IGNPAR, IGNPAR, IGNPAR },
1134 { TARGET_PARMRK, TARGET_PARMRK, PARMRK, PARMRK },
1135 { TARGET_INPCK, TARGET_INPCK, INPCK, INPCK },
1136 { TARGET_ISTRIP, TARGET_ISTRIP, ISTRIP, ISTRIP },
1137 { TARGET_INLCR, TARGET_INLCR, INLCR, INLCR },
1138 { TARGET_IGNCR, TARGET_IGNCR, IGNCR, IGNCR },
1139 { TARGET_ICRNL, TARGET_ICRNL, ICRNL, ICRNL },
1140 { TARGET_IUCLC, TARGET_IUCLC, IUCLC, IUCLC },
1141 { TARGET_IXON, TARGET_IXON, IXON, IXON },
1142 { TARGET_IXANY, TARGET_IXANY, IXANY, IXANY },
1143 { TARGET_IXOFF, TARGET_IXOFF, IXOFF, IXOFF },
1144 { TARGET_IMAXBEL, TARGET_IMAXBEL, IMAXBEL, IMAXBEL },
1145 { 0, 0, 0, 0 }
1148 bitmask_transtbl oflag_tbl[] = {
1149 { TARGET_OPOST, TARGET_OPOST, OPOST, OPOST },
1150 { TARGET_OLCUC, TARGET_OLCUC, OLCUC, OLCUC },
1151 { TARGET_ONLCR, TARGET_ONLCR, ONLCR, ONLCR },
1152 { TARGET_OCRNL, TARGET_OCRNL, OCRNL, OCRNL },
1153 { TARGET_ONOCR, TARGET_ONOCR, ONOCR, ONOCR },
1154 { TARGET_ONLRET, TARGET_ONLRET, ONLRET, ONLRET },
1155 { TARGET_OFILL, TARGET_OFILL, OFILL, OFILL },
1156 { TARGET_OFDEL, TARGET_OFDEL, OFDEL, OFDEL },
1157 { TARGET_NLDLY, TARGET_NL0, NLDLY, NL0 },
1158 { TARGET_NLDLY, TARGET_NL1, NLDLY, NL1 },
1159 { TARGET_CRDLY, TARGET_CR0, CRDLY, CR0 },
1160 { TARGET_CRDLY, TARGET_CR1, CRDLY, CR1 },
1161 { TARGET_CRDLY, TARGET_CR2, CRDLY, CR2 },
1162 { TARGET_CRDLY, TARGET_CR3, CRDLY, CR3 },
1163 { TARGET_TABDLY, TARGET_TAB0, TABDLY, TAB0 },
1164 { TARGET_TABDLY, TARGET_TAB1, TABDLY, TAB1 },
1165 { TARGET_TABDLY, TARGET_TAB2, TABDLY, TAB2 },
1166 { TARGET_TABDLY, TARGET_TAB3, TABDLY, TAB3 },
1167 { TARGET_BSDLY, TARGET_BS0, BSDLY, BS0 },
1168 { TARGET_BSDLY, TARGET_BS1, BSDLY, BS1 },
1169 { TARGET_VTDLY, TARGET_VT0, VTDLY, VT0 },
1170 { TARGET_VTDLY, TARGET_VT1, VTDLY, VT1 },
1171 { TARGET_FFDLY, TARGET_FF0, FFDLY, FF0 },
1172 { TARGET_FFDLY, TARGET_FF1, FFDLY, FF1 },
1173 { 0, 0, 0, 0 }
1176 bitmask_transtbl cflag_tbl[] = {
1177 { TARGET_CBAUD, TARGET_B0, CBAUD, B0 },
1178 { TARGET_CBAUD, TARGET_B50, CBAUD, B50 },
1179 { TARGET_CBAUD, TARGET_B75, CBAUD, B75 },
1180 { TARGET_CBAUD, TARGET_B110, CBAUD, B110 },
1181 { TARGET_CBAUD, TARGET_B134, CBAUD, B134 },
1182 { TARGET_CBAUD, TARGET_B150, CBAUD, B150 },
1183 { TARGET_CBAUD, TARGET_B200, CBAUD, B200 },
1184 { TARGET_CBAUD, TARGET_B300, CBAUD, B300 },
1185 { TARGET_CBAUD, TARGET_B600, CBAUD, B600 },
1186 { TARGET_CBAUD, TARGET_B1200, CBAUD, B1200 },
1187 { TARGET_CBAUD, TARGET_B1800, CBAUD, B1800 },
1188 { TARGET_CBAUD, TARGET_B2400, CBAUD, B2400 },
1189 { TARGET_CBAUD, TARGET_B4800, CBAUD, B4800 },
1190 { TARGET_CBAUD, TARGET_B9600, CBAUD, B9600 },
1191 { TARGET_CBAUD, TARGET_B19200, CBAUD, B19200 },
1192 { TARGET_CBAUD, TARGET_B38400, CBAUD, B38400 },
1193 { TARGET_CBAUD, TARGET_B57600, CBAUD, B57600 },
1194 { TARGET_CBAUD, TARGET_B115200, CBAUD, B115200 },
1195 { TARGET_CBAUD, TARGET_B230400, CBAUD, B230400 },
1196 { TARGET_CBAUD, TARGET_B460800, CBAUD, B460800 },
1197 { TARGET_CSIZE, TARGET_CS5, CSIZE, CS5 },
1198 { TARGET_CSIZE, TARGET_CS6, CSIZE, CS6 },
1199 { TARGET_CSIZE, TARGET_CS7, CSIZE, CS7 },
1200 { TARGET_CSIZE, TARGET_CS8, CSIZE, CS8 },
1201 { TARGET_CSTOPB, TARGET_CSTOPB, CSTOPB, CSTOPB },
1202 { TARGET_CREAD, TARGET_CREAD, CREAD, CREAD },
1203 { TARGET_PARENB, TARGET_PARENB, PARENB, PARENB },
1204 { TARGET_PARODD, TARGET_PARODD, PARODD, PARODD },
1205 { TARGET_HUPCL, TARGET_HUPCL, HUPCL, HUPCL },
1206 { TARGET_CLOCAL, TARGET_CLOCAL, CLOCAL, CLOCAL },
1207 { TARGET_CRTSCTS, TARGET_CRTSCTS, CRTSCTS, CRTSCTS },
1208 { 0, 0, 0, 0 }
1211 bitmask_transtbl lflag_tbl[] = {
1212 { TARGET_ISIG, TARGET_ISIG, ISIG, ISIG },
1213 { TARGET_ICANON, TARGET_ICANON, ICANON, ICANON },
1214 { TARGET_XCASE, TARGET_XCASE, XCASE, XCASE },
1215 { TARGET_ECHO, TARGET_ECHO, ECHO, ECHO },
1216 { TARGET_ECHOE, TARGET_ECHOE, ECHOE, ECHOE },
1217 { TARGET_ECHOK, TARGET_ECHOK, ECHOK, ECHOK },
1218 { TARGET_ECHONL, TARGET_ECHONL, ECHONL, ECHONL },
1219 { TARGET_NOFLSH, TARGET_NOFLSH, NOFLSH, NOFLSH },
1220 { TARGET_TOSTOP, TARGET_TOSTOP, TOSTOP, TOSTOP },
1221 { TARGET_ECHOCTL, TARGET_ECHOCTL, ECHOCTL, ECHOCTL },
1222 { TARGET_ECHOPRT, TARGET_ECHOPRT, ECHOPRT, ECHOPRT },
1223 { TARGET_ECHOKE, TARGET_ECHOKE, ECHOKE, ECHOKE },
1224 { TARGET_FLUSHO, TARGET_FLUSHO, FLUSHO, FLUSHO },
1225 { TARGET_PENDIN, TARGET_PENDIN, PENDIN, PENDIN },
1226 { TARGET_IEXTEN, TARGET_IEXTEN, IEXTEN, IEXTEN },
1227 { 0, 0, 0, 0 }
1230 static void target_to_host_termios (void *dst, const void *src)
1232 struct host_termios *host = dst;
1233 const struct target_termios *target = src;
1235 host->c_iflag =
1236 target_to_host_bitmask(tswap32(target->c_iflag), iflag_tbl);
1237 host->c_oflag =
1238 target_to_host_bitmask(tswap32(target->c_oflag), oflag_tbl);
1239 host->c_cflag =
1240 target_to_host_bitmask(tswap32(target->c_cflag), cflag_tbl);
1241 host->c_lflag =
1242 target_to_host_bitmask(tswap32(target->c_lflag), lflag_tbl);
1243 host->c_line = target->c_line;
1245 host->c_cc[VINTR] = target->c_cc[TARGET_VINTR];
1246 host->c_cc[VQUIT] = target->c_cc[TARGET_VQUIT];
1247 host->c_cc[VERASE] = target->c_cc[TARGET_VERASE];
1248 host->c_cc[VKILL] = target->c_cc[TARGET_VKILL];
1249 host->c_cc[VEOF] = target->c_cc[TARGET_VEOF];
1250 host->c_cc[VTIME] = target->c_cc[TARGET_VTIME];
1251 host->c_cc[VMIN] = target->c_cc[TARGET_VMIN];
1252 host->c_cc[VSWTC] = target->c_cc[TARGET_VSWTC];
1253 host->c_cc[VSTART] = target->c_cc[TARGET_VSTART];
1254 host->c_cc[VSTOP] = target->c_cc[TARGET_VSTOP];
1255 host->c_cc[VSUSP] = target->c_cc[TARGET_VSUSP];
1256 host->c_cc[VEOL] = target->c_cc[TARGET_VEOL];
1257 host->c_cc[VREPRINT] = target->c_cc[TARGET_VREPRINT];
1258 host->c_cc[VDISCARD] = target->c_cc[TARGET_VDISCARD];
1259 host->c_cc[VWERASE] = target->c_cc[TARGET_VWERASE];
1260 host->c_cc[VLNEXT] = target->c_cc[TARGET_VLNEXT];
1261 host->c_cc[VEOL2] = target->c_cc[TARGET_VEOL2];
1264 static void host_to_target_termios (void *dst, const void *src)
1266 struct target_termios *target = dst;
1267 const struct host_termios *host = src;
1269 target->c_iflag =
1270 tswap32(host_to_target_bitmask(host->c_iflag, iflag_tbl));
1271 target->c_oflag =
1272 tswap32(host_to_target_bitmask(host->c_oflag, oflag_tbl));
1273 target->c_cflag =
1274 tswap32(host_to_target_bitmask(host->c_cflag, cflag_tbl));
1275 target->c_lflag =
1276 tswap32(host_to_target_bitmask(host->c_lflag, lflag_tbl));
1277 target->c_line = host->c_line;
1279 target->c_cc[TARGET_VINTR] = host->c_cc[VINTR];
1280 target->c_cc[TARGET_VQUIT] = host->c_cc[VQUIT];
1281 target->c_cc[TARGET_VERASE] = host->c_cc[VERASE];
1282 target->c_cc[TARGET_VKILL] = host->c_cc[VKILL];
1283 target->c_cc[TARGET_VEOF] = host->c_cc[VEOF];
1284 target->c_cc[TARGET_VTIME] = host->c_cc[VTIME];
1285 target->c_cc[TARGET_VMIN] = host->c_cc[VMIN];
1286 target->c_cc[TARGET_VSWTC] = host->c_cc[VSWTC];
1287 target->c_cc[TARGET_VSTART] = host->c_cc[VSTART];
1288 target->c_cc[TARGET_VSTOP] = host->c_cc[VSTOP];
1289 target->c_cc[TARGET_VSUSP] = host->c_cc[VSUSP];
1290 target->c_cc[TARGET_VEOL] = host->c_cc[VEOL];
1291 target->c_cc[TARGET_VREPRINT] = host->c_cc[VREPRINT];
1292 target->c_cc[TARGET_VDISCARD] = host->c_cc[VDISCARD];
1293 target->c_cc[TARGET_VWERASE] = host->c_cc[VWERASE];
1294 target->c_cc[TARGET_VLNEXT] = host->c_cc[VLNEXT];
1295 target->c_cc[TARGET_VEOL2] = host->c_cc[VEOL2];
1298 StructEntry struct_termios_def = {
1299 .convert = { host_to_target_termios, target_to_host_termios },
1300 .size = { sizeof(struct target_termios), sizeof(struct host_termios) },
1301 .align = { __alignof__(struct target_termios), __alignof__(struct host_termios) },
1304 static bitmask_transtbl mmap_flags_tbl[] = {
1305 { TARGET_MAP_SHARED, TARGET_MAP_SHARED, MAP_SHARED, MAP_SHARED },
1306 { TARGET_MAP_PRIVATE, TARGET_MAP_PRIVATE, MAP_PRIVATE, MAP_PRIVATE },
1307 { TARGET_MAP_FIXED, TARGET_MAP_FIXED, MAP_FIXED, MAP_FIXED },
1308 { TARGET_MAP_ANONYMOUS, TARGET_MAP_ANONYMOUS, MAP_ANONYMOUS, MAP_ANONYMOUS },
1309 { TARGET_MAP_GROWSDOWN, TARGET_MAP_GROWSDOWN, MAP_GROWSDOWN, MAP_GROWSDOWN },
1310 { TARGET_MAP_DENYWRITE, TARGET_MAP_DENYWRITE, MAP_DENYWRITE, MAP_DENYWRITE },
1311 { TARGET_MAP_EXECUTABLE, TARGET_MAP_EXECUTABLE, MAP_EXECUTABLE, MAP_EXECUTABLE },
1312 { TARGET_MAP_LOCKED, TARGET_MAP_LOCKED, MAP_LOCKED, MAP_LOCKED },
1313 { 0, 0, 0, 0 }
1316 static bitmask_transtbl fcntl_flags_tbl[] = {
1317 { TARGET_O_ACCMODE, TARGET_O_WRONLY, O_ACCMODE, O_WRONLY, },
1318 { TARGET_O_ACCMODE, TARGET_O_RDWR, O_ACCMODE, O_RDWR, },
1319 { TARGET_O_CREAT, TARGET_O_CREAT, O_CREAT, O_CREAT, },
1320 { TARGET_O_EXCL, TARGET_O_EXCL, O_EXCL, O_EXCL, },
1321 { TARGET_O_NOCTTY, TARGET_O_NOCTTY, O_NOCTTY, O_NOCTTY, },
1322 { TARGET_O_TRUNC, TARGET_O_TRUNC, O_TRUNC, O_TRUNC, },
1323 { TARGET_O_APPEND, TARGET_O_APPEND, O_APPEND, O_APPEND, },
1324 { TARGET_O_NONBLOCK, TARGET_O_NONBLOCK, O_NONBLOCK, O_NONBLOCK, },
1325 { TARGET_O_SYNC, TARGET_O_SYNC, O_SYNC, O_SYNC, },
1326 { TARGET_FASYNC, TARGET_FASYNC, FASYNC, FASYNC, },
1327 { TARGET_O_DIRECTORY, TARGET_O_DIRECTORY, O_DIRECTORY, O_DIRECTORY, },
1328 { TARGET_O_NOFOLLOW, TARGET_O_NOFOLLOW, O_NOFOLLOW, O_NOFOLLOW, },
1329 { TARGET_O_LARGEFILE, TARGET_O_LARGEFILE, O_LARGEFILE, O_LARGEFILE, },
1330 #if defined(O_DIRECT)
1331 { TARGET_O_DIRECT, TARGET_O_DIRECT, O_DIRECT, O_DIRECT, },
1332 #endif
1333 { 0, 0, 0, 0 }
1336 #if defined(TARGET_I386)
1338 /* NOTE: there is really one LDT for all the threads */
1339 uint8_t *ldt_table;
1341 static int read_ldt(void *ptr, unsigned long bytecount)
1343 int size;
1345 if (!ldt_table)
1346 return 0;
1347 size = TARGET_LDT_ENTRIES * TARGET_LDT_ENTRY_SIZE;
1348 if (size > bytecount)
1349 size = bytecount;
1350 memcpy(ptr, ldt_table, size);
1351 return size;
1354 /* XXX: add locking support */
1355 static int write_ldt(CPUX86State *env,
1356 void *ptr, unsigned long bytecount, int oldmode)
1358 struct target_modify_ldt_ldt_s ldt_info;
1359 int seg_32bit, contents, read_exec_only, limit_in_pages;
1360 int seg_not_present, useable;
1361 uint32_t *lp, entry_1, entry_2;
1363 if (bytecount != sizeof(ldt_info))
1364 return -EINVAL;
1365 memcpy(&ldt_info, ptr, sizeof(ldt_info));
1366 tswap32s(&ldt_info.entry_number);
1367 tswapls((long *)&ldt_info.base_addr);
1368 tswap32s(&ldt_info.limit);
1369 tswap32s(&ldt_info.flags);
1371 if (ldt_info.entry_number >= TARGET_LDT_ENTRIES)
1372 return -EINVAL;
1373 seg_32bit = ldt_info.flags & 1;
1374 contents = (ldt_info.flags >> 1) & 3;
1375 read_exec_only = (ldt_info.flags >> 3) & 1;
1376 limit_in_pages = (ldt_info.flags >> 4) & 1;
1377 seg_not_present = (ldt_info.flags >> 5) & 1;
1378 useable = (ldt_info.flags >> 6) & 1;
1380 if (contents == 3) {
1381 if (oldmode)
1382 return -EINVAL;
1383 if (seg_not_present == 0)
1384 return -EINVAL;
1386 /* allocate the LDT */
1387 if (!ldt_table) {
1388 ldt_table = malloc(TARGET_LDT_ENTRIES * TARGET_LDT_ENTRY_SIZE);
1389 if (!ldt_table)
1390 return -ENOMEM;
1391 memset(ldt_table, 0, TARGET_LDT_ENTRIES * TARGET_LDT_ENTRY_SIZE);
1392 env->ldt.base = (long)ldt_table;
1393 env->ldt.limit = 0xffff;
1396 /* NOTE: same code as Linux kernel */
1397 /* Allow LDTs to be cleared by the user. */
1398 if (ldt_info.base_addr == 0 && ldt_info.limit == 0) {
1399 if (oldmode ||
1400 (contents == 0 &&
1401 read_exec_only == 1 &&
1402 seg_32bit == 0 &&
1403 limit_in_pages == 0 &&
1404 seg_not_present == 1 &&
1405 useable == 0 )) {
1406 entry_1 = 0;
1407 entry_2 = 0;
1408 goto install;
1412 entry_1 = ((ldt_info.base_addr & 0x0000ffff) << 16) |
1413 (ldt_info.limit & 0x0ffff);
1414 entry_2 = (ldt_info.base_addr & 0xff000000) |
1415 ((ldt_info.base_addr & 0x00ff0000) >> 16) |
1416 (ldt_info.limit & 0xf0000) |
1417 ((read_exec_only ^ 1) << 9) |
1418 (contents << 10) |
1419 ((seg_not_present ^ 1) << 15) |
1420 (seg_32bit << 22) |
1421 (limit_in_pages << 23) |
1422 0x7000;
1423 if (!oldmode)
1424 entry_2 |= (useable << 20);
1426 /* Install the new entry ... */
1427 install:
1428 lp = (uint32_t *)(ldt_table + (ldt_info.entry_number << 3));
1429 lp[0] = tswap32(entry_1);
1430 lp[1] = tswap32(entry_2);
1431 return 0;
1434 /* specific and weird i386 syscalls */
1435 int do_modify_ldt(CPUX86State *env, int func, void *ptr, unsigned long bytecount)
1437 int ret = -ENOSYS;
1439 switch (func) {
1440 case 0:
1441 ret = read_ldt(ptr, bytecount);
1442 break;
1443 case 1:
1444 ret = write_ldt(env, ptr, bytecount, 1);
1445 break;
1446 case 0x11:
1447 ret = write_ldt(env, ptr, bytecount, 0);
1448 break;
1450 return ret;
1453 #endif /* defined(TARGET_I386) */
1455 /* this stack is the equivalent of the kernel stack associated with a
1456 thread/process */
1457 #define NEW_STACK_SIZE 8192
1459 static int clone_func(void *arg)
1461 CPUState *env = arg;
1462 cpu_loop(env);
1463 /* never exits */
1464 return 0;
1467 int do_fork(CPUState *env, unsigned int flags, unsigned long newsp)
1469 int ret;
1470 TaskState *ts;
1471 uint8_t *new_stack;
1472 CPUState *new_env;
1474 if (flags & CLONE_VM) {
1475 ts = malloc(sizeof(TaskState) + NEW_STACK_SIZE);
1476 memset(ts, 0, sizeof(TaskState));
1477 new_stack = ts->stack;
1478 ts->used = 1;
1479 /* add in task state list */
1480 ts->next = first_task_state;
1481 first_task_state = ts;
1482 /* we create a new CPU instance. */
1483 new_env = cpu_init();
1484 memcpy(new_env, env, sizeof(CPUState));
1485 #if defined(TARGET_I386)
1486 if (!newsp)
1487 newsp = env->regs[R_ESP];
1488 new_env->regs[R_ESP] = newsp;
1489 new_env->regs[R_EAX] = 0;
1490 #elif defined(TARGET_ARM)
1491 if (!newsp)
1492 newsp = env->regs[13];
1493 new_env->regs[13] = newsp;
1494 new_env->regs[0] = 0;
1495 #elif defined(TARGET_SPARC)
1496 printf ("HELPME: %s:%d\n", __FILE__, __LINE__);
1497 #elif defined(TARGET_MIPS)
1498 printf ("HELPME: %s:%d\n", __FILE__, __LINE__);
1499 #elif defined(TARGET_PPC)
1500 if (!newsp)
1501 newsp = env->gpr[1];
1502 new_env->gpr[1] = newsp;
1504 int i;
1505 for (i = 7; i < 32; i++)
1506 new_env->gpr[i] = 0;
1508 #else
1509 #error unsupported target CPU
1510 #endif
1511 new_env->opaque = ts;
1512 #ifdef __ia64__
1513 ret = clone2(clone_func, new_stack + NEW_STACK_SIZE, flags, new_env);
1514 #else
1515 ret = clone(clone_func, new_stack + NEW_STACK_SIZE, flags, new_env);
1516 #endif
1517 } else {
1518 /* if no CLONE_VM, we consider it is a fork */
1519 if ((flags & ~CSIGNAL) != 0)
1520 return -EINVAL;
1521 ret = fork();
1523 return ret;
1526 static long do_fcntl(int fd, int cmd, unsigned long arg)
1528 struct flock fl;
1529 struct target_flock *target_fl = (void *)arg;
1530 long ret;
1532 switch(cmd) {
1533 case TARGET_F_GETLK:
1534 ret = fcntl(fd, cmd, &fl);
1535 if (ret == 0) {
1536 target_fl->l_type = tswap16(fl.l_type);
1537 target_fl->l_whence = tswap16(fl.l_whence);
1538 target_fl->l_start = tswapl(fl.l_start);
1539 target_fl->l_len = tswapl(fl.l_len);
1540 target_fl->l_pid = tswapl(fl.l_pid);
1542 break;
1544 case TARGET_F_SETLK:
1545 case TARGET_F_SETLKW:
1546 fl.l_type = tswap16(target_fl->l_type);
1547 fl.l_whence = tswap16(target_fl->l_whence);
1548 fl.l_start = tswapl(target_fl->l_start);
1549 fl.l_len = tswapl(target_fl->l_len);
1550 fl.l_pid = tswapl(target_fl->l_pid);
1551 ret = fcntl(fd, cmd, &fl);
1552 break;
1554 case TARGET_F_GETLK64:
1555 case TARGET_F_SETLK64:
1556 case TARGET_F_SETLKW64:
1557 ret = -1;
1558 errno = EINVAL;
1559 break;
1561 case F_GETFL:
1562 ret = fcntl(fd, cmd, arg);
1563 ret = host_to_target_bitmask(ret, fcntl_flags_tbl);
1564 break;
1566 case F_SETFL:
1567 ret = fcntl(fd, cmd, target_to_host_bitmask(arg, fcntl_flags_tbl));
1568 break;
1570 default:
1571 ret = fcntl(fd, cmd, arg);
1572 break;
1574 return ret;
1577 #ifdef USE_UID16
1579 static inline int high2lowuid(int uid)
1581 if (uid > 65535)
1582 return 65534;
1583 else
1584 return uid;
1587 static inline int high2lowgid(int gid)
1589 if (gid > 65535)
1590 return 65534;
1591 else
1592 return gid;
1595 static inline int low2highuid(int uid)
1597 if ((int16_t)uid == -1)
1598 return -1;
1599 else
1600 return uid;
1603 static inline int low2highgid(int gid)
1605 if ((int16_t)gid == -1)
1606 return -1;
1607 else
1608 return gid;
1611 #endif /* USE_UID16 */
1613 void syscall_init(void)
1615 IOCTLEntry *ie;
1616 const argtype *arg_type;
1617 int size;
1619 #define STRUCT(name, list...) thunk_register_struct(STRUCT_ ## name, #name, struct_ ## name ## _def);
1620 #define STRUCT_SPECIAL(name) thunk_register_struct_direct(STRUCT_ ## name, #name, &struct_ ## name ## _def);
1621 #include "syscall_types.h"
1622 #undef STRUCT
1623 #undef STRUCT_SPECIAL
1625 /* we patch the ioctl size if necessary. We rely on the fact that
1626 no ioctl has all the bits at '1' in the size field */
1627 ie = ioctl_entries;
1628 while (ie->target_cmd != 0) {
1629 if (((ie->target_cmd >> TARGET_IOC_SIZESHIFT) & TARGET_IOC_SIZEMASK) ==
1630 TARGET_IOC_SIZEMASK) {
1631 arg_type = ie->arg_type;
1632 if (arg_type[0] != TYPE_PTR) {
1633 fprintf(stderr, "cannot patch size for ioctl 0x%x\n",
1634 ie->target_cmd);
1635 exit(1);
1637 arg_type++;
1638 size = thunk_type_size(arg_type, 0);
1639 ie->target_cmd = (ie->target_cmd &
1640 ~(TARGET_IOC_SIZEMASK << TARGET_IOC_SIZESHIFT)) |
1641 (size << TARGET_IOC_SIZESHIFT);
1643 /* automatic consistency check if same arch */
1644 #if defined(__i386__) && defined(TARGET_I386)
1645 if (ie->target_cmd != ie->host_cmd) {
1646 fprintf(stderr, "ERROR: ioctl: target=0x%x host=0x%x\n",
1647 ie->target_cmd, ie->host_cmd);
1649 #endif
1650 ie++;
1654 static inline uint64_t target_offset64(uint32_t word0, uint32_t word1)
1656 #ifdef TARGET_WORDS_BIG_ENDIAN
1657 return ((uint64_t)word0 << 32) | word1;
1658 #else
1659 return ((uint64_t)word1 << 32) | word0;
1660 #endif
1663 #ifdef TARGET_NR_truncate64
1664 static inline long target_truncate64(void *cpu_env, const char *arg1,
1665 long arg2, long arg3, long arg4)
1667 #ifdef TARGET_ARM
1668 if (((CPUARMState *)cpu_env)->eabi)
1670 arg2 = arg3;
1671 arg3 = arg4;
1673 #endif
1674 return get_errno(truncate64(arg1, target_offset64(arg2, arg3)));
1676 #endif
1678 #ifdef TARGET_NR_ftruncate64
1679 static inline long target_ftruncate64(void *cpu_env, long arg1, long arg2,
1680 long arg3, long arg4)
1682 #ifdef TARGET_ARM
1683 if (((CPUARMState *)cpu_env)->eabi)
1685 arg2 = arg3;
1686 arg3 = arg4;
1688 #endif
1689 return get_errno(ftruncate64(arg1, target_offset64(arg2, arg3)));
1691 #endif
1693 long do_syscall(void *cpu_env, int num, long arg1, long arg2, long arg3,
1694 long arg4, long arg5, long arg6)
1696 long ret;
1697 struct stat st;
1698 struct statfs stfs;
1700 #ifdef DEBUG
1701 gemu_log("syscall %d", num);
1702 #endif
1703 switch(num) {
1704 case TARGET_NR_exit:
1705 #ifdef HAVE_GPROF
1706 _mcleanup();
1707 #endif
1708 gdb_exit(cpu_env, arg1);
1709 /* XXX: should free thread stack and CPU env */
1710 _exit(arg1);
1711 ret = 0; /* avoid warning */
1712 break;
1713 case TARGET_NR_read:
1714 page_unprotect_range((void *)arg2, arg3);
1715 ret = get_errno(read(arg1, (void *)arg2, arg3));
1716 break;
1717 case TARGET_NR_write:
1718 ret = get_errno(write(arg1, (void *)arg2, arg3));
1719 break;
1720 case TARGET_NR_open:
1721 ret = get_errno(open(path((const char *)arg1),
1722 target_to_host_bitmask(arg2, fcntl_flags_tbl),
1723 arg3));
1724 break;
1725 case TARGET_NR_close:
1726 ret = get_errno(close(arg1));
1727 break;
1728 case TARGET_NR_brk:
1729 ret = do_brk((char *)arg1);
1730 break;
1731 case TARGET_NR_fork:
1732 ret = get_errno(do_fork(cpu_env, SIGCHLD, 0));
1733 break;
1734 case TARGET_NR_waitpid:
1736 int *status = (int *)arg2;
1737 ret = get_errno(waitpid(arg1, status, arg3));
1738 if (!is_error(ret) && status)
1739 tswapls((long *)&status);
1741 break;
1742 case TARGET_NR_creat:
1743 ret = get_errno(creat((const char *)arg1, arg2));
1744 break;
1745 case TARGET_NR_link:
1746 ret = get_errno(link((const char *)arg1, (const char *)arg2));
1747 break;
1748 case TARGET_NR_unlink:
1749 ret = get_errno(unlink((const char *)arg1));
1750 break;
1751 case TARGET_NR_execve:
1753 char **argp, **envp;
1754 int argc, envc;
1755 uint32_t *p;
1756 char **q;
1758 argc = 0;
1759 for (p = (void *)arg2; *p; p++)
1760 argc++;
1761 envc = 0;
1762 for (p = (void *)arg3; *p; p++)
1763 envc++;
1765 argp = alloca((argc + 1) * sizeof(void *));
1766 envp = alloca((envc + 1) * sizeof(void *));
1768 for (p = (void *)arg2, q = argp; *p; p++, q++)
1769 *q = (void *)tswap32(*p);
1770 *q = NULL;
1772 for (p = (void *)arg3, q = envp; *p; p++, q++)
1773 *q = (void *)tswap32(*p);
1774 *q = NULL;
1776 ret = get_errno(execve((const char *)arg1, argp, envp));
1778 break;
1779 case TARGET_NR_chdir:
1780 ret = get_errno(chdir((const char *)arg1));
1781 break;
1782 #ifdef TARGET_NR_time
1783 case TARGET_NR_time:
1785 int *time_ptr = (int *)arg1;
1786 ret = get_errno(time((time_t *)time_ptr));
1787 if (!is_error(ret) && time_ptr)
1788 tswap32s(time_ptr);
1790 break;
1791 #endif
1792 case TARGET_NR_mknod:
1793 ret = get_errno(mknod((const char *)arg1, arg2, arg3));
1794 break;
1795 case TARGET_NR_chmod:
1796 ret = get_errno(chmod((const char *)arg1, arg2));
1797 break;
1798 #ifdef TARGET_NR_break
1799 case TARGET_NR_break:
1800 goto unimplemented;
1801 #endif
1802 #ifdef TARGET_NR_oldstat
1803 case TARGET_NR_oldstat:
1804 goto unimplemented;
1805 #endif
1806 case TARGET_NR_lseek:
1807 ret = get_errno(lseek(arg1, arg2, arg3));
1808 break;
1809 case TARGET_NR_getpid:
1810 ret = get_errno(getpid());
1811 break;
1812 case TARGET_NR_mount:
1813 /* need to look at the data field */
1814 goto unimplemented;
1815 case TARGET_NR_umount:
1816 ret = get_errno(umount((const char *)arg1));
1817 break;
1818 case TARGET_NR_stime:
1820 int *time_ptr = (int *)arg1;
1821 if (time_ptr)
1822 tswap32s(time_ptr);
1823 ret = get_errno(stime((time_t *)time_ptr));
1825 break;
1826 case TARGET_NR_ptrace:
1827 goto unimplemented;
1828 case TARGET_NR_alarm:
1829 ret = alarm(arg1);
1830 break;
1831 #ifdef TARGET_NR_oldfstat
1832 case TARGET_NR_oldfstat:
1833 goto unimplemented;
1834 #endif
1835 case TARGET_NR_pause:
1836 ret = get_errno(pause());
1837 break;
1838 case TARGET_NR_utime:
1840 struct utimbuf tbuf, *tbuf1;
1841 struct target_utimbuf *target_tbuf = (void *)arg2;
1842 if (target_tbuf) {
1843 get_user(tbuf.actime, &target_tbuf->actime);
1844 get_user(tbuf.modtime, &target_tbuf->modtime);
1845 tbuf1 = &tbuf;
1846 } else {
1847 tbuf1 = NULL;
1849 ret = get_errno(utime((const char *)arg1, tbuf1));
1851 break;
1852 case TARGET_NR_utimes:
1854 struct target_timeval *target_tvp = (struct target_timeval *)arg2;
1855 struct timeval *tvp, tv[2];
1856 if (target_tvp) {
1857 target_to_host_timeval(&tv[0], &target_tvp[0]);
1858 target_to_host_timeval(&tv[1], &target_tvp[1]);
1859 tvp = tv;
1860 } else {
1861 tvp = NULL;
1863 ret = get_errno(utimes((const char *)arg1, tvp));
1865 break;
1866 #ifdef TARGET_NR_stty
1867 case TARGET_NR_stty:
1868 goto unimplemented;
1869 #endif
1870 #ifdef TARGET_NR_gtty
1871 case TARGET_NR_gtty:
1872 goto unimplemented;
1873 #endif
1874 case TARGET_NR_access:
1875 ret = get_errno(access((const char *)arg1, arg2));
1876 break;
1877 case TARGET_NR_nice:
1878 ret = get_errno(nice(arg1));
1879 break;
1880 #ifdef TARGET_NR_ftime
1881 case TARGET_NR_ftime:
1882 goto unimplemented;
1883 #endif
1884 case TARGET_NR_sync:
1885 sync();
1886 ret = 0;
1887 break;
1888 case TARGET_NR_kill:
1889 ret = get_errno(kill(arg1, arg2));
1890 break;
1891 case TARGET_NR_rename:
1892 ret = get_errno(rename((const char *)arg1, (const char *)arg2));
1893 break;
1894 case TARGET_NR_mkdir:
1895 ret = get_errno(mkdir((const char *)arg1, arg2));
1896 break;
1897 case TARGET_NR_rmdir:
1898 ret = get_errno(rmdir((const char *)arg1));
1899 break;
1900 case TARGET_NR_dup:
1901 ret = get_errno(dup(arg1));
1902 break;
1903 case TARGET_NR_pipe:
1905 int *pipe_ptr = (int *)arg1;
1906 ret = get_errno(pipe(pipe_ptr));
1907 if (!is_error(ret)) {
1908 tswap32s(&pipe_ptr[0]);
1909 tswap32s(&pipe_ptr[1]);
1912 break;
1913 case TARGET_NR_times:
1915 struct target_tms *tmsp = (void *)arg1;
1916 struct tms tms;
1917 ret = get_errno(times(&tms));
1918 if (tmsp) {
1919 tmsp->tms_utime = tswapl(host_to_target_clock_t(tms.tms_utime));
1920 tmsp->tms_stime = tswapl(host_to_target_clock_t(tms.tms_stime));
1921 tmsp->tms_cutime = tswapl(host_to_target_clock_t(tms.tms_cutime));
1922 tmsp->tms_cstime = tswapl(host_to_target_clock_t(tms.tms_cstime));
1924 if (!is_error(ret))
1925 ret = host_to_target_clock_t(ret);
1927 break;
1928 #ifdef TARGET_NR_prof
1929 case TARGET_NR_prof:
1930 goto unimplemented;
1931 #endif
1932 case TARGET_NR_signal:
1933 goto unimplemented;
1935 case TARGET_NR_acct:
1936 goto unimplemented;
1937 case TARGET_NR_umount2:
1938 ret = get_errno(umount2((const char *)arg1, arg2));
1939 break;
1940 #ifdef TARGET_NR_lock
1941 case TARGET_NR_lock:
1942 goto unimplemented;
1943 #endif
1944 case TARGET_NR_ioctl:
1945 ret = do_ioctl(arg1, arg2, arg3);
1946 break;
1947 case TARGET_NR_fcntl:
1948 ret = get_errno(do_fcntl(arg1, arg2, arg3));
1949 break;
1950 #ifdef TARGET_NR_mpx
1951 case TARGET_NR_mpx:
1952 goto unimplemented;
1953 #endif
1954 case TARGET_NR_setpgid:
1955 ret = get_errno(setpgid(arg1, arg2));
1956 break;
1957 #ifdef TARGET_NR_ulimit
1958 case TARGET_NR_ulimit:
1959 goto unimplemented;
1960 #endif
1961 #ifdef TARGET_NR_oldolduname
1962 case TARGET_NR_oldolduname:
1963 goto unimplemented;
1964 #endif
1965 case TARGET_NR_umask:
1966 ret = get_errno(umask(arg1));
1967 break;
1968 case TARGET_NR_chroot:
1969 ret = get_errno(chroot((const char *)arg1));
1970 break;
1971 case TARGET_NR_ustat:
1972 goto unimplemented;
1973 case TARGET_NR_dup2:
1974 ret = get_errno(dup2(arg1, arg2));
1975 break;
1976 case TARGET_NR_getppid:
1977 ret = get_errno(getppid());
1978 break;
1979 case TARGET_NR_getpgrp:
1980 ret = get_errno(getpgrp());
1981 break;
1982 case TARGET_NR_setsid:
1983 ret = get_errno(setsid());
1984 break;
1985 case TARGET_NR_sigaction:
1987 struct target_old_sigaction *old_act = (void *)arg2;
1988 struct target_old_sigaction *old_oact = (void *)arg3;
1989 struct target_sigaction act, oact, *pact;
1990 if (old_act) {
1991 act._sa_handler = old_act->_sa_handler;
1992 target_siginitset(&act.sa_mask, old_act->sa_mask);
1993 act.sa_flags = old_act->sa_flags;
1994 act.sa_restorer = old_act->sa_restorer;
1995 pact = &act;
1996 } else {
1997 pact = NULL;
1999 ret = get_errno(do_sigaction(arg1, pact, &oact));
2000 if (!is_error(ret) && old_oact) {
2001 old_oact->_sa_handler = oact._sa_handler;
2002 old_oact->sa_mask = oact.sa_mask.sig[0];
2003 old_oact->sa_flags = oact.sa_flags;
2004 old_oact->sa_restorer = oact.sa_restorer;
2007 break;
2008 case TARGET_NR_rt_sigaction:
2009 ret = get_errno(do_sigaction(arg1, (void *)arg2, (void *)arg3));
2010 break;
2011 case TARGET_NR_sgetmask:
2013 sigset_t cur_set;
2014 target_ulong target_set;
2015 sigprocmask(0, NULL, &cur_set);
2016 host_to_target_old_sigset(&target_set, &cur_set);
2017 ret = target_set;
2019 break;
2020 case TARGET_NR_ssetmask:
2022 sigset_t set, oset, cur_set;
2023 target_ulong target_set = arg1;
2024 sigprocmask(0, NULL, &cur_set);
2025 target_to_host_old_sigset(&set, &target_set);
2026 sigorset(&set, &set, &cur_set);
2027 sigprocmask(SIG_SETMASK, &set, &oset);
2028 host_to_target_old_sigset(&target_set, &oset);
2029 ret = target_set;
2031 break;
2032 case TARGET_NR_sigprocmask:
2034 int how = arg1;
2035 sigset_t set, oldset, *set_ptr;
2036 target_ulong *pset = (void *)arg2, *poldset = (void *)arg3;
2038 if (pset) {
2039 switch(how) {
2040 case TARGET_SIG_BLOCK:
2041 how = SIG_BLOCK;
2042 break;
2043 case TARGET_SIG_UNBLOCK:
2044 how = SIG_UNBLOCK;
2045 break;
2046 case TARGET_SIG_SETMASK:
2047 how = SIG_SETMASK;
2048 break;
2049 default:
2050 ret = -EINVAL;
2051 goto fail;
2053 target_to_host_old_sigset(&set, pset);
2054 set_ptr = &set;
2055 } else {
2056 how = 0;
2057 set_ptr = NULL;
2059 ret = get_errno(sigprocmask(arg1, set_ptr, &oldset));
2060 if (!is_error(ret) && poldset) {
2061 host_to_target_old_sigset(poldset, &oldset);
2064 break;
2065 case TARGET_NR_rt_sigprocmask:
2067 int how = arg1;
2068 sigset_t set, oldset, *set_ptr;
2069 target_sigset_t *pset = (void *)arg2;
2070 target_sigset_t *poldset = (void *)arg3;
2072 if (pset) {
2073 switch(how) {
2074 case TARGET_SIG_BLOCK:
2075 how = SIG_BLOCK;
2076 break;
2077 case TARGET_SIG_UNBLOCK:
2078 how = SIG_UNBLOCK;
2079 break;
2080 case TARGET_SIG_SETMASK:
2081 how = SIG_SETMASK;
2082 break;
2083 default:
2084 ret = -EINVAL;
2085 goto fail;
2087 target_to_host_sigset(&set, pset);
2088 set_ptr = &set;
2089 } else {
2090 how = 0;
2091 set_ptr = NULL;
2093 ret = get_errno(sigprocmask(how, set_ptr, &oldset));
2094 if (!is_error(ret) && poldset) {
2095 host_to_target_sigset(poldset, &oldset);
2098 break;
2099 case TARGET_NR_sigpending:
2101 sigset_t set;
2102 ret = get_errno(sigpending(&set));
2103 if (!is_error(ret)) {
2104 host_to_target_old_sigset((target_ulong *)arg1, &set);
2107 break;
2108 case TARGET_NR_rt_sigpending:
2110 sigset_t set;
2111 ret = get_errno(sigpending(&set));
2112 if (!is_error(ret)) {
2113 host_to_target_sigset((target_sigset_t *)arg1, &set);
2116 break;
2117 case TARGET_NR_sigsuspend:
2119 sigset_t set;
2120 target_to_host_old_sigset(&set, (target_ulong *)arg1);
2121 ret = get_errno(sigsuspend(&set));
2123 break;
2124 case TARGET_NR_rt_sigsuspend:
2126 sigset_t set;
2127 target_to_host_sigset(&set, (target_sigset_t *)arg1);
2128 ret = get_errno(sigsuspend(&set));
2130 break;
2131 case TARGET_NR_rt_sigtimedwait:
2133 target_sigset_t *target_set = (void *)arg1;
2134 target_siginfo_t *target_uinfo = (void *)arg2;
2135 struct target_timespec *target_uts = (void *)arg3;
2136 sigset_t set;
2137 struct timespec uts, *puts;
2138 siginfo_t uinfo;
2140 target_to_host_sigset(&set, target_set);
2141 if (target_uts) {
2142 puts = &uts;
2143 puts->tv_sec = tswapl(target_uts->tv_sec);
2144 puts->tv_nsec = tswapl(target_uts->tv_nsec);
2145 } else {
2146 puts = NULL;
2148 ret = get_errno(sigtimedwait(&set, &uinfo, puts));
2149 if (!is_error(ret) && target_uinfo) {
2150 host_to_target_siginfo(target_uinfo, &uinfo);
2153 break;
2154 case TARGET_NR_rt_sigqueueinfo:
2156 siginfo_t uinfo;
2157 target_to_host_siginfo(&uinfo, (target_siginfo_t *)arg3);
2158 ret = get_errno(sys_rt_sigqueueinfo(arg1, arg2, &uinfo));
2160 break;
2161 case TARGET_NR_sigreturn:
2162 /* NOTE: ret is eax, so not transcoding must be done */
2163 ret = do_sigreturn(cpu_env);
2164 break;
2165 case TARGET_NR_rt_sigreturn:
2166 /* NOTE: ret is eax, so not transcoding must be done */
2167 ret = do_rt_sigreturn(cpu_env);
2168 break;
2169 case TARGET_NR_sethostname:
2170 ret = get_errno(sethostname((const char *)arg1, arg2));
2171 break;
2172 case TARGET_NR_setrlimit:
2174 /* XXX: convert resource ? */
2175 int resource = arg1;
2176 struct target_rlimit *target_rlim = (void *)arg2;
2177 struct rlimit rlim;
2178 rlim.rlim_cur = tswapl(target_rlim->rlim_cur);
2179 rlim.rlim_max = tswapl(target_rlim->rlim_max);
2180 ret = get_errno(setrlimit(resource, &rlim));
2182 break;
2183 case TARGET_NR_getrlimit:
2185 /* XXX: convert resource ? */
2186 int resource = arg1;
2187 struct target_rlimit *target_rlim = (void *)arg2;
2188 struct rlimit rlim;
2190 ret = get_errno(getrlimit(resource, &rlim));
2191 if (!is_error(ret)) {
2192 target_rlim->rlim_cur = tswapl(rlim.rlim_cur);
2193 target_rlim->rlim_max = tswapl(rlim.rlim_max);
2196 break;
2197 case TARGET_NR_getrusage:
2199 struct rusage rusage;
2200 struct target_rusage *target_rusage = (void *)arg2;
2201 ret = get_errno(getrusage(arg1, &rusage));
2202 if (!is_error(ret)) {
2203 host_to_target_rusage(target_rusage, &rusage);
2206 break;
2207 case TARGET_NR_gettimeofday:
2209 struct target_timeval *target_tv = (void *)arg1;
2210 struct timeval tv;
2211 ret = get_errno(gettimeofday(&tv, NULL));
2212 if (!is_error(ret)) {
2213 host_to_target_timeval(target_tv, &tv);
2216 break;
2217 case TARGET_NR_settimeofday:
2219 struct target_timeval *target_tv = (void *)arg1;
2220 struct timeval tv;
2221 target_to_host_timeval(&tv, target_tv);
2222 ret = get_errno(settimeofday(&tv, NULL));
2224 break;
2225 #ifdef TARGET_NR_select
2226 case TARGET_NR_select:
2228 struct target_sel_arg_struct *sel = (void *)arg1;
2229 sel->n = tswapl(sel->n);
2230 sel->inp = tswapl(sel->inp);
2231 sel->outp = tswapl(sel->outp);
2232 sel->exp = tswapl(sel->exp);
2233 sel->tvp = tswapl(sel->tvp);
2234 ret = do_select(sel->n, (void *)sel->inp, (void *)sel->outp,
2235 (void *)sel->exp, (void *)sel->tvp);
2237 break;
2238 #endif
2239 case TARGET_NR_symlink:
2240 ret = get_errno(symlink((const char *)arg1, (const char *)arg2));
2241 break;
2242 #ifdef TARGET_NR_oldlstat
2243 case TARGET_NR_oldlstat:
2244 goto unimplemented;
2245 #endif
2246 case TARGET_NR_readlink:
2247 ret = get_errno(readlink(path((const char *)arg1), (char *)arg2, arg3));
2248 break;
2249 case TARGET_NR_uselib:
2250 goto unimplemented;
2251 case TARGET_NR_swapon:
2252 ret = get_errno(swapon((const char *)arg1, arg2));
2253 break;
2254 case TARGET_NR_reboot:
2255 goto unimplemented;
2256 case TARGET_NR_readdir:
2257 goto unimplemented;
2258 case TARGET_NR_mmap:
2259 #if defined(TARGET_I386) || defined(TARGET_ARM)
2261 uint32_t v1, v2, v3, v4, v5, v6, *vptr;
2262 vptr = (uint32_t *)arg1;
2263 v1 = tswap32(vptr[0]);
2264 v2 = tswap32(vptr[1]);
2265 v3 = tswap32(vptr[2]);
2266 v4 = tswap32(vptr[3]);
2267 v5 = tswap32(vptr[4]);
2268 v6 = tswap32(vptr[5]);
2269 ret = get_errno(target_mmap(v1, v2, v3,
2270 target_to_host_bitmask(v4, mmap_flags_tbl),
2271 v5, v6));
2273 #else
2274 ret = get_errno(target_mmap(arg1, arg2, arg3,
2275 target_to_host_bitmask(arg4, mmap_flags_tbl),
2276 arg5,
2277 arg6));
2278 #endif
2279 break;
2280 #ifdef TARGET_NR_mmap2
2281 case TARGET_NR_mmap2:
2282 #if defined(TARGET_SPARC)
2283 #define MMAP_SHIFT 12
2284 #else
2285 #define MMAP_SHIFT TARGET_PAGE_BITS
2286 #endif
2287 ret = get_errno(target_mmap(arg1, arg2, arg3,
2288 target_to_host_bitmask(arg4, mmap_flags_tbl),
2289 arg5,
2290 arg6 << MMAP_SHIFT));
2291 break;
2292 #endif
2293 case TARGET_NR_munmap:
2294 ret = get_errno(target_munmap(arg1, arg2));
2295 break;
2296 case TARGET_NR_mprotect:
2297 ret = get_errno(target_mprotect(arg1, arg2, arg3));
2298 break;
2299 case TARGET_NR_mremap:
2300 ret = get_errno(target_mremap(arg1, arg2, arg3, arg4, arg5));
2301 break;
2302 case TARGET_NR_msync:
2303 ret = get_errno(msync((void *)arg1, arg2, arg3));
2304 break;
2305 case TARGET_NR_mlock:
2306 ret = get_errno(mlock((void *)arg1, arg2));
2307 break;
2308 case TARGET_NR_munlock:
2309 ret = get_errno(munlock((void *)arg1, arg2));
2310 break;
2311 case TARGET_NR_mlockall:
2312 ret = get_errno(mlockall(arg1));
2313 break;
2314 case TARGET_NR_munlockall:
2315 ret = get_errno(munlockall());
2316 break;
2317 case TARGET_NR_truncate:
2318 ret = get_errno(truncate((const char *)arg1, arg2));
2319 break;
2320 case TARGET_NR_ftruncate:
2321 ret = get_errno(ftruncate(arg1, arg2));
2322 break;
2323 case TARGET_NR_fchmod:
2324 ret = get_errno(fchmod(arg1, arg2));
2325 break;
2326 case TARGET_NR_getpriority:
2327 ret = get_errno(getpriority(arg1, arg2));
2328 break;
2329 case TARGET_NR_setpriority:
2330 ret = get_errno(setpriority(arg1, arg2, arg3));
2331 break;
2332 #ifdef TARGET_NR_profil
2333 case TARGET_NR_profil:
2334 goto unimplemented;
2335 #endif
2336 case TARGET_NR_statfs:
2337 ret = get_errno(statfs(path((const char *)arg1), &stfs));
2338 convert_statfs:
2339 if (!is_error(ret)) {
2340 struct target_statfs *target_stfs = (void *)arg2;
2342 put_user(stfs.f_type, &target_stfs->f_type);
2343 put_user(stfs.f_bsize, &target_stfs->f_bsize);
2344 put_user(stfs.f_blocks, &target_stfs->f_blocks);
2345 put_user(stfs.f_bfree, &target_stfs->f_bfree);
2346 put_user(stfs.f_bavail, &target_stfs->f_bavail);
2347 put_user(stfs.f_files, &target_stfs->f_files);
2348 put_user(stfs.f_ffree, &target_stfs->f_ffree);
2349 put_user(stfs.f_fsid.__val[0], &target_stfs->f_fsid);
2350 put_user(stfs.f_namelen, &target_stfs->f_namelen);
2352 break;
2353 case TARGET_NR_fstatfs:
2354 ret = get_errno(fstatfs(arg1, &stfs));
2355 goto convert_statfs;
2356 #ifdef TARGET_NR_statfs64
2357 case TARGET_NR_statfs64:
2358 ret = get_errno(statfs(path((const char *)arg1), &stfs));
2359 convert_statfs64:
2360 if (!is_error(ret)) {
2361 struct target_statfs64 *target_stfs = (void *)arg3;
2363 put_user(stfs.f_type, &target_stfs->f_type);
2364 put_user(stfs.f_bsize, &target_stfs->f_bsize);
2365 put_user(stfs.f_blocks, &target_stfs->f_blocks);
2366 put_user(stfs.f_bfree, &target_stfs->f_bfree);
2367 put_user(stfs.f_bavail, &target_stfs->f_bavail);
2368 put_user(stfs.f_files, &target_stfs->f_files);
2369 put_user(stfs.f_ffree, &target_stfs->f_ffree);
2370 put_user(stfs.f_fsid.__val[0], &target_stfs->f_fsid);
2371 put_user(stfs.f_namelen, &target_stfs->f_namelen);
2373 break;
2374 case TARGET_NR_fstatfs64:
2375 ret = get_errno(fstatfs(arg1, &stfs));
2376 goto convert_statfs64;
2377 #endif
2378 #ifdef TARGET_NR_ioperm
2379 case TARGET_NR_ioperm:
2380 goto unimplemented;
2381 #endif
2382 case TARGET_NR_socketcall:
2383 ret = do_socketcall(arg1, (int32_t *)arg2);
2384 break;
2385 case TARGET_NR_syslog:
2386 goto unimplemented;
2387 case TARGET_NR_setitimer:
2389 struct target_itimerval *target_value = (void *)arg2;
2390 struct target_itimerval *target_ovalue = (void *)arg3;
2391 struct itimerval value, ovalue, *pvalue;
2393 if (target_value) {
2394 pvalue = &value;
2395 target_to_host_timeval(&pvalue->it_interval,
2396 &target_value->it_interval);
2397 target_to_host_timeval(&pvalue->it_value,
2398 &target_value->it_value);
2399 } else {
2400 pvalue = NULL;
2402 ret = get_errno(setitimer(arg1, pvalue, &ovalue));
2403 if (!is_error(ret) && target_ovalue) {
2404 host_to_target_timeval(&target_ovalue->it_interval,
2405 &ovalue.it_interval);
2406 host_to_target_timeval(&target_ovalue->it_value,
2407 &ovalue.it_value);
2410 break;
2411 case TARGET_NR_getitimer:
2413 struct target_itimerval *target_value = (void *)arg2;
2414 struct itimerval value;
2416 ret = get_errno(getitimer(arg1, &value));
2417 if (!is_error(ret) && target_value) {
2418 host_to_target_timeval(&target_value->it_interval,
2419 &value.it_interval);
2420 host_to_target_timeval(&target_value->it_value,
2421 &value.it_value);
2424 break;
2425 case TARGET_NR_stat:
2426 ret = get_errno(stat(path((const char *)arg1), &st));
2427 goto do_stat;
2428 case TARGET_NR_lstat:
2429 ret = get_errno(lstat(path((const char *)arg1), &st));
2430 goto do_stat;
2431 case TARGET_NR_fstat:
2433 ret = get_errno(fstat(arg1, &st));
2434 do_stat:
2435 if (!is_error(ret)) {
2436 struct target_stat *target_st = (void *)arg2;
2437 target_st->st_dev = tswap16(st.st_dev);
2438 target_st->st_ino = tswapl(st.st_ino);
2439 #if defined(TARGET_PPC)
2440 target_st->st_mode = tswapl(st.st_mode); /* XXX: check this */
2441 target_st->st_uid = tswap32(st.st_uid);
2442 target_st->st_gid = tswap32(st.st_gid);
2443 #else
2444 target_st->st_mode = tswap16(st.st_mode);
2445 target_st->st_uid = tswap16(st.st_uid);
2446 target_st->st_gid = tswap16(st.st_gid);
2447 #endif
2448 target_st->st_nlink = tswap16(st.st_nlink);
2449 target_st->st_rdev = tswap16(st.st_rdev);
2450 target_st->st_size = tswapl(st.st_size);
2451 target_st->st_blksize = tswapl(st.st_blksize);
2452 target_st->st_blocks = tswapl(st.st_blocks);
2453 target_st->target_st_atime = tswapl(st.st_atime);
2454 target_st->target_st_mtime = tswapl(st.st_mtime);
2455 target_st->target_st_ctime = tswapl(st.st_ctime);
2458 break;
2459 #ifdef TARGET_NR_olduname
2460 case TARGET_NR_olduname:
2461 goto unimplemented;
2462 #endif
2463 #ifdef TARGET_NR_iopl
2464 case TARGET_NR_iopl:
2465 goto unimplemented;
2466 #endif
2467 case TARGET_NR_vhangup:
2468 ret = get_errno(vhangup());
2469 break;
2470 #ifdef TARGET_NR_idle
2471 case TARGET_NR_idle:
2472 goto unimplemented;
2473 #endif
2474 #ifdef TARGET_NR_syscall
2475 case TARGET_NR_syscall:
2476 ret = do_syscall(cpu_env,arg1 & 0xffff,arg2,arg3,arg4,arg5,arg6,0);
2477 break;
2478 #endif
2479 case TARGET_NR_wait4:
2481 int status;
2482 target_long *status_ptr = (void *)arg2;
2483 struct rusage rusage, *rusage_ptr;
2484 struct target_rusage *target_rusage = (void *)arg4;
2485 if (target_rusage)
2486 rusage_ptr = &rusage;
2487 else
2488 rusage_ptr = NULL;
2489 ret = get_errno(wait4(arg1, &status, arg3, rusage_ptr));
2490 if (!is_error(ret)) {
2491 if (status_ptr)
2492 *status_ptr = tswap32(status);
2493 if (target_rusage) {
2494 host_to_target_rusage(target_rusage, &rusage);
2498 break;
2499 case TARGET_NR_swapoff:
2500 ret = get_errno(swapoff((const char *)arg1));
2501 break;
2502 case TARGET_NR_sysinfo:
2504 struct target_sysinfo *target_value = (void *)arg1;
2505 struct sysinfo value;
2506 ret = get_errno(sysinfo(&value));
2507 if (!is_error(ret) && target_value)
2509 __put_user(value.uptime, &target_value->uptime);
2510 __put_user(value.loads[0], &target_value->loads[0]);
2511 __put_user(value.loads[1], &target_value->loads[1]);
2512 __put_user(value.loads[2], &target_value->loads[2]);
2513 __put_user(value.totalram, &target_value->totalram);
2514 __put_user(value.freeram, &target_value->freeram);
2515 __put_user(value.sharedram, &target_value->sharedram);
2516 __put_user(value.bufferram, &target_value->bufferram);
2517 __put_user(value.totalswap, &target_value->totalswap);
2518 __put_user(value.freeswap, &target_value->freeswap);
2519 __put_user(value.procs, &target_value->procs);
2520 __put_user(value.totalhigh, &target_value->totalhigh);
2521 __put_user(value.freehigh, &target_value->freehigh);
2522 __put_user(value.mem_unit, &target_value->mem_unit);
2525 break;
2526 case TARGET_NR_ipc:
2527 ret = do_ipc(arg1, arg2, arg3, arg4, arg5, arg6);
2528 break;
2529 case TARGET_NR_fsync:
2530 ret = get_errno(fsync(arg1));
2531 break;
2532 case TARGET_NR_clone:
2533 ret = get_errno(do_fork(cpu_env, arg1, arg2));
2534 break;
2535 #ifdef __NR_exit_group
2536 /* new thread calls */
2537 case TARGET_NR_exit_group:
2538 gdb_exit(cpu_env, arg1);
2539 ret = get_errno(exit_group(arg1));
2540 break;
2541 #endif
2542 case TARGET_NR_setdomainname:
2543 ret = get_errno(setdomainname((const char *)arg1, arg2));
2544 break;
2545 case TARGET_NR_uname:
2546 /* no need to transcode because we use the linux syscall */
2548 struct new_utsname * buf;
2550 buf = (struct new_utsname *)arg1;
2551 ret = get_errno(sys_uname(buf));
2552 if (!is_error(ret)) {
2553 /* Overrite the native machine name with whatever is being
2554 emulated. */
2555 strcpy (buf->machine, UNAME_MACHINE);
2558 break;
2559 #ifdef TARGET_I386
2560 case TARGET_NR_modify_ldt:
2561 ret = get_errno(do_modify_ldt(cpu_env, arg1, (void *)arg2, arg3));
2562 break;
2563 case TARGET_NR_vm86old:
2564 goto unimplemented;
2565 case TARGET_NR_vm86:
2566 ret = do_vm86(cpu_env, arg1, (void *)arg2);
2567 break;
2568 #endif
2569 case TARGET_NR_adjtimex:
2570 goto unimplemented;
2571 case TARGET_NR_create_module:
2572 case TARGET_NR_init_module:
2573 case TARGET_NR_delete_module:
2574 case TARGET_NR_get_kernel_syms:
2575 goto unimplemented;
2576 case TARGET_NR_quotactl:
2577 goto unimplemented;
2578 case TARGET_NR_getpgid:
2579 ret = get_errno(getpgid(arg1));
2580 break;
2581 case TARGET_NR_fchdir:
2582 ret = get_errno(fchdir(arg1));
2583 break;
2584 case TARGET_NR_bdflush:
2585 goto unimplemented;
2586 case TARGET_NR_sysfs:
2587 goto unimplemented;
2588 case TARGET_NR_personality:
2589 ret = get_errno(personality(arg1));
2590 break;
2591 case TARGET_NR_afs_syscall:
2592 goto unimplemented;
2593 case TARGET_NR__llseek:
2595 #if defined (__x86_64__)
2596 ret = get_errno(lseek(arg1, ((uint64_t )arg2 << 32) | arg3, arg5));
2597 *(int64_t *)arg4 = ret;
2598 #else
2599 int64_t res;
2600 ret = get_errno(_llseek(arg1, arg2, arg3, &res, arg5));
2601 *(int64_t *)arg4 = tswap64(res);
2602 #endif
2604 break;
2605 case TARGET_NR_getdents:
2606 #if TARGET_LONG_SIZE != 4
2607 #warning not supported
2608 #elif TARGET_LONG_SIZE == 4 && HOST_LONG_SIZE == 8
2610 struct target_dirent *target_dirp = (void *)arg2;
2611 struct dirent *dirp;
2612 long count = arg3;
2614 dirp = malloc(count);
2615 if (!dirp)
2616 return -ENOMEM;
2618 ret = get_errno(sys_getdents(arg1, dirp, count));
2619 if (!is_error(ret)) {
2620 struct dirent *de;
2621 struct target_dirent *tde;
2622 int len = ret;
2623 int reclen, treclen;
2624 int count1, tnamelen;
2626 count1 = 0;
2627 de = dirp;
2628 tde = target_dirp;
2629 while (len > 0) {
2630 reclen = de->d_reclen;
2631 treclen = reclen - (2 * (sizeof(long) - sizeof(target_long)));
2632 tde->d_reclen = tswap16(treclen);
2633 tde->d_ino = tswapl(de->d_ino);
2634 tde->d_off = tswapl(de->d_off);
2635 tnamelen = treclen - (2 * sizeof(target_long) + 2);
2636 if (tnamelen > 256)
2637 tnamelen = 256;
2638 /* XXX: may not be correct */
2639 strncpy(tde->d_name, de->d_name, tnamelen);
2640 de = (struct dirent *)((char *)de + reclen);
2641 len -= reclen;
2642 tde = (struct dirent *)((char *)tde + treclen);
2643 count1 += treclen;
2645 ret = count1;
2647 free(dirp);
2649 #else
2651 struct dirent *dirp = (void *)arg2;
2652 long count = arg3;
2654 ret = get_errno(sys_getdents(arg1, dirp, count));
2655 if (!is_error(ret)) {
2656 struct dirent *de;
2657 int len = ret;
2658 int reclen;
2659 de = dirp;
2660 while (len > 0) {
2661 reclen = de->d_reclen;
2662 if (reclen > len)
2663 break;
2664 de->d_reclen = tswap16(reclen);
2665 tswapls(&de->d_ino);
2666 tswapls(&de->d_off);
2667 de = (struct dirent *)((char *)de + reclen);
2668 len -= reclen;
2672 #endif
2673 break;
2674 #ifdef TARGET_NR_getdents64
2675 case TARGET_NR_getdents64:
2677 struct dirent64 *dirp = (void *)arg2;
2678 long count = arg3;
2679 ret = get_errno(sys_getdents64(arg1, dirp, count));
2680 if (!is_error(ret)) {
2681 struct dirent64 *de;
2682 int len = ret;
2683 int reclen;
2684 de = dirp;
2685 while (len > 0) {
2686 reclen = de->d_reclen;
2687 if (reclen > len)
2688 break;
2689 de->d_reclen = tswap16(reclen);
2690 tswap64s(&de->d_ino);
2691 tswap64s(&de->d_off);
2692 de = (struct dirent64 *)((char *)de + reclen);
2693 len -= reclen;
2697 break;
2698 #endif /* TARGET_NR_getdents64 */
2699 case TARGET_NR__newselect:
2700 ret = do_select(arg1, (void *)arg2, (void *)arg3, (void *)arg4,
2701 (void *)arg5);
2702 break;
2703 case TARGET_NR_poll:
2705 struct target_pollfd *target_pfd = (void *)arg1;
2706 unsigned int nfds = arg2;
2707 int timeout = arg3;
2708 struct pollfd *pfd;
2709 unsigned int i;
2711 pfd = alloca(sizeof(struct pollfd) * nfds);
2712 for(i = 0; i < nfds; i++) {
2713 pfd[i].fd = tswap32(target_pfd[i].fd);
2714 pfd[i].events = tswap16(target_pfd[i].events);
2716 ret = get_errno(poll(pfd, nfds, timeout));
2717 if (!is_error(ret)) {
2718 for(i = 0; i < nfds; i++) {
2719 target_pfd[i].revents = tswap16(pfd[i].revents);
2723 break;
2724 case TARGET_NR_flock:
2725 /* NOTE: the flock constant seems to be the same for every
2726 Linux platform */
2727 ret = get_errno(flock(arg1, arg2));
2728 break;
2729 case TARGET_NR_readv:
2731 int count = arg3;
2732 int i;
2733 struct iovec *vec;
2734 struct target_iovec *target_vec = (void *)arg2;
2736 vec = alloca(count * sizeof(struct iovec));
2737 for(i = 0;i < count; i++) {
2738 vec[i].iov_base = (void *)tswapl(target_vec[i].iov_base);
2739 vec[i].iov_len = tswapl(target_vec[i].iov_len);
2741 ret = get_errno(readv(arg1, vec, count));
2743 break;
2744 case TARGET_NR_writev:
2746 int count = arg3;
2747 int i;
2748 struct iovec *vec;
2749 struct target_iovec *target_vec = (void *)arg2;
2751 vec = alloca(count * sizeof(struct iovec));
2752 for(i = 0;i < count; i++) {
2753 vec[i].iov_base = (void *)tswapl(target_vec[i].iov_base);
2754 vec[i].iov_len = tswapl(target_vec[i].iov_len);
2756 ret = get_errno(writev(arg1, vec, count));
2758 break;
2759 case TARGET_NR_getsid:
2760 ret = get_errno(getsid(arg1));
2761 break;
2762 case TARGET_NR_fdatasync:
2763 ret = get_errno(fdatasync(arg1));
2764 break;
2765 case TARGET_NR__sysctl:
2766 /* We don't implement this, but ENODIR is always a safe
2767 return value. */
2768 return -ENOTDIR;
2769 case TARGET_NR_sched_setparam:
2771 struct sched_param *target_schp = (void *)arg2;
2772 struct sched_param schp;
2773 schp.sched_priority = tswap32(target_schp->sched_priority);
2774 ret = get_errno(sched_setparam(arg1, &schp));
2776 break;
2777 case TARGET_NR_sched_getparam:
2779 struct sched_param *target_schp = (void *)arg2;
2780 struct sched_param schp;
2781 ret = get_errno(sched_getparam(arg1, &schp));
2782 if (!is_error(ret)) {
2783 target_schp->sched_priority = tswap32(schp.sched_priority);
2786 break;
2787 case TARGET_NR_sched_setscheduler:
2789 struct sched_param *target_schp = (void *)arg3;
2790 struct sched_param schp;
2791 schp.sched_priority = tswap32(target_schp->sched_priority);
2792 ret = get_errno(sched_setscheduler(arg1, arg2, &schp));
2794 break;
2795 case TARGET_NR_sched_getscheduler:
2796 ret = get_errno(sched_getscheduler(arg1));
2797 break;
2798 case TARGET_NR_sched_yield:
2799 ret = get_errno(sched_yield());
2800 break;
2801 case TARGET_NR_sched_get_priority_max:
2802 ret = get_errno(sched_get_priority_max(arg1));
2803 break;
2804 case TARGET_NR_sched_get_priority_min:
2805 ret = get_errno(sched_get_priority_min(arg1));
2806 break;
2807 case TARGET_NR_sched_rr_get_interval:
2809 struct target_timespec *target_ts = (void *)arg2;
2810 struct timespec ts;
2811 ret = get_errno(sched_rr_get_interval(arg1, &ts));
2812 if (!is_error(ret)) {
2813 target_ts->tv_sec = tswapl(ts.tv_sec);
2814 target_ts->tv_nsec = tswapl(ts.tv_nsec);
2817 break;
2818 case TARGET_NR_nanosleep:
2820 struct target_timespec *target_req = (void *)arg1;
2821 struct target_timespec *target_rem = (void *)arg2;
2822 struct timespec req, rem;
2823 req.tv_sec = tswapl(target_req->tv_sec);
2824 req.tv_nsec = tswapl(target_req->tv_nsec);
2825 ret = get_errno(nanosleep(&req, &rem));
2826 if (is_error(ret) && target_rem) {
2827 target_rem->tv_sec = tswapl(rem.tv_sec);
2828 target_rem->tv_nsec = tswapl(rem.tv_nsec);
2831 break;
2832 case TARGET_NR_query_module:
2833 goto unimplemented;
2834 case TARGET_NR_nfsservctl:
2835 goto unimplemented;
2836 case TARGET_NR_prctl:
2837 goto unimplemented;
2838 #ifdef TARGET_NR_pread
2839 case TARGET_NR_pread:
2840 page_unprotect_range((void *)arg2, arg3);
2841 ret = get_errno(pread(arg1, (void *)arg2, arg3, arg4));
2842 break;
2843 case TARGET_NR_pwrite:
2844 ret = get_errno(pwrite(arg1, (void *)arg2, arg3, arg4));
2845 break;
2846 #endif
2847 case TARGET_NR_getcwd:
2848 ret = get_errno(sys_getcwd1((char *)arg1, arg2));
2849 break;
2850 case TARGET_NR_capget:
2851 goto unimplemented;
2852 case TARGET_NR_capset:
2853 goto unimplemented;
2854 case TARGET_NR_sigaltstack:
2855 goto unimplemented;
2856 case TARGET_NR_sendfile:
2857 goto unimplemented;
2858 #ifdef TARGET_NR_getpmsg
2859 case TARGET_NR_getpmsg:
2860 goto unimplemented;
2861 #endif
2862 #ifdef TARGET_NR_putpmsg
2863 case TARGET_NR_putpmsg:
2864 goto unimplemented;
2865 #endif
2866 #ifdef TARGET_NR_vfork
2867 case TARGET_NR_vfork:
2868 ret = get_errno(do_fork(cpu_env, CLONE_VFORK | CLONE_VM | SIGCHLD, 0));
2869 break;
2870 #endif
2871 #ifdef TARGET_NR_ugetrlimit
2872 case TARGET_NR_ugetrlimit:
2874 struct rlimit rlim;
2875 ret = get_errno(getrlimit(arg1, &rlim));
2876 if (!is_error(ret)) {
2877 struct target_rlimit *target_rlim = (void *)arg2;
2878 target_rlim->rlim_cur = tswapl(rlim.rlim_cur);
2879 target_rlim->rlim_max = tswapl(rlim.rlim_max);
2881 break;
2883 #endif
2884 #ifdef TARGET_NR_truncate64
2885 case TARGET_NR_truncate64:
2886 ret = target_truncate64(cpu_env, (const char *)arg1, arg2, arg3, arg4);
2887 break;
2888 #endif
2889 #ifdef TARGET_NR_ftruncate64
2890 case TARGET_NR_ftruncate64:
2891 ret = target_ftruncate64(cpu_env, arg1, arg2, arg3, arg4);
2892 break;
2893 #endif
2894 #ifdef TARGET_NR_stat64
2895 case TARGET_NR_stat64:
2896 ret = get_errno(stat(path((const char *)arg1), &st));
2897 goto do_stat64;
2898 #endif
2899 #ifdef TARGET_NR_lstat64
2900 case TARGET_NR_lstat64:
2901 ret = get_errno(lstat(path((const char *)arg1), &st));
2902 goto do_stat64;
2903 #endif
2904 #ifdef TARGET_NR_fstat64
2905 case TARGET_NR_fstat64:
2907 ret = get_errno(fstat(arg1, &st));
2908 do_stat64:
2909 if (!is_error(ret)) {
2910 #ifdef TARGET_ARM
2911 if (((CPUARMState *)cpu_env)->eabi) {
2912 struct target_eabi_stat64 *target_st = (void *)arg2;
2913 memset(target_st, 0, sizeof(struct target_eabi_stat64));
2914 put_user(st.st_dev, &target_st->st_dev);
2915 put_user(st.st_ino, &target_st->st_ino);
2916 #ifdef TARGET_STAT64_HAS_BROKEN_ST_INO
2917 put_user(st.st_ino, &target_st->__st_ino);
2918 #endif
2919 put_user(st.st_mode, &target_st->st_mode);
2920 put_user(st.st_nlink, &target_st->st_nlink);
2921 put_user(st.st_uid, &target_st->st_uid);
2922 put_user(st.st_gid, &target_st->st_gid);
2923 put_user(st.st_rdev, &target_st->st_rdev);
2924 /* XXX: better use of kernel struct */
2925 put_user(st.st_size, &target_st->st_size);
2926 put_user(st.st_blksize, &target_st->st_blksize);
2927 put_user(st.st_blocks, &target_st->st_blocks);
2928 put_user(st.st_atime, &target_st->target_st_atime);
2929 put_user(st.st_mtime, &target_st->target_st_mtime);
2930 put_user(st.st_ctime, &target_st->target_st_ctime);
2931 } else
2932 #endif
2934 struct target_stat64 *target_st = (void *)arg2;
2935 memset(target_st, 0, sizeof(struct target_stat64));
2936 put_user(st.st_dev, &target_st->st_dev);
2937 put_user(st.st_ino, &target_st->st_ino);
2938 #ifdef TARGET_STAT64_HAS_BROKEN_ST_INO
2939 put_user(st.st_ino, &target_st->__st_ino);
2940 #endif
2941 put_user(st.st_mode, &target_st->st_mode);
2942 put_user(st.st_nlink, &target_st->st_nlink);
2943 put_user(st.st_uid, &target_st->st_uid);
2944 put_user(st.st_gid, &target_st->st_gid);
2945 put_user(st.st_rdev, &target_st->st_rdev);
2946 /* XXX: better use of kernel struct */
2947 put_user(st.st_size, &target_st->st_size);
2948 put_user(st.st_blksize, &target_st->st_blksize);
2949 put_user(st.st_blocks, &target_st->st_blocks);
2950 put_user(st.st_atime, &target_st->target_st_atime);
2951 put_user(st.st_mtime, &target_st->target_st_mtime);
2952 put_user(st.st_ctime, &target_st->target_st_ctime);
2956 break;
2957 #endif
2958 #ifdef USE_UID16
2959 case TARGET_NR_lchown:
2960 ret = get_errno(lchown((const char *)arg1, low2highuid(arg2), low2highgid(arg3)));
2961 break;
2962 case TARGET_NR_getuid:
2963 ret = get_errno(high2lowuid(getuid()));
2964 break;
2965 case TARGET_NR_getgid:
2966 ret = get_errno(high2lowgid(getgid()));
2967 break;
2968 case TARGET_NR_geteuid:
2969 ret = get_errno(high2lowuid(geteuid()));
2970 break;
2971 case TARGET_NR_getegid:
2972 ret = get_errno(high2lowgid(getegid()));
2973 break;
2974 case TARGET_NR_setreuid:
2975 ret = get_errno(setreuid(low2highuid(arg1), low2highuid(arg2)));
2976 break;
2977 case TARGET_NR_setregid:
2978 ret = get_errno(setregid(low2highgid(arg1), low2highgid(arg2)));
2979 break;
2980 case TARGET_NR_getgroups:
2982 int gidsetsize = arg1;
2983 uint16_t *target_grouplist = (void *)arg2;
2984 gid_t *grouplist;
2985 int i;
2987 grouplist = alloca(gidsetsize * sizeof(gid_t));
2988 ret = get_errno(getgroups(gidsetsize, grouplist));
2989 if (!is_error(ret)) {
2990 for(i = 0;i < gidsetsize; i++)
2991 target_grouplist[i] = tswap16(grouplist[i]);
2994 break;
2995 case TARGET_NR_setgroups:
2997 int gidsetsize = arg1;
2998 uint16_t *target_grouplist = (void *)arg2;
2999 gid_t *grouplist;
3000 int i;
3002 grouplist = alloca(gidsetsize * sizeof(gid_t));
3003 for(i = 0;i < gidsetsize; i++)
3004 grouplist[i] = tswap16(target_grouplist[i]);
3005 ret = get_errno(setgroups(gidsetsize, grouplist));
3007 break;
3008 case TARGET_NR_fchown:
3009 ret = get_errno(fchown(arg1, low2highuid(arg2), low2highgid(arg3)));
3010 break;
3011 #ifdef TARGET_NR_setresuid
3012 case TARGET_NR_setresuid:
3013 ret = get_errno(setresuid(low2highuid(arg1),
3014 low2highuid(arg2),
3015 low2highuid(arg3)));
3016 break;
3017 #endif
3018 #ifdef TARGET_NR_getresuid
3019 case TARGET_NR_getresuid:
3021 int ruid, euid, suid;
3022 ret = get_errno(getresuid(&ruid, &euid, &suid));
3023 if (!is_error(ret)) {
3024 *(uint16_t *)arg1 = tswap16(high2lowuid(ruid));
3025 *(uint16_t *)arg2 = tswap16(high2lowuid(euid));
3026 *(uint16_t *)arg3 = tswap16(high2lowuid(suid));
3029 break;
3030 #endif
3031 #ifdef TARGET_NR_getresgid
3032 case TARGET_NR_setresgid:
3033 ret = get_errno(setresgid(low2highgid(arg1),
3034 low2highgid(arg2),
3035 low2highgid(arg3)));
3036 break;
3037 #endif
3038 #ifdef TARGET_NR_getresgid
3039 case TARGET_NR_getresgid:
3041 int rgid, egid, sgid;
3042 ret = get_errno(getresgid(&rgid, &egid, &sgid));
3043 if (!is_error(ret)) {
3044 *(uint16_t *)arg1 = tswap16(high2lowgid(rgid));
3045 *(uint16_t *)arg2 = tswap16(high2lowgid(egid));
3046 *(uint16_t *)arg3 = tswap16(high2lowgid(sgid));
3049 break;
3050 #endif
3051 case TARGET_NR_chown:
3052 ret = get_errno(chown((const char *)arg1, low2highuid(arg2), low2highgid(arg3)));
3053 break;
3054 case TARGET_NR_setuid:
3055 ret = get_errno(setuid(low2highuid(arg1)));
3056 break;
3057 case TARGET_NR_setgid:
3058 ret = get_errno(setgid(low2highgid(arg1)));
3059 break;
3060 case TARGET_NR_setfsuid:
3061 ret = get_errno(setfsuid(arg1));
3062 break;
3063 case TARGET_NR_setfsgid:
3064 ret = get_errno(setfsgid(arg1));
3065 break;
3066 #endif /* USE_UID16 */
3068 #ifdef TARGET_NR_lchown32
3069 case TARGET_NR_lchown32:
3070 ret = get_errno(lchown((const char *)arg1, arg2, arg3));
3071 break;
3072 #endif
3073 #ifdef TARGET_NR_getuid32
3074 case TARGET_NR_getuid32:
3075 ret = get_errno(getuid());
3076 break;
3077 #endif
3078 #ifdef TARGET_NR_getgid32
3079 case TARGET_NR_getgid32:
3080 ret = get_errno(getgid());
3081 break;
3082 #endif
3083 #ifdef TARGET_NR_geteuid32
3084 case TARGET_NR_geteuid32:
3085 ret = get_errno(geteuid());
3086 break;
3087 #endif
3088 #ifdef TARGET_NR_getegid32
3089 case TARGET_NR_getegid32:
3090 ret = get_errno(getegid());
3091 break;
3092 #endif
3093 #ifdef TARGET_NR_setreuid32
3094 case TARGET_NR_setreuid32:
3095 ret = get_errno(setreuid(arg1, arg2));
3096 break;
3097 #endif
3098 #ifdef TARGET_NR_setregid32
3099 case TARGET_NR_setregid32:
3100 ret = get_errno(setregid(arg1, arg2));
3101 break;
3102 #endif
3103 #ifdef TARGET_NR_getgroups32
3104 case TARGET_NR_getgroups32:
3106 int gidsetsize = arg1;
3107 uint32_t *target_grouplist = (void *)arg2;
3108 gid_t *grouplist;
3109 int i;
3111 grouplist = alloca(gidsetsize * sizeof(gid_t));
3112 ret = get_errno(getgroups(gidsetsize, grouplist));
3113 if (!is_error(ret)) {
3114 for(i = 0;i < gidsetsize; i++)
3115 put_user(grouplist[i], &target_grouplist[i]);
3118 break;
3119 #endif
3120 #ifdef TARGET_NR_setgroups32
3121 case TARGET_NR_setgroups32:
3123 int gidsetsize = arg1;
3124 uint32_t *target_grouplist = (void *)arg2;
3125 gid_t *grouplist;
3126 int i;
3128 grouplist = alloca(gidsetsize * sizeof(gid_t));
3129 for(i = 0;i < gidsetsize; i++)
3130 get_user(grouplist[i], &target_grouplist[i]);
3131 ret = get_errno(setgroups(gidsetsize, grouplist));
3133 break;
3134 #endif
3135 #ifdef TARGET_NR_fchown32
3136 case TARGET_NR_fchown32:
3137 ret = get_errno(fchown(arg1, arg2, arg3));
3138 break;
3139 #endif
3140 #ifdef TARGET_NR_setresuid32
3141 case TARGET_NR_setresuid32:
3142 ret = get_errno(setresuid(arg1, arg2, arg3));
3143 break;
3144 #endif
3145 #ifdef TARGET_NR_getresuid32
3146 case TARGET_NR_getresuid32:
3148 int ruid, euid, suid;
3149 ret = get_errno(getresuid(&ruid, &euid, &suid));
3150 if (!is_error(ret)) {
3151 *(uint32_t *)arg1 = tswap32(ruid);
3152 *(uint32_t *)arg2 = tswap32(euid);
3153 *(uint32_t *)arg3 = tswap32(suid);
3156 break;
3157 #endif
3158 #ifdef TARGET_NR_setresgid32
3159 case TARGET_NR_setresgid32:
3160 ret = get_errno(setresgid(arg1, arg2, arg3));
3161 break;
3162 #endif
3163 #ifdef TARGET_NR_getresgid32
3164 case TARGET_NR_getresgid32:
3166 int rgid, egid, sgid;
3167 ret = get_errno(getresgid(&rgid, &egid, &sgid));
3168 if (!is_error(ret)) {
3169 *(uint32_t *)arg1 = tswap32(rgid);
3170 *(uint32_t *)arg2 = tswap32(egid);
3171 *(uint32_t *)arg3 = tswap32(sgid);
3174 break;
3175 #endif
3176 #ifdef TARGET_NR_chown32
3177 case TARGET_NR_chown32:
3178 ret = get_errno(chown((const char *)arg1, arg2, arg3));
3179 break;
3180 #endif
3181 #ifdef TARGET_NR_setuid32
3182 case TARGET_NR_setuid32:
3183 ret = get_errno(setuid(arg1));
3184 break;
3185 #endif
3186 #ifdef TARGET_NR_setgid32
3187 case TARGET_NR_setgid32:
3188 ret = get_errno(setgid(arg1));
3189 break;
3190 #endif
3191 #ifdef TARGET_NR_setfsuid32
3192 case TARGET_NR_setfsuid32:
3193 ret = get_errno(setfsuid(arg1));
3194 break;
3195 #endif
3196 #ifdef TARGET_NR_setfsgid32
3197 case TARGET_NR_setfsgid32:
3198 ret = get_errno(setfsgid(arg1));
3199 break;
3200 #endif
3202 case TARGET_NR_pivot_root:
3203 goto unimplemented;
3204 #ifdef TARGET_NR_mincore
3205 case TARGET_NR_mincore:
3206 goto unimplemented;
3207 #endif
3208 #ifdef TARGET_NR_madvise
3209 case TARGET_NR_madvise:
3210 goto unimplemented;
3211 #endif
3212 #if TARGET_LONG_BITS == 32
3213 case TARGET_NR_fcntl64:
3215 struct flock64 fl;
3216 struct target_flock64 *target_fl = (void *)arg3;
3217 #ifdef TARGET_ARM
3218 struct target_eabi_flock64 *target_efl = (void *)arg3;
3219 #endif
3221 switch(arg2) {
3222 case F_GETLK64:
3223 ret = get_errno(fcntl(arg1, arg2, &fl));
3224 if (ret == 0) {
3225 #ifdef TARGET_ARM
3226 if (((CPUARMState *)cpu_env)->eabi) {
3227 target_efl->l_type = tswap16(fl.l_type);
3228 target_efl->l_whence = tswap16(fl.l_whence);
3229 target_efl->l_start = tswap64(fl.l_start);
3230 target_efl->l_len = tswap64(fl.l_len);
3231 target_efl->l_pid = tswapl(fl.l_pid);
3232 } else
3233 #endif
3235 target_fl->l_type = tswap16(fl.l_type);
3236 target_fl->l_whence = tswap16(fl.l_whence);
3237 target_fl->l_start = tswap64(fl.l_start);
3238 target_fl->l_len = tswap64(fl.l_len);
3239 target_fl->l_pid = tswapl(fl.l_pid);
3242 break;
3244 case F_SETLK64:
3245 case F_SETLKW64:
3246 #ifdef TARGET_ARM
3247 if (((CPUARMState *)cpu_env)->eabi) {
3248 fl.l_type = tswap16(target_efl->l_type);
3249 fl.l_whence = tswap16(target_efl->l_whence);
3250 fl.l_start = tswap64(target_efl->l_start);
3251 fl.l_len = tswap64(target_efl->l_len);
3252 fl.l_pid = tswapl(target_efl->l_pid);
3253 } else
3254 #endif
3256 fl.l_type = tswap16(target_fl->l_type);
3257 fl.l_whence = tswap16(target_fl->l_whence);
3258 fl.l_start = tswap64(target_fl->l_start);
3259 fl.l_len = tswap64(target_fl->l_len);
3260 fl.l_pid = tswapl(target_fl->l_pid);
3262 ret = get_errno(fcntl(arg1, arg2, &fl));
3263 break;
3264 default:
3265 ret = get_errno(do_fcntl(arg1, arg2, arg3));
3266 break;
3268 break;
3270 #endif
3271 #ifdef TARGET_NR_security
3272 case TARGET_NR_security:
3273 goto unimplemented;
3274 #endif
3275 #ifdef TARGET_NR_getpagesize
3276 case TARGET_NR_getpagesize:
3277 ret = TARGET_PAGE_SIZE;
3278 break;
3279 #endif
3280 case TARGET_NR_gettid:
3281 ret = get_errno(gettid());
3282 break;
3283 case TARGET_NR_readahead:
3284 goto unimplemented;
3285 #ifdef TARGET_NR_setxattr
3286 case TARGET_NR_setxattr:
3287 case TARGET_NR_lsetxattr:
3288 case TARGET_NR_fsetxattr:
3289 case TARGET_NR_getxattr:
3290 case TARGET_NR_lgetxattr:
3291 case TARGET_NR_fgetxattr:
3292 case TARGET_NR_listxattr:
3293 case TARGET_NR_llistxattr:
3294 case TARGET_NR_flistxattr:
3295 case TARGET_NR_removexattr:
3296 case TARGET_NR_lremovexattr:
3297 case TARGET_NR_fremovexattr:
3298 goto unimplemented_nowarn;
3299 #endif
3300 #ifdef TARGET_NR_set_thread_area
3301 case TARGET_NR_set_thread_area:
3302 case TARGET_NR_get_thread_area:
3303 goto unimplemented_nowarn;
3304 #endif
3305 default:
3306 unimplemented:
3307 gemu_log("qemu: Unsupported syscall: %d\n", num);
3308 #if defined(TARGET_NR_setxattr) || defined(TARGET_NR_set_thread_area)
3309 unimplemented_nowarn:
3310 #endif
3311 ret = -ENOSYS;
3312 break;
3314 fail:
3315 #ifdef DEBUG
3316 gemu_log(" = %ld\n", ret);
3317 #endif
3318 return ret;