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