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