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