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 #ifdef HAVE_GPROF 632 _mcleanup(); 633 #endif 634 _exit(arg1); 635 ret = 0; /* avoid warning */ 636 break; 637 case TARGET_NR_read: 638 ret = get_errno(read(arg1, (void *)arg2, arg3)); 639 break; 640 case TARGET_NR_write: 641 ret = get_errno(write(arg1, (void *)arg2, arg3)); 642 break; 643 case TARGET_NR_open: 644 ret = get_errno(open((const char *)arg1, arg2, arg3)); 645 break; 646 case TARGET_NR_close: 647 ret = get_errno(close(arg1)); 648 break; 649 case TARGET_NR_brk: 650 ret = do_brk((char *)arg1); 651 break; 652 case TARGET_NR_fork: 653 ret = get_errno(fork()); 654 break; 655 case TARGET_NR_waitpid: 656 { 657 int *status = (int *)arg2; 658 ret = get_errno(waitpid(arg1, status, arg3)); 659 if (!is_error(ret) && status) 660 tswapls((long *)&status); 661 } 662 break; 663 case TARGET_NR_creat: 664 ret = get_errno(creat((const char *)arg1, arg2)); 665 break; 666 case TARGET_NR_link: 667 ret = get_errno(link((const char *)arg1, (const char *)arg2)); 668 break; 669 case TARGET_NR_unlink: 670 ret = get_errno(unlink((const char *)arg1)); 671 break; 672 case TARGET_NR_execve: 673 ret = get_errno(execve((const char *)arg1, (void *)arg2, (void *)arg3)); 674 break; 675 case TARGET_NR_chdir: 676 ret = get_errno(chdir((const char *)arg1)); 677 break; 678 case TARGET_NR_time: 679 { 680 int *time_ptr = (int *)arg1; 681 ret = get_errno(time((time_t *)time_ptr)); 682 if (!is_error(ret) && time_ptr) 683 tswap32s(time_ptr); 684 } 685 break; 686 case TARGET_NR_mknod: 687 ret = get_errno(mknod((const char *)arg1, arg2, arg3)); 688 break; 689 case TARGET_NR_chmod: 690 ret = get_errno(chmod((const char *)arg1, arg2)); 691 break; 692 case TARGET_NR_lchown: 693 ret = get_errno(chown((const char *)arg1, arg2, arg3)); 694 break; 695 case TARGET_NR_break: 696 goto unimplemented; 697 case TARGET_NR_oldstat: 698 goto unimplemented; 699 case TARGET_NR_lseek: 700 ret = get_errno(lseek(arg1, arg2, arg3)); 701 break; 702 case TARGET_NR_getpid: 703 ret = get_errno(getpid()); 704 break; 705 case TARGET_NR_mount: 706 /* need to look at the data field */ 707 goto unimplemented; 708 case TARGET_NR_umount: 709 ret = get_errno(umount((const char *)arg1)); 710 break; 711 case TARGET_NR_setuid: 712 ret = get_errno(setuid(arg1)); 713 break; 714 case TARGET_NR_getuid: 715 ret = get_errno(getuid()); 716 break; 717 case TARGET_NR_stime: 718 { 719 int *time_ptr = (int *)arg1; 720 if (time_ptr) 721 tswap32s(time_ptr); 722 ret = get_errno(stime((time_t *)time_ptr)); 723 } 724 break; 725 case TARGET_NR_ptrace: 726 goto unimplemented; 727 case TARGET_NR_alarm: 728 ret = alarm(arg1); 729 break; 730 case TARGET_NR_oldfstat: 731 goto unimplemented; 732 case TARGET_NR_pause: 733 ret = get_errno(pause()); 734 break; 735 case TARGET_NR_utime: 736 goto unimplemented; 737 case TARGET_NR_stty: 738 goto unimplemented; 739 case TARGET_NR_gtty: 740 goto unimplemented; 741 case TARGET_NR_access: 742 ret = get_errno(access((const char *)arg1, arg2)); 743 break; 744 case TARGET_NR_nice: 745 ret = get_errno(nice(arg1)); 746 break; 747 case TARGET_NR_ftime: 748 goto unimplemented; 749 case TARGET_NR_sync: 750 ret = get_errno(sync()); 751 break; 752 case TARGET_NR_kill: 753 ret = get_errno(kill(arg1, arg2)); 754 break; 755 case TARGET_NR_rename: 756 ret = get_errno(rename((const char *)arg1, (const char *)arg2)); 757 break; 758 case TARGET_NR_mkdir: 759 ret = get_errno(mkdir((const char *)arg1, arg2)); 760 break; 761 case TARGET_NR_rmdir: 762 ret = get_errno(rmdir((const char *)arg1)); 763 break; 764 case TARGET_NR_dup: 765 ret = get_errno(dup(arg1)); 766 break; 767 case TARGET_NR_pipe: 768 { 769 int *pipe_ptr = (int *)arg1; 770 ret = get_errno(pipe(pipe_ptr)); 771 if (!is_error(ret)) { 772 tswap32s(&pipe_ptr[0]); 773 tswap32s(&pipe_ptr[1]); 774 } 775 } 776 break; 777 case TARGET_NR_times: 778 goto unimplemented; 779 case TARGET_NR_prof: 780 goto unimplemented; 781 case TARGET_NR_setgid: 782 ret = get_errno(setgid(arg1)); 783 break; 784 case TARGET_NR_getgid: 785 ret = get_errno(getgid()); 786 break; 787 case TARGET_NR_signal: 788 goto unimplemented; 789 case TARGET_NR_geteuid: 790 ret = get_errno(geteuid()); 791 break; 792 case TARGET_NR_getegid: 793 ret = get_errno(getegid()); 794 break; 795 case TARGET_NR_acct: 796 goto unimplemented; 797 case TARGET_NR_umount2: 798 ret = get_errno(umount2((const char *)arg1, arg2)); 799 break; 800 case TARGET_NR_lock: 801 goto unimplemented; 802 case TARGET_NR_ioctl: 803 ret = do_ioctl(arg1, arg2, arg3); 804 break; 805 case TARGET_NR_fcntl: 806 switch(arg2) { 807 case F_GETLK: 808 case F_SETLK: 809 case F_SETLKW: 810 goto unimplemented; 811 default: 812 ret = get_errno(fcntl(arg1, arg2, arg3)); 813 break; 814 } 815 break; 816 case TARGET_NR_mpx: 817 goto unimplemented; 818 case TARGET_NR_setpgid: 819 ret = get_errno(setpgid(arg1, arg2)); 820 break; 821 case TARGET_NR_ulimit: 822 goto unimplemented; 823 case TARGET_NR_oldolduname: 824 goto unimplemented; 825 case TARGET_NR_umask: 826 ret = get_errno(umask(arg1)); 827 break; 828 case TARGET_NR_chroot: 829 ret = get_errno(chroot((const char *)arg1)); 830 break; 831 case TARGET_NR_ustat: 832 goto unimplemented; 833 case TARGET_NR_dup2: 834 ret = get_errno(dup2(arg1, arg2)); 835 break; 836 case TARGET_NR_getppid: 837 ret = get_errno(getppid()); 838 break; 839 case TARGET_NR_getpgrp: 840 ret = get_errno(getpgrp()); 841 break; 842 case TARGET_NR_setsid: 843 ret = get_errno(setsid()); 844 break; 845 case TARGET_NR_sigaction: 846 #if 0 847 { 848 int signum = arg1; 849 struct target_old_sigaction *tact = arg2, *toldact = arg3; 850 ret = get_errno(setsid()); 851 852 853 } 854 break; 855 #else 856 goto unimplemented; 857 #endif 858 case TARGET_NR_sgetmask: 859 goto unimplemented; 860 case TARGET_NR_ssetmask: 861 goto unimplemented; 862 case TARGET_NR_setreuid: 863 ret = get_errno(setreuid(arg1, arg2)); 864 break; 865 case TARGET_NR_setregid: 866 ret = get_errno(setregid(arg1, arg2)); 867 break; 868 case TARGET_NR_sigsuspend: 869 goto unimplemented; 870 case TARGET_NR_sigpending: 871 goto unimplemented; 872 case TARGET_NR_sethostname: 873 ret = get_errno(sethostname((const char *)arg1, arg2)); 874 break; 875 case TARGET_NR_setrlimit: 876 goto unimplemented; 877 case TARGET_NR_getrlimit: 878 goto unimplemented; 879 case TARGET_NR_getrusage: 880 goto unimplemented; 881 case TARGET_NR_gettimeofday: 882 { 883 struct target_timeval *target_tv = (void *)arg1; 884 struct timeval tv; 885 ret = get_errno(gettimeofday(&tv, NULL)); 886 if (!is_error(ret)) { 887 target_tv->tv_sec = tswapl(tv.tv_sec); 888 target_tv->tv_usec = tswapl(tv.tv_usec); 889 } 890 } 891 break; 892 case TARGET_NR_settimeofday: 893 { 894 struct target_timeval *target_tv = (void *)arg1; 895 struct timeval tv; 896 tv.tv_sec = tswapl(target_tv->tv_sec); 897 tv.tv_usec = tswapl(target_tv->tv_usec); 898 ret = get_errno(settimeofday(&tv, NULL)); 899 } 900 break; 901 case TARGET_NR_getgroups: 902 goto unimplemented; 903 case TARGET_NR_setgroups: 904 goto unimplemented; 905 case TARGET_NR_select: 906 goto unimplemented; 907 case TARGET_NR_symlink: 908 ret = get_errno(symlink((const char *)arg1, (const char *)arg2)); 909 break; 910 case TARGET_NR_oldlstat: 911 goto unimplemented; 912 case TARGET_NR_readlink: 913 ret = get_errno(readlink((const char *)arg1, (char *)arg2, arg3)); 914 break; 915 case TARGET_NR_uselib: 916 goto unimplemented; 917 case TARGET_NR_swapon: 918 ret = get_errno(swapon((const char *)arg1, arg2)); 919 break; 920 case TARGET_NR_reboot: 921 goto unimplemented; 922 case TARGET_NR_readdir: 923 goto unimplemented; 924 #ifdef TARGET_I386 925 case TARGET_NR_mmap: 926 { 927 uint32_t v1, v2, v3, v4, v5, v6, *vptr; 928 vptr = (uint32_t *)arg1; 929 v1 = tswap32(vptr[0]); 930 v2 = tswap32(vptr[1]); 931 v3 = tswap32(vptr[2]); 932 v4 = tswap32(vptr[3]); 933 v5 = tswap32(vptr[4]); 934 v6 = tswap32(vptr[5]); 935 ret = get_errno((long)mmap((void *)v1, v2, v3, v4, v5, v6)); 936 } 937 break; 938 #endif 939 #ifdef TARGET_I386 940 case TARGET_NR_mmap2: 941 #else 942 case TARGET_NR_mmap: 943 #endif 944 ret = get_errno((long)mmap((void *)arg1, arg2, arg3, arg4, arg5, arg6)); 945 break; 946 case TARGET_NR_munmap: 947 ret = get_errno(munmap((void *)arg1, arg2)); 948 break; 949 case TARGET_NR_truncate: 950 ret = get_errno(truncate((const char *)arg1, arg2)); 951 break; 952 case TARGET_NR_ftruncate: 953 ret = get_errno(ftruncate(arg1, arg2)); 954 break; 955 case TARGET_NR_fchmod: 956 ret = get_errno(fchmod(arg1, arg2)); 957 break; 958 case TARGET_NR_fchown: 959 ret = get_errno(fchown(arg1, arg2, arg3)); 960 break; 961 case TARGET_NR_getpriority: 962 ret = get_errno(getpriority(arg1, arg2)); 963 break; 964 case TARGET_NR_setpriority: 965 ret = get_errno(setpriority(arg1, arg2, arg3)); 966 break; 967 case TARGET_NR_profil: 968 goto unimplemented; 969 case TARGET_NR_statfs: 970 stfs = (void *)arg2; 971 ret = get_errno(sys_statfs((const char *)arg1, stfs)); 972 convert_statfs: 973 if (!is_error(ret)) { 974 tswap32s(&stfs->f_type); 975 tswap32s(&stfs->f_bsize); 976 tswap32s(&stfs->f_blocks); 977 tswap32s(&stfs->f_bfree); 978 tswap32s(&stfs->f_bavail); 979 tswap32s(&stfs->f_files); 980 tswap32s(&stfs->f_ffree); 981 tswap32s(&stfs->f_fsid.val[0]); 982 tswap32s(&stfs->f_fsid.val[1]); 983 tswap32s(&stfs->f_namelen); 984 } 985 break; 986 case TARGET_NR_fstatfs: 987 stfs = (void *)arg2; 988 ret = get_errno(sys_fstatfs(arg1, stfs)); 989 goto convert_statfs; 990 case TARGET_NR_ioperm: 991 goto unimplemented; 992 case TARGET_NR_socketcall: 993 ret = do_socketcall(arg1, (long *)arg2); 994 break; 995 case TARGET_NR_syslog: 996 goto unimplemented; 997 case TARGET_NR_setitimer: 998 goto unimplemented; 999 case TARGET_NR_getitimer: 1000 goto unimplemented; 1001 case TARGET_NR_stat: 1002 ret = get_errno(stat((const char *)arg1, &st)); 1003 goto do_stat; 1004 case TARGET_NR_lstat: 1005 ret = get_errno(lstat((const char *)arg1, &st)); 1006 goto do_stat; 1007 case TARGET_NR_fstat: 1008 { 1009 ret = get_errno(fstat(arg1, &st)); 1010 do_stat: 1011 if (!is_error(ret)) { 1012 struct target_stat *target_st = (void *)arg2; 1013 target_st->st_dev = tswap16(st.st_dev); 1014 target_st->st_ino = tswapl(st.st_ino); 1015 target_st->st_mode = tswap16(st.st_mode); 1016 target_st->st_nlink = tswap16(st.st_nlink); 1017 target_st->st_uid = tswap16(st.st_uid); 1018 target_st->st_gid = tswap16(st.st_gid); 1019 target_st->st_rdev = tswap16(st.st_rdev); 1020 target_st->st_size = tswapl(st.st_size); 1021 target_st->st_blksize = tswapl(st.st_blksize); 1022 target_st->st_blocks = tswapl(st.st_blocks); 1023 target_st->st_atime = tswapl(st.st_atime); 1024 target_st->st_mtime = tswapl(st.st_mtime); 1025 target_st->st_ctime = tswapl(st.st_ctime); 1026 } 1027 } 1028 break; 1029 case TARGET_NR_olduname: 1030 goto unimplemented; 1031 case TARGET_NR_iopl: 1032 goto unimplemented; 1033 case TARGET_NR_vhangup: 1034 ret = get_errno(vhangup()); 1035 break; 1036 case TARGET_NR_idle: 1037 goto unimplemented; 1038 case TARGET_NR_vm86old: 1039 goto unimplemented; 1040 case TARGET_NR_wait4: 1041 { 1042 int status; 1043 target_long *status_ptr = (void *)arg2; 1044 struct rusage rusage, *rusage_ptr; 1045 struct target_rusage *target_rusage = (void *)arg4; 1046 if (target_rusage) 1047 rusage_ptr = &rusage; 1048 else 1049 rusage_ptr = NULL; 1050 ret = get_errno(wait4(arg1, &status, arg3, rusage_ptr)); 1051 if (!is_error(ret)) { 1052 if (status_ptr) 1053 *status_ptr = tswap32(status); 1054 if (target_rusage) { 1055 target_rusage->ru_utime.tv_sec = tswapl(rusage.ru_utime.tv_sec); 1056 target_rusage->ru_utime.tv_usec = tswapl(rusage.ru_utime.tv_usec); 1057 target_rusage->ru_stime.tv_sec = tswapl(rusage.ru_stime.tv_sec); 1058 target_rusage->ru_stime.tv_usec = tswapl(rusage.ru_stime.tv_usec); 1059 target_rusage->ru_maxrss = tswapl(rusage.ru_maxrss); 1060 target_rusage->ru_ixrss = tswapl(rusage.ru_ixrss); 1061 target_rusage->ru_idrss = tswapl(rusage.ru_idrss); 1062 target_rusage->ru_isrss = tswapl(rusage.ru_isrss); 1063 target_rusage->ru_minflt = tswapl(rusage.ru_minflt); 1064 target_rusage->ru_majflt = tswapl(rusage.ru_majflt); 1065 target_rusage->ru_nswap = tswapl(rusage.ru_nswap); 1066 target_rusage->ru_inblock = tswapl(rusage.ru_inblock); 1067 target_rusage->ru_oublock = tswapl(rusage.ru_oublock); 1068 target_rusage->ru_msgsnd = tswapl(rusage.ru_msgsnd); 1069 target_rusage->ru_msgrcv = tswapl(rusage.ru_msgrcv); 1070 target_rusage->ru_nsignals = tswapl(rusage.ru_nsignals); 1071 target_rusage->ru_nvcsw = tswapl(rusage.ru_nvcsw); 1072 target_rusage->ru_nivcsw = tswapl(rusage.ru_nivcsw); 1073 } 1074 } 1075 } 1076 break; 1077 case TARGET_NR_swapoff: 1078 ret = get_errno(swapoff((const char *)arg1)); 1079 break; 1080 case TARGET_NR_sysinfo: 1081 goto unimplemented; 1082 case TARGET_NR_ipc: 1083 goto unimplemented; 1084 case TARGET_NR_fsync: 1085 ret = get_errno(fsync(arg1)); 1086 break; 1087 case TARGET_NR_sigreturn: 1088 goto unimplemented; 1089 case TARGET_NR_clone: 1090 goto unimplemented; 1091 case TARGET_NR_setdomainname: 1092 ret = get_errno(setdomainname((const char *)arg1, arg2)); 1093 break; 1094 case TARGET_NR_uname: 1095 /* no need to transcode because we use the linux syscall */ 1096 ret = get_errno(sys_uname((struct new_utsname *)arg1)); 1097 break; 1098 case TARGET_NR_modify_ldt: 1099 goto unimplemented; 1100 case TARGET_NR_adjtimex: 1101 goto unimplemented; 1102 case TARGET_NR_mprotect: 1103 ret = get_errno(mprotect((void *)arg1, arg2, arg3)); 1104 break; 1105 case TARGET_NR_sigprocmask: 1106 { 1107 int how = arg1; 1108 sigset_t set, oldset, *set_ptr; 1109 target_ulong *pset = (void *)arg2, *poldset = (void *)arg3; 1110 1111 switch(how) { 1112 case TARGET_SIG_BLOCK: 1113 how = SIG_BLOCK; 1114 break; 1115 case TARGET_SIG_UNBLOCK: 1116 how = SIG_UNBLOCK; 1117 break; 1118 case TARGET_SIG_SETMASK: 1119 how = SIG_SETMASK; 1120 break; 1121 default: 1122 ret = -EINVAL; 1123 goto fail; 1124 } 1125 1126 if (pset) { 1127 target_to_host_old_sigset(&set, pset); 1128 set_ptr = &set; 1129 } else { 1130 set_ptr = NULL; 1131 } 1132 ret = get_errno(sigprocmask(arg1, set_ptr, &oldset)); 1133 if (!is_error(ret) && poldset) { 1134 host_to_target_old_sigset(poldset, &oldset); 1135 } 1136 } 1137 break; 1138 case TARGET_NR_create_module: 1139 case TARGET_NR_init_module: 1140 case TARGET_NR_delete_module: 1141 case TARGET_NR_get_kernel_syms: 1142 goto unimplemented; 1143 case TARGET_NR_quotactl: 1144 goto unimplemented; 1145 case TARGET_NR_getpgid: 1146 ret = get_errno(getpgid(arg1)); 1147 break; 1148 case TARGET_NR_fchdir: 1149 ret = get_errno(fchdir(arg1)); 1150 break; 1151 case TARGET_NR_bdflush: 1152 goto unimplemented; 1153 case TARGET_NR_sysfs: 1154 goto unimplemented; 1155 case TARGET_NR_personality: 1156 ret = get_errno(mprotect((void *)arg1, arg2, arg3)); 1157 break; 1158 case TARGET_NR_afs_syscall: 1159 goto unimplemented; 1160 case TARGET_NR_setfsuid: 1161 goto unimplemented; 1162 case TARGET_NR_setfsgid: 1163 goto unimplemented; 1164 case TARGET_NR__llseek: 1165 { 1166 int64_t res; 1167 ret = get_errno(_llseek(arg1, arg2, arg3, &res, arg5)); 1168 *(int64_t *)arg4 = tswap64(res); 1169 } 1170 break; 1171 case TARGET_NR_getdents: 1172 #if TARGET_LONG_SIZE != 4 1173 #error not supported 1174 #endif 1175 { 1176 struct dirent *dirp = (void *)arg2; 1177 long count = arg3; 1178 ret = get_errno(sys_getdents(arg1, dirp, count)); 1179 if (!is_error(ret)) { 1180 struct dirent *de; 1181 int len = ret; 1182 int reclen; 1183 de = dirp; 1184 while (len > 0) { 1185 reclen = tswap16(de->d_reclen); 1186 if (reclen > len) 1187 break; 1188 de->d_reclen = reclen; 1189 tswapls(&de->d_ino); 1190 tswapls(&de->d_off); 1191 de = (struct dirent *)((char *)de + reclen); 1192 len -= reclen; 1193 } 1194 } 1195 } 1196 break; 1197 case TARGET_NR__newselect: 1198 ret = do_select(arg1, (void *)arg2, (void *)arg3, (void *)arg4, 1199 (void *)arg5); 1200 break; 1201 case TARGET_NR_flock: 1202 goto unimplemented; 1203 case TARGET_NR_msync: 1204 ret = get_errno(msync((void *)arg1, arg2, arg3)); 1205 break; 1206 case TARGET_NR_readv: 1207 { 1208 int count = arg3; 1209 int i; 1210 struct iovec *vec; 1211 struct target_iovec *target_vec = (void *)arg2; 1212 1213 vec = alloca(count * sizeof(struct iovec)); 1214 for(i = 0;i < count; i++) { 1215 vec[i].iov_base = (void *)tswapl(target_vec[i].iov_base); 1216 vec[i].iov_len = tswapl(target_vec[i].iov_len); 1217 } 1218 ret = get_errno(readv(arg1, vec, count)); 1219 } 1220 break; 1221 case TARGET_NR_writev: 1222 { 1223 int count = arg3; 1224 int i; 1225 struct iovec *vec; 1226 struct target_iovec *target_vec = (void *)arg2; 1227 1228 vec = alloca(count * sizeof(struct iovec)); 1229 for(i = 0;i < count; i++) { 1230 vec[i].iov_base = (void *)tswapl(target_vec[i].iov_base); 1231 vec[i].iov_len = tswapl(target_vec[i].iov_len); 1232 } 1233 ret = get_errno(writev(arg1, vec, count)); 1234 } 1235 break; 1236 case TARGET_NR_getsid: 1237 ret = get_errno(getsid(arg1)); 1238 break; 1239 case TARGET_NR_fdatasync: 1240 goto unimplemented; 1241 case TARGET_NR__sysctl: 1242 goto unimplemented; 1243 case TARGET_NR_mlock: 1244 ret = get_errno(mlock((void *)arg1, arg2)); 1245 break; 1246 case TARGET_NR_munlock: 1247 ret = get_errno(munlock((void *)arg1, arg2)); 1248 break; 1249 case TARGET_NR_mlockall: 1250 ret = get_errno(mlockall(arg1)); 1251 break; 1252 case TARGET_NR_munlockall: 1253 ret = get_errno(munlockall()); 1254 break; 1255 case TARGET_NR_sched_setparam: 1256 goto unimplemented; 1257 case TARGET_NR_sched_getparam: 1258 goto unimplemented; 1259 case TARGET_NR_sched_setscheduler: 1260 goto unimplemented; 1261 case TARGET_NR_sched_getscheduler: 1262 goto unimplemented; 1263 case TARGET_NR_sched_yield: 1264 ret = get_errno(sched_yield()); 1265 break; 1266 case TARGET_NR_sched_get_priority_max: 1267 case TARGET_NR_sched_get_priority_min: 1268 case TARGET_NR_sched_rr_get_interval: 1269 case TARGET_NR_nanosleep: 1270 case TARGET_NR_mremap: 1271 case TARGET_NR_setresuid: 1272 case TARGET_NR_getresuid: 1273 case TARGET_NR_vm86: 1274 case TARGET_NR_query_module: 1275 case TARGET_NR_poll: 1276 case TARGET_NR_nfsservctl: 1277 case TARGET_NR_setresgid: 1278 case TARGET_NR_getresgid: 1279 case TARGET_NR_prctl: 1280 case TARGET_NR_rt_sigreturn: 1281 case TARGET_NR_rt_sigaction: 1282 case TARGET_NR_rt_sigprocmask: 1283 case TARGET_NR_rt_sigpending: 1284 case TARGET_NR_rt_sigtimedwait: 1285 case TARGET_NR_rt_sigqueueinfo: 1286 case TARGET_NR_rt_sigsuspend: 1287 case TARGET_NR_pread: 1288 case TARGET_NR_pwrite: 1289 goto unimplemented; 1290 case TARGET_NR_chown: 1291 ret = get_errno(chown((const char *)arg1, arg2, arg3)); 1292 break; 1293 case TARGET_NR_getcwd: 1294 ret = get_errno(sys_getcwd1((char *)arg1, arg2)); 1295 break; 1296 case TARGET_NR_capget: 1297 case TARGET_NR_capset: 1298 case TARGET_NR_sigaltstack: 1299 case TARGET_NR_sendfile: 1300 case TARGET_NR_getpmsg: 1301 case TARGET_NR_putpmsg: 1302 case TARGET_NR_vfork: 1303 ret = get_errno(vfork()); 1304 break; 1305 case TARGET_NR_ugetrlimit: 1306 case TARGET_NR_truncate64: 1307 case TARGET_NR_ftruncate64: 1308 case TARGET_NR_stat64: 1309 case TARGET_NR_lstat64: 1310 case TARGET_NR_fstat64: 1311 case TARGET_NR_lchown32: 1312 case TARGET_NR_getuid32: 1313 case TARGET_NR_getgid32: 1314 case TARGET_NR_geteuid32: 1315 case TARGET_NR_getegid32: 1316 case TARGET_NR_setreuid32: 1317 case TARGET_NR_setregid32: 1318 case TARGET_NR_getgroups32: 1319 case TARGET_NR_setgroups32: 1320 case TARGET_NR_fchown32: 1321 case TARGET_NR_setresuid32: 1322 case TARGET_NR_getresuid32: 1323 case TARGET_NR_setresgid32: 1324 case TARGET_NR_getresgid32: 1325 case TARGET_NR_chown32: 1326 case TARGET_NR_setuid32: 1327 case TARGET_NR_setgid32: 1328 case TARGET_NR_setfsuid32: 1329 case TARGET_NR_setfsgid32: 1330 case TARGET_NR_pivot_root: 1331 case TARGET_NR_mincore: 1332 case TARGET_NR_madvise: 1333 case TARGET_NR_getdents64: 1334 case TARGET_NR_fcntl64: 1335 case TARGET_NR_security: 1336 goto unimplemented; 1337 case TARGET_NR_gettid: 1338 ret = get_errno(gettid()); 1339 break; 1340 case TARGET_NR_readahead: 1341 case TARGET_NR_setxattr: 1342 case TARGET_NR_lsetxattr: 1343 case TARGET_NR_fsetxattr: 1344 case TARGET_NR_getxattr: 1345 case TARGET_NR_lgetxattr: 1346 case TARGET_NR_fgetxattr: 1347 case TARGET_NR_listxattr: 1348 case TARGET_NR_llistxattr: 1349 case TARGET_NR_flistxattr: 1350 case TARGET_NR_removexattr: 1351 case TARGET_NR_lremovexattr: 1352 case TARGET_NR_fremovexattr: 1353 goto unimplemented; 1354 default: 1355 unimplemented: 1356 gemu_log("Unsupported syscall: %d\n", num); 1357 ret = -ENOSYS; 1358 break; 1359 } 1360 fail: 1361 return ret; 1362 } 1363 1364