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