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