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