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 <time.h> 30 #include <sys/types.h> 31 #include <sys/wait.h> 32 #include <sys/time.h> 33 #include <sys/stat.h> 34 #include <sys/mount.h> 35 #include <sys/resource.h> 36 #include <sys/mman.h> 37 #include <sys/swap.h> 38 #include <signal.h> 39 #include <sched.h> 40 #include <sys/socket.h> 41 #include <sys/uio.h> 42 #include <sys/poll.h> 43 #include <sys/times.h> 44 //#include <sys/user.h> 45 #include <netinet/tcp.h> 46 47 #define termios host_termios 48 #define winsize host_winsize 49 #define termio host_termio 50 #define sgttyb host_sgttyb /* same as target */ 51 #define tchars host_tchars /* same as target */ 52 #define ltchars host_ltchars /* same as target */ 53 54 #include <linux/termios.h> 55 #include <linux/unistd.h> 56 #include <linux/utsname.h> 57 #include <linux/cdrom.h> 58 #include <linux/hdreg.h> 59 #include <linux/soundcard.h> 60 #include <linux/dirent.h> 61 #include <linux/kd.h> 62 63 #include "qemu.h" 64 65 //#define DEBUG 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 void host_to_target_siginfo(target_siginfo_t *tinfo, const siginfo_t *info); 72 void target_to_host_siginfo(siginfo_t *info, const target_siginfo_t *tinfo); 73 long do_sigreturn(CPUX86State *env); 74 long do_rt_sigreturn(CPUX86State *env); 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 #define __NR_sys_getdents64 __NR_getdents64 82 #define __NR_sys_rt_sigqueueinfo __NR_rt_sigqueueinfo 83 84 #if defined(__alpha__) || defined (__ia64__) 85 #define __NR__llseek __NR_lseek 86 #endif 87 88 #ifdef __NR_gettid 89 _syscall0(int, gettid) 90 #else 91 static int gettid(void) { 92 return -ENOSYS; 93 } 94 #endif 95 _syscall1(int,sys_uname,struct new_utsname *,buf) 96 _syscall2(int,sys_getcwd1,char *,buf,size_t,size) 97 _syscall3(int, sys_getdents, uint, fd, struct dirent *, dirp, uint, count); 98 _syscall3(int, sys_getdents64, uint, fd, struct dirent64 *, dirp, uint, count); 99 _syscall5(int, _llseek, uint, fd, ulong, hi, ulong, lo, 100 loff_t *, res, uint, wh); 101 _syscall2(int,sys_statfs,const char *,path,struct kernel_statfs *,buf) 102 _syscall2(int,sys_fstatfs,int,fd,struct kernel_statfs *,buf) 103 _syscall3(int,sys_rt_sigqueueinfo,int,pid,int,sig,siginfo_t *,uinfo) 104 #ifdef __NR_exit_group 105 _syscall1(int,exit_group,int,error_code) 106 #endif 107 108 extern int personality(int); 109 extern int flock(int, int); 110 extern int setfsuid(int); 111 extern int setfsgid(int); 112 extern int setresuid(uid_t, uid_t, uid_t); 113 extern int getresuid(uid_t *, uid_t *, uid_t *); 114 extern int setresgid(gid_t, gid_t, gid_t); 115 extern int getresgid(gid_t *, gid_t *, gid_t *); 116 extern int setgroups(int, gid_t *); 117 118 static inline long get_errno(long ret) 119 { 120 if (ret == -1) 121 return -errno; 122 else 123 return ret; 124 } 125 126 static inline int is_error(long ret) 127 { 128 return (unsigned long)ret >= (unsigned long)(-4096); 129 } 130 131 static char *target_brk; 132 static char *target_original_brk; 133 134 void target_set_brk(char *new_brk) 135 { 136 target_brk = new_brk; 137 target_original_brk = new_brk; 138 } 139 140 static long do_brk(char *new_brk) 141 { 142 char *brk_page; 143 long mapped_addr; 144 int new_alloc_size; 145 146 if (!new_brk) 147 return (long)target_brk; 148 if (new_brk < target_original_brk) 149 return -ENOMEM; 150 151 brk_page = (char *)HOST_PAGE_ALIGN((unsigned long)target_brk); 152 153 /* If the new brk is less than this, set it and we're done... */ 154 if (new_brk < brk_page) { 155 target_brk = new_brk; 156 return (long)target_brk; 157 } 158 159 /* We need to allocate more memory after the brk... */ 160 new_alloc_size = HOST_PAGE_ALIGN(new_brk - brk_page + 1); 161 mapped_addr = get_errno(target_mmap((unsigned long)brk_page, new_alloc_size, 162 PROT_READ|PROT_WRITE, 163 MAP_ANON|MAP_FIXED|MAP_PRIVATE, 0, 0)); 164 if (is_error(mapped_addr)) { 165 return mapped_addr; 166 } else { 167 target_brk = new_brk; 168 return (long)target_brk; 169 } 170 } 171 172 static inline fd_set *target_to_host_fds(fd_set *fds, 173 target_long *target_fds, int n) 174 { 175 #if !defined(BSWAP_NEEDED) && !defined(WORDS_BIGENDIAN) 176 return (fd_set *)target_fds; 177 #else 178 int i, b; 179 if (target_fds) { 180 FD_ZERO(fds); 181 for(i = 0;i < n; i++) { 182 b = (tswapl(target_fds[i / TARGET_LONG_BITS]) >> 183 (i & (TARGET_LONG_BITS - 1))) & 1; 184 if (b) 185 FD_SET(i, fds); 186 } 187 return fds; 188 } else { 189 return NULL; 190 } 191 #endif 192 } 193 194 static inline void host_to_target_fds(target_long *target_fds, 195 fd_set *fds, int n) 196 { 197 #if !defined(BSWAP_NEEDED) && !defined(WORDS_BIGENDIAN) 198 /* nothing to do */ 199 #else 200 int i, nw, j, k; 201 target_long v; 202 203 if (target_fds) { 204 nw = n / TARGET_LONG_BITS; 205 k = 0; 206 for(i = 0;i < nw; i++) { 207 v = 0; 208 for(j = 0; j < TARGET_LONG_BITS; j++) { 209 v |= ((FD_ISSET(k, fds) != 0) << j); 210 k++; 211 } 212 target_fds[i] = tswapl(v); 213 } 214 } 215 #endif 216 } 217 218 static inline void host_to_target_rusage(struct target_rusage *target_rusage, 219 const struct rusage *rusage) 220 { 221 target_rusage->ru_utime.tv_sec = tswapl(rusage->ru_utime.tv_sec); 222 target_rusage->ru_utime.tv_usec = tswapl(rusage->ru_utime.tv_usec); 223 target_rusage->ru_stime.tv_sec = tswapl(rusage->ru_stime.tv_sec); 224 target_rusage->ru_stime.tv_usec = tswapl(rusage->ru_stime.tv_usec); 225 target_rusage->ru_maxrss = tswapl(rusage->ru_maxrss); 226 target_rusage->ru_ixrss = tswapl(rusage->ru_ixrss); 227 target_rusage->ru_idrss = tswapl(rusage->ru_idrss); 228 target_rusage->ru_isrss = tswapl(rusage->ru_isrss); 229 target_rusage->ru_minflt = tswapl(rusage->ru_minflt); 230 target_rusage->ru_majflt = tswapl(rusage->ru_majflt); 231 target_rusage->ru_nswap = tswapl(rusage->ru_nswap); 232 target_rusage->ru_inblock = tswapl(rusage->ru_inblock); 233 target_rusage->ru_oublock = tswapl(rusage->ru_oublock); 234 target_rusage->ru_msgsnd = tswapl(rusage->ru_msgsnd); 235 target_rusage->ru_msgrcv = tswapl(rusage->ru_msgrcv); 236 target_rusage->ru_nsignals = tswapl(rusage->ru_nsignals); 237 target_rusage->ru_nvcsw = tswapl(rusage->ru_nvcsw); 238 target_rusage->ru_nivcsw = tswapl(rusage->ru_nivcsw); 239 } 240 241 static inline void target_to_host_timeval(struct timeval *tv, 242 const struct target_timeval *target_tv) 243 { 244 tv->tv_sec = tswapl(target_tv->tv_sec); 245 tv->tv_usec = tswapl(target_tv->tv_usec); 246 } 247 248 static inline void host_to_target_timeval(struct target_timeval *target_tv, 249 const struct timeval *tv) 250 { 251 target_tv->tv_sec = tswapl(tv->tv_sec); 252 target_tv->tv_usec = tswapl(tv->tv_usec); 253 } 254 255 256 static long do_select(long n, 257 target_long *target_rfds, target_long *target_wfds, 258 target_long *target_efds, struct target_timeval *target_tv) 259 { 260 fd_set rfds, wfds, efds; 261 fd_set *rfds_ptr, *wfds_ptr, *efds_ptr; 262 struct timeval tv, *tv_ptr; 263 long ret; 264 265 rfds_ptr = target_to_host_fds(&rfds, target_rfds, n); 266 wfds_ptr = target_to_host_fds(&wfds, target_wfds, n); 267 efds_ptr = target_to_host_fds(&efds, target_efds, n); 268 269 if (target_tv) { 270 target_to_host_timeval(&tv, target_tv); 271 tv_ptr = &tv; 272 } else { 273 tv_ptr = NULL; 274 } 275 ret = get_errno(select(n, rfds_ptr, wfds_ptr, efds_ptr, tv_ptr)); 276 if (!is_error(ret)) { 277 host_to_target_fds(target_rfds, rfds_ptr, n); 278 host_to_target_fds(target_wfds, wfds_ptr, n); 279 host_to_target_fds(target_efds, efds_ptr, n); 280 281 if (target_tv) { 282 host_to_target_timeval(target_tv, &tv); 283 } 284 } 285 return ret; 286 } 287 288 static inline void target_to_host_sockaddr(struct sockaddr *addr, 289 struct target_sockaddr *target_addr, 290 socklen_t len) 291 { 292 memcpy(addr, target_addr, len); 293 addr->sa_family = tswap16(target_addr->sa_family); 294 } 295 296 static inline void host_to_target_sockaddr(struct target_sockaddr *target_addr, 297 struct sockaddr *addr, 298 socklen_t len) 299 { 300 memcpy(target_addr, addr, len); 301 target_addr->sa_family = tswap16(addr->sa_family); 302 } 303 304 static inline void target_to_host_cmsg(struct msghdr *msgh, 305 struct target_msghdr *target_msgh) 306 { 307 struct cmsghdr *cmsg = CMSG_FIRSTHDR(msgh); 308 struct target_cmsghdr *target_cmsg = TARGET_CMSG_FIRSTHDR(target_msgh); 309 socklen_t space = 0; 310 311 while (cmsg && target_cmsg) { 312 void *data = CMSG_DATA(cmsg); 313 void *target_data = TARGET_CMSG_DATA(target_cmsg); 314 315 int len = tswapl(target_cmsg->cmsg_len) 316 - TARGET_CMSG_ALIGN(sizeof (struct target_cmsghdr)); 317 318 space += CMSG_SPACE(len); 319 if (space > msgh->msg_controllen) { 320 space -= CMSG_SPACE(len); 321 gemu_log("Host cmsg overflow"); 322 break; 323 } 324 325 cmsg->cmsg_level = tswap32(target_cmsg->cmsg_level); 326 cmsg->cmsg_type = tswap32(target_cmsg->cmsg_type); 327 cmsg->cmsg_len = CMSG_LEN(len); 328 329 if (cmsg->cmsg_level != SOL_SOCKET || cmsg->cmsg_type != SCM_RIGHTS) { 330 gemu_log("Unsupported ancillary data: %d/%d\n", cmsg->cmsg_level, cmsg->cmsg_type); 331 memcpy(data, target_data, len); 332 } else { 333 int *fd = (int *)data; 334 int *target_fd = (int *)target_data; 335 int i, numfds = len / sizeof(int); 336 337 for (i = 0; i < numfds; i++) 338 fd[i] = tswap32(target_fd[i]); 339 } 340 341 cmsg = CMSG_NXTHDR(msgh, cmsg); 342 target_cmsg = TARGET_CMSG_NXTHDR(target_msgh, target_cmsg); 343 } 344 345 msgh->msg_controllen = space; 346 } 347 348 static inline void host_to_target_cmsg(struct target_msghdr *target_msgh, 349 struct msghdr *msgh) 350 { 351 struct cmsghdr *cmsg = CMSG_FIRSTHDR(msgh); 352 struct target_cmsghdr *target_cmsg = TARGET_CMSG_FIRSTHDR(target_msgh); 353 socklen_t space = 0; 354 355 while (cmsg && target_cmsg) { 356 void *data = CMSG_DATA(cmsg); 357 void *target_data = TARGET_CMSG_DATA(target_cmsg); 358 359 int len = cmsg->cmsg_len - CMSG_ALIGN(sizeof (struct cmsghdr)); 360 361 space += TARGET_CMSG_SPACE(len); 362 if (space > tswapl(target_msgh->msg_controllen)) { 363 space -= TARGET_CMSG_SPACE(len); 364 gemu_log("Target cmsg overflow"); 365 break; 366 } 367 368 target_cmsg->cmsg_level = tswap32(cmsg->cmsg_level); 369 target_cmsg->cmsg_type = tswap32(cmsg->cmsg_type); 370 target_cmsg->cmsg_len = tswapl(TARGET_CMSG_LEN(len)); 371 372 if (cmsg->cmsg_level != SOL_SOCKET || cmsg->cmsg_type != SCM_RIGHTS) { 373 gemu_log("Unsupported ancillary data: %d/%d\n", cmsg->cmsg_level, cmsg->cmsg_type); 374 memcpy(target_data, data, len); 375 } else { 376 int *fd = (int *)data; 377 int *target_fd = (int *)target_data; 378 int i, numfds = len / sizeof(int); 379 380 for (i = 0; i < numfds; i++) 381 target_fd[i] = tswap32(fd[i]); 382 } 383 384 cmsg = CMSG_NXTHDR(msgh, cmsg); 385 target_cmsg = TARGET_CMSG_NXTHDR(target_msgh, target_cmsg); 386 } 387 388 msgh->msg_controllen = tswapl(space); 389 } 390 391 static long do_setsockopt(int sockfd, int level, int optname, 392 void *optval, socklen_t optlen) 393 { 394 if (level == SOL_TCP) { 395 /* TCP options all take an 'int' value. */ 396 int val; 397 398 if (optlen < sizeof(uint32_t)) 399 return -EINVAL; 400 401 val = tswap32(*(uint32_t *)optval); 402 return get_errno(setsockopt(sockfd, level, optname, &val, sizeof(val))); 403 } 404 405 else if (level != SOL_SOCKET) { 406 gemu_log("Unsupported setsockopt level: %d\n", level); 407 return -ENOSYS; 408 } 409 410 switch (optname) { 411 /* Options with 'int' argument. */ 412 case SO_DEBUG: 413 case SO_REUSEADDR: 414 case SO_TYPE: 415 case SO_ERROR: 416 case SO_DONTROUTE: 417 case SO_BROADCAST: 418 case SO_SNDBUF: 419 case SO_RCVBUF: 420 case SO_KEEPALIVE: 421 case SO_OOBINLINE: 422 case SO_NO_CHECK: 423 case SO_PRIORITY: 424 case SO_BSDCOMPAT: 425 case SO_PASSCRED: 426 case SO_TIMESTAMP: 427 case SO_RCVLOWAT: 428 case SO_RCVTIMEO: 429 case SO_SNDTIMEO: 430 { 431 int val; 432 if (optlen < sizeof(uint32_t)) 433 return -EINVAL; 434 val = tswap32(*(uint32_t *)optval); 435 return get_errno(setsockopt(sockfd, level, optname, &val, sizeof(val))); 436 } 437 438 default: 439 gemu_log("Unsupported setsockopt SOL_SOCKET option: %d\n", optname); 440 return -ENOSYS; 441 } 442 } 443 444 static long do_getsockopt(int sockfd, int level, int optname, 445 void *optval, socklen_t *optlen) 446 { 447 gemu_log("getsockopt not yet supported\n"); 448 return -ENOSYS; 449 } 450 451 static long do_socketcall(int num, int32_t *vptr) 452 { 453 long ret; 454 455 switch(num) { 456 case SOCKOP_socket: 457 { 458 int domain = tswap32(vptr[0]); 459 int type = tswap32(vptr[1]); 460 int protocol = tswap32(vptr[2]); 461 462 ret = get_errno(socket(domain, type, protocol)); 463 } 464 break; 465 case SOCKOP_bind: 466 { 467 int sockfd = tswap32(vptr[0]); 468 void *target_addr = (void *)tswap32(vptr[1]); 469 socklen_t addrlen = tswap32(vptr[2]); 470 void *addr = alloca(addrlen); 471 472 target_to_host_sockaddr(addr, target_addr, addrlen); 473 ret = get_errno(bind(sockfd, addr, addrlen)); 474 } 475 break; 476 case SOCKOP_connect: 477 { 478 int sockfd = tswap32(vptr[0]); 479 void *target_addr = (void *)tswap32(vptr[1]); 480 socklen_t addrlen = tswap32(vptr[2]); 481 void *addr = alloca(addrlen); 482 483 target_to_host_sockaddr(addr, target_addr, addrlen); 484 ret = get_errno(connect(sockfd, addr, addrlen)); 485 } 486 break; 487 case SOCKOP_listen: 488 { 489 int sockfd = tswap32(vptr[0]); 490 int backlog = tswap32(vptr[1]); 491 492 ret = get_errno(listen(sockfd, backlog)); 493 } 494 break; 495 case SOCKOP_accept: 496 { 497 int sockfd = tswap32(vptr[0]); 498 void *target_addr = (void *)tswap32(vptr[1]); 499 uint32_t *target_addrlen = (void *)tswap32(vptr[2]); 500 socklen_t addrlen = tswap32(*target_addrlen); 501 void *addr = alloca(addrlen); 502 503 ret = get_errno(accept(sockfd, addr, &addrlen)); 504 if (!is_error(ret)) { 505 host_to_target_sockaddr(target_addr, addr, addrlen); 506 *target_addrlen = tswap32(addrlen); 507 } 508 } 509 break; 510 case SOCKOP_getsockname: 511 { 512 int sockfd = tswap32(vptr[0]); 513 void *target_addr = (void *)tswap32(vptr[1]); 514 uint32_t *target_addrlen = (void *)tswap32(vptr[2]); 515 socklen_t addrlen = tswap32(*target_addrlen); 516 void *addr = alloca(addrlen); 517 518 ret = get_errno(getsockname(sockfd, addr, &addrlen)); 519 if (!is_error(ret)) { 520 host_to_target_sockaddr(target_addr, addr, addrlen); 521 *target_addrlen = tswap32(addrlen); 522 } 523 } 524 break; 525 case SOCKOP_getpeername: 526 { 527 int sockfd = tswap32(vptr[0]); 528 void *target_addr = (void *)tswap32(vptr[1]); 529 uint32_t *target_addrlen = (void *)tswap32(vptr[2]); 530 socklen_t addrlen = tswap32(*target_addrlen); 531 void *addr = alloca(addrlen); 532 533 ret = get_errno(getpeername(sockfd, addr, &addrlen)); 534 if (!is_error(ret)) { 535 host_to_target_sockaddr(target_addr, addr, addrlen); 536 *target_addrlen = tswap32(addrlen); 537 } 538 } 539 break; 540 case SOCKOP_socketpair: 541 { 542 int domain = tswap32(vptr[0]); 543 int type = tswap32(vptr[1]); 544 int protocol = tswap32(vptr[2]); 545 int32_t *target_tab = (void *)tswap32(vptr[3]); 546 int tab[2]; 547 548 ret = get_errno(socketpair(domain, type, protocol, tab)); 549 if (!is_error(ret)) { 550 target_tab[0] = tswap32(tab[0]); 551 target_tab[1] = tswap32(tab[1]); 552 } 553 } 554 break; 555 case SOCKOP_send: 556 { 557 int sockfd = tswap32(vptr[0]); 558 void *msg = (void *)tswap32(vptr[1]); 559 size_t len = tswap32(vptr[2]); 560 int flags = tswap32(vptr[3]); 561 562 ret = get_errno(send(sockfd, msg, len, flags)); 563 } 564 break; 565 case SOCKOP_recv: 566 { 567 int sockfd = tswap32(vptr[0]); 568 void *msg = (void *)tswap32(vptr[1]); 569 size_t len = tswap32(vptr[2]); 570 int flags = tswap32(vptr[3]); 571 572 ret = get_errno(recv(sockfd, msg, len, flags)); 573 } 574 break; 575 case SOCKOP_sendto: 576 { 577 int sockfd = tswap32(vptr[0]); 578 void *msg = (void *)tswap32(vptr[1]); 579 size_t len = tswap32(vptr[2]); 580 int flags = tswap32(vptr[3]); 581 void *target_addr = (void *)tswap32(vptr[4]); 582 socklen_t addrlen = tswap32(vptr[5]); 583 void *addr = alloca(addrlen); 584 585 target_to_host_sockaddr(addr, target_addr, addrlen); 586 ret = get_errno(sendto(sockfd, msg, len, flags, addr, addrlen)); 587 } 588 break; 589 case SOCKOP_recvfrom: 590 { 591 int sockfd = tswap32(vptr[0]); 592 void *msg = (void *)tswap32(vptr[1]); 593 size_t len = tswap32(vptr[2]); 594 int flags = tswap32(vptr[3]); 595 void *target_addr = (void *)tswap32(vptr[4]); 596 uint32_t *target_addrlen = (void *)tswap32(vptr[5]); 597 socklen_t addrlen = tswap32(*target_addrlen); 598 void *addr = alloca(addrlen); 599 600 ret = get_errno(recvfrom(sockfd, msg, len, flags, addr, &addrlen)); 601 if (!is_error(ret)) { 602 host_to_target_sockaddr(target_addr, addr, addrlen); 603 *target_addrlen = tswap32(addrlen); 604 } 605 } 606 break; 607 case SOCKOP_shutdown: 608 { 609 int sockfd = tswap32(vptr[0]); 610 int how = tswap32(vptr[1]); 611 612 ret = get_errno(shutdown(sockfd, how)); 613 } 614 break; 615 case SOCKOP_sendmsg: 616 case SOCKOP_recvmsg: 617 { 618 int fd; 619 struct target_msghdr *msgp; 620 struct msghdr msg; 621 int flags, count, i; 622 struct iovec *vec; 623 struct target_iovec *target_vec; 624 625 msgp = (void *)tswap32(vptr[1]); 626 msg.msg_name = (void *)tswapl(msgp->msg_name); 627 msg.msg_namelen = tswapl(msgp->msg_namelen); 628 msg.msg_controllen = 2 * tswapl(msgp->msg_controllen); 629 msg.msg_control = alloca(msg.msg_controllen); 630 msg.msg_flags = tswap32(msgp->msg_flags); 631 632 count = tswapl(msgp->msg_iovlen); 633 vec = alloca(count * sizeof(struct iovec)); 634 target_vec = (void *)tswapl(msgp->msg_iov); 635 for(i = 0;i < count; i++) { 636 vec[i].iov_base = (void *)tswapl(target_vec[i].iov_base); 637 vec[i].iov_len = tswapl(target_vec[i].iov_len); 638 } 639 msg.msg_iovlen = count; 640 msg.msg_iov = vec; 641 642 fd = tswap32(vptr[0]); 643 flags = tswap32(vptr[2]); 644 if (num == SOCKOP_sendmsg) { 645 target_to_host_cmsg(&msg, msgp); 646 ret = get_errno(sendmsg(fd, &msg, flags)); 647 } else { 648 ret = get_errno(recvmsg(fd, &msg, flags)); 649 if (!is_error(ret)) 650 host_to_target_cmsg(msgp, &msg); 651 } 652 } 653 break; 654 case SOCKOP_setsockopt: 655 { 656 int sockfd = tswap32(vptr[0]); 657 int level = tswap32(vptr[1]); 658 int optname = tswap32(vptr[2]); 659 void *optval = (void *)tswap32(vptr[3]); 660 socklen_t optlen = tswap32(vptr[4]); 661 662 ret = do_setsockopt(sockfd, level, optname, optval, optlen); 663 } 664 break; 665 case SOCKOP_getsockopt: 666 { 667 int sockfd = tswap32(vptr[0]); 668 int level = tswap32(vptr[1]); 669 int optname = tswap32(vptr[2]); 670 void *optval = (void *)tswap32(vptr[3]); 671 uint32_t *target_len = (void *)tswap32(vptr[4]); 672 socklen_t optlen = tswap32(*target_len); 673 674 ret = do_getsockopt(sockfd, level, optname, optval, &optlen); 675 if (!is_error(ret)) 676 *target_len = tswap32(optlen); 677 } 678 break; 679 default: 680 gemu_log("Unsupported socketcall: %d\n", num); 681 ret = -ENOSYS; 682 break; 683 } 684 return ret; 685 } 686 687 /* kernel structure types definitions */ 688 #define IFNAMSIZ 16 689 690 #define STRUCT(name, list...) STRUCT_ ## name, 691 #define STRUCT_SPECIAL(name) STRUCT_ ## name, 692 enum { 693 #include "syscall_types.h" 694 }; 695 #undef STRUCT 696 #undef STRUCT_SPECIAL 697 698 #define STRUCT(name, list...) const argtype struct_ ## name ## _def[] = { list, TYPE_NULL }; 699 #define STRUCT_SPECIAL(name) 700 #include "syscall_types.h" 701 #undef STRUCT 702 #undef STRUCT_SPECIAL 703 704 typedef struct IOCTLEntry { 705 int target_cmd; 706 int host_cmd; 707 const char *name; 708 int access; 709 const argtype arg_type[5]; 710 } IOCTLEntry; 711 712 #define IOC_R 0x0001 713 #define IOC_W 0x0002 714 #define IOC_RW (IOC_R | IOC_W) 715 716 #define MAX_STRUCT_SIZE 4096 717 718 const IOCTLEntry ioctl_entries[] = { 719 #define IOCTL(cmd, access, types...) \ 720 { TARGET_ ## cmd, cmd, #cmd, access, { types } }, 721 #include "ioctls.h" 722 { 0, 0, }, 723 }; 724 725 static long do_ioctl(long fd, long cmd, long arg) 726 { 727 const IOCTLEntry *ie; 728 const argtype *arg_type; 729 long ret; 730 uint8_t buf_temp[MAX_STRUCT_SIZE]; 731 732 ie = ioctl_entries; 733 for(;;) { 734 if (ie->target_cmd == 0) { 735 gemu_log("Unsupported ioctl: cmd=0x%04lx\n", cmd); 736 return -ENOSYS; 737 } 738 if (ie->target_cmd == cmd) 739 break; 740 ie++; 741 } 742 arg_type = ie->arg_type; 743 #if defined(DEBUG) 744 gemu_log("ioctl: cmd=0x%04lx (%s)\n", cmd, ie->name); 745 #endif 746 switch(arg_type[0]) { 747 case TYPE_NULL: 748 /* no argument */ 749 ret = get_errno(ioctl(fd, ie->host_cmd)); 750 break; 751 case TYPE_PTRVOID: 752 case TYPE_INT: 753 /* int argment */ 754 ret = get_errno(ioctl(fd, ie->host_cmd, arg)); 755 break; 756 case TYPE_PTR: 757 arg_type++; 758 switch(ie->access) { 759 case IOC_R: 760 ret = get_errno(ioctl(fd, ie->host_cmd, buf_temp)); 761 if (!is_error(ret)) { 762 thunk_convert((void *)arg, buf_temp, arg_type, THUNK_TARGET); 763 } 764 break; 765 case IOC_W: 766 thunk_convert(buf_temp, (void *)arg, arg_type, THUNK_HOST); 767 ret = get_errno(ioctl(fd, ie->host_cmd, buf_temp)); 768 break; 769 default: 770 case IOC_RW: 771 thunk_convert(buf_temp, (void *)arg, arg_type, THUNK_HOST); 772 ret = get_errno(ioctl(fd, ie->host_cmd, buf_temp)); 773 if (!is_error(ret)) { 774 thunk_convert((void *)arg, buf_temp, arg_type, THUNK_TARGET); 775 } 776 break; 777 } 778 break; 779 default: 780 gemu_log("Unsupported ioctl type: cmd=0x%04lx type=%d\n", cmd, arg_type[0]); 781 ret = -ENOSYS; 782 break; 783 } 784 return ret; 785 } 786 787 bitmask_transtbl iflag_tbl[] = { 788 { TARGET_IGNBRK, TARGET_IGNBRK, IGNBRK, IGNBRK }, 789 { TARGET_BRKINT, TARGET_BRKINT, BRKINT, BRKINT }, 790 { TARGET_IGNPAR, TARGET_IGNPAR, IGNPAR, IGNPAR }, 791 { TARGET_PARMRK, TARGET_PARMRK, PARMRK, PARMRK }, 792 { TARGET_INPCK, TARGET_INPCK, INPCK, INPCK }, 793 { TARGET_ISTRIP, TARGET_ISTRIP, ISTRIP, ISTRIP }, 794 { TARGET_INLCR, TARGET_INLCR, INLCR, INLCR }, 795 { TARGET_IGNCR, TARGET_IGNCR, IGNCR, IGNCR }, 796 { TARGET_ICRNL, TARGET_ICRNL, ICRNL, ICRNL }, 797 { TARGET_IUCLC, TARGET_IUCLC, IUCLC, IUCLC }, 798 { TARGET_IXON, TARGET_IXON, IXON, IXON }, 799 { TARGET_IXANY, TARGET_IXANY, IXANY, IXANY }, 800 { TARGET_IXOFF, TARGET_IXOFF, IXOFF, IXOFF }, 801 { TARGET_IMAXBEL, TARGET_IMAXBEL, IMAXBEL, IMAXBEL }, 802 { 0, 0, 0, 0 } 803 }; 804 805 bitmask_transtbl oflag_tbl[] = { 806 { TARGET_OPOST, TARGET_OPOST, OPOST, OPOST }, 807 { TARGET_OLCUC, TARGET_OLCUC, OLCUC, OLCUC }, 808 { TARGET_ONLCR, TARGET_ONLCR, ONLCR, ONLCR }, 809 { TARGET_OCRNL, TARGET_OCRNL, OCRNL, OCRNL }, 810 { TARGET_ONOCR, TARGET_ONOCR, ONOCR, ONOCR }, 811 { TARGET_ONLRET, TARGET_ONLRET, ONLRET, ONLRET }, 812 { TARGET_OFILL, TARGET_OFILL, OFILL, OFILL }, 813 { TARGET_OFDEL, TARGET_OFDEL, OFDEL, OFDEL }, 814 { TARGET_NLDLY, TARGET_NL0, NLDLY, NL0 }, 815 { TARGET_NLDLY, TARGET_NL1, NLDLY, NL1 }, 816 { TARGET_CRDLY, TARGET_CR0, CRDLY, CR0 }, 817 { TARGET_CRDLY, TARGET_CR1, CRDLY, CR1 }, 818 { TARGET_CRDLY, TARGET_CR2, CRDLY, CR2 }, 819 { TARGET_CRDLY, TARGET_CR3, CRDLY, CR3 }, 820 { TARGET_TABDLY, TARGET_TAB0, TABDLY, TAB0 }, 821 { TARGET_TABDLY, TARGET_TAB1, TABDLY, TAB1 }, 822 { TARGET_TABDLY, TARGET_TAB2, TABDLY, TAB2 }, 823 { TARGET_TABDLY, TARGET_TAB3, TABDLY, TAB3 }, 824 { TARGET_BSDLY, TARGET_BS0, BSDLY, BS0 }, 825 { TARGET_BSDLY, TARGET_BS1, BSDLY, BS1 }, 826 { TARGET_VTDLY, TARGET_VT0, VTDLY, VT0 }, 827 { TARGET_VTDLY, TARGET_VT1, VTDLY, VT1 }, 828 { TARGET_FFDLY, TARGET_FF0, FFDLY, FF0 }, 829 { TARGET_FFDLY, TARGET_FF1, FFDLY, FF1 }, 830 { 0, 0, 0, 0 } 831 }; 832 833 bitmask_transtbl cflag_tbl[] = { 834 { TARGET_CBAUD, TARGET_B0, CBAUD, B0 }, 835 { TARGET_CBAUD, TARGET_B50, CBAUD, B50 }, 836 { TARGET_CBAUD, TARGET_B75, CBAUD, B75 }, 837 { TARGET_CBAUD, TARGET_B110, CBAUD, B110 }, 838 { TARGET_CBAUD, TARGET_B134, CBAUD, B134 }, 839 { TARGET_CBAUD, TARGET_B150, CBAUD, B150 }, 840 { TARGET_CBAUD, TARGET_B200, CBAUD, B200 }, 841 { TARGET_CBAUD, TARGET_B300, CBAUD, B300 }, 842 { TARGET_CBAUD, TARGET_B600, CBAUD, B600 }, 843 { TARGET_CBAUD, TARGET_B1200, CBAUD, B1200 }, 844 { TARGET_CBAUD, TARGET_B1800, CBAUD, B1800 }, 845 { TARGET_CBAUD, TARGET_B2400, CBAUD, B2400 }, 846 { TARGET_CBAUD, TARGET_B4800, CBAUD, B4800 }, 847 { TARGET_CBAUD, TARGET_B9600, CBAUD, B9600 }, 848 { TARGET_CBAUD, TARGET_B19200, CBAUD, B19200 }, 849 { TARGET_CBAUD, TARGET_B38400, CBAUD, B38400 }, 850 { TARGET_CBAUD, TARGET_B57600, CBAUD, B57600 }, 851 { TARGET_CBAUD, TARGET_B115200, CBAUD, B115200 }, 852 { TARGET_CBAUD, TARGET_B230400, CBAUD, B230400 }, 853 { TARGET_CBAUD, TARGET_B460800, CBAUD, B460800 }, 854 { TARGET_CSIZE, TARGET_CS5, CSIZE, CS5 }, 855 { TARGET_CSIZE, TARGET_CS6, CSIZE, CS6 }, 856 { TARGET_CSIZE, TARGET_CS7, CSIZE, CS7 }, 857 { TARGET_CSIZE, TARGET_CS8, CSIZE, CS8 }, 858 { TARGET_CSTOPB, TARGET_CSTOPB, CSTOPB, CSTOPB }, 859 { TARGET_CREAD, TARGET_CREAD, CREAD, CREAD }, 860 { TARGET_PARENB, TARGET_PARENB, PARENB, PARENB }, 861 { TARGET_PARODD, TARGET_PARODD, PARODD, PARODD }, 862 { TARGET_HUPCL, TARGET_HUPCL, HUPCL, HUPCL }, 863 { TARGET_CLOCAL, TARGET_CLOCAL, CLOCAL, CLOCAL }, 864 { TARGET_CRTSCTS, TARGET_CRTSCTS, CRTSCTS, CRTSCTS }, 865 { 0, 0, 0, 0 } 866 }; 867 868 bitmask_transtbl lflag_tbl[] = { 869 { TARGET_ISIG, TARGET_ISIG, ISIG, ISIG }, 870 { TARGET_ICANON, TARGET_ICANON, ICANON, ICANON }, 871 { TARGET_XCASE, TARGET_XCASE, XCASE, XCASE }, 872 { TARGET_ECHO, TARGET_ECHO, ECHO, ECHO }, 873 { TARGET_ECHOE, TARGET_ECHOE, ECHOE, ECHOE }, 874 { TARGET_ECHOK, TARGET_ECHOK, ECHOK, ECHOK }, 875 { TARGET_ECHONL, TARGET_ECHONL, ECHONL, ECHONL }, 876 { TARGET_NOFLSH, TARGET_NOFLSH, NOFLSH, NOFLSH }, 877 { TARGET_TOSTOP, TARGET_TOSTOP, TOSTOP, TOSTOP }, 878 { TARGET_ECHOCTL, TARGET_ECHOCTL, ECHOCTL, ECHOCTL }, 879 { TARGET_ECHOPRT, TARGET_ECHOPRT, ECHOPRT, ECHOPRT }, 880 { TARGET_ECHOKE, TARGET_ECHOKE, ECHOKE, ECHOKE }, 881 { TARGET_FLUSHO, TARGET_FLUSHO, FLUSHO, FLUSHO }, 882 { TARGET_PENDIN, TARGET_PENDIN, PENDIN, PENDIN }, 883 { TARGET_IEXTEN, TARGET_IEXTEN, IEXTEN, IEXTEN }, 884 { 0, 0, 0, 0 } 885 }; 886 887 static void target_to_host_termios (void *dst, const void *src) 888 { 889 struct host_termios *host = dst; 890 const struct target_termios *target = src; 891 892 host->c_iflag = 893 target_to_host_bitmask(tswap32(target->c_iflag), iflag_tbl); 894 host->c_oflag = 895 target_to_host_bitmask(tswap32(target->c_oflag), oflag_tbl); 896 host->c_cflag = 897 target_to_host_bitmask(tswap32(target->c_cflag), cflag_tbl); 898 host->c_lflag = 899 target_to_host_bitmask(tswap32(target->c_lflag), lflag_tbl); 900 host->c_line = target->c_line; 901 902 host->c_cc[VINTR] = target->c_cc[TARGET_VINTR]; 903 host->c_cc[VQUIT] = target->c_cc[TARGET_VQUIT]; 904 host->c_cc[VERASE] = target->c_cc[TARGET_VERASE]; 905 host->c_cc[VKILL] = target->c_cc[TARGET_VKILL]; 906 host->c_cc[VEOF] = target->c_cc[TARGET_VEOF]; 907 host->c_cc[VTIME] = target->c_cc[TARGET_VTIME]; 908 host->c_cc[VMIN] = target->c_cc[TARGET_VMIN]; 909 host->c_cc[VSWTC] = target->c_cc[TARGET_VSWTC]; 910 host->c_cc[VSTART] = target->c_cc[TARGET_VSTART]; 911 host->c_cc[VSTOP] = target->c_cc[TARGET_VSTOP]; 912 host->c_cc[VSUSP] = target->c_cc[TARGET_VSUSP]; 913 host->c_cc[VEOL] = target->c_cc[TARGET_VEOL]; 914 host->c_cc[VREPRINT] = target->c_cc[TARGET_VREPRINT]; 915 host->c_cc[VDISCARD] = target->c_cc[TARGET_VDISCARD]; 916 host->c_cc[VWERASE] = target->c_cc[TARGET_VWERASE]; 917 host->c_cc[VLNEXT] = target->c_cc[TARGET_VLNEXT]; 918 host->c_cc[VEOL2] = target->c_cc[TARGET_VEOL2]; 919 } 920 921 static void host_to_target_termios (void *dst, const void *src) 922 { 923 struct target_termios *target = dst; 924 const struct host_termios *host = src; 925 926 target->c_iflag = 927 tswap32(host_to_target_bitmask(host->c_iflag, iflag_tbl)); 928 target->c_oflag = 929 tswap32(host_to_target_bitmask(host->c_oflag, oflag_tbl)); 930 target->c_cflag = 931 tswap32(host_to_target_bitmask(host->c_cflag, cflag_tbl)); 932 target->c_lflag = 933 tswap32(host_to_target_bitmask(host->c_lflag, lflag_tbl)); 934 target->c_line = host->c_line; 935 936 target->c_cc[TARGET_VINTR] = host->c_cc[VINTR]; 937 target->c_cc[TARGET_VQUIT] = host->c_cc[VQUIT]; 938 target->c_cc[TARGET_VERASE] = host->c_cc[VERASE]; 939 target->c_cc[TARGET_VKILL] = host->c_cc[VKILL]; 940 target->c_cc[TARGET_VEOF] = host->c_cc[VEOF]; 941 target->c_cc[TARGET_VTIME] = host->c_cc[VTIME]; 942 target->c_cc[TARGET_VMIN] = host->c_cc[VMIN]; 943 target->c_cc[TARGET_VSWTC] = host->c_cc[VSWTC]; 944 target->c_cc[TARGET_VSTART] = host->c_cc[VSTART]; 945 target->c_cc[TARGET_VSTOP] = host->c_cc[VSTOP]; 946 target->c_cc[TARGET_VSUSP] = host->c_cc[VSUSP]; 947 target->c_cc[TARGET_VEOL] = host->c_cc[VEOL]; 948 target->c_cc[TARGET_VREPRINT] = host->c_cc[VREPRINT]; 949 target->c_cc[TARGET_VDISCARD] = host->c_cc[VDISCARD]; 950 target->c_cc[TARGET_VWERASE] = host->c_cc[VWERASE]; 951 target->c_cc[TARGET_VLNEXT] = host->c_cc[VLNEXT]; 952 target->c_cc[TARGET_VEOL2] = host->c_cc[VEOL2]; 953 } 954 955 StructEntry struct_termios_def = { 956 .convert = { host_to_target_termios, target_to_host_termios }, 957 .size = { sizeof(struct target_termios), sizeof(struct host_termios) }, 958 .align = { __alignof__(struct target_termios), __alignof__(struct host_termios) }, 959 }; 960 961 static bitmask_transtbl mmap_flags_tbl[] = { 962 { TARGET_MAP_SHARED, TARGET_MAP_SHARED, MAP_SHARED, MAP_SHARED }, 963 { TARGET_MAP_PRIVATE, TARGET_MAP_PRIVATE, MAP_PRIVATE, MAP_PRIVATE }, 964 { TARGET_MAP_FIXED, TARGET_MAP_FIXED, MAP_FIXED, MAP_FIXED }, 965 { TARGET_MAP_ANONYMOUS, TARGET_MAP_ANONYMOUS, MAP_ANONYMOUS, MAP_ANONYMOUS }, 966 { TARGET_MAP_GROWSDOWN, TARGET_MAP_GROWSDOWN, MAP_GROWSDOWN, MAP_GROWSDOWN }, 967 { TARGET_MAP_DENYWRITE, TARGET_MAP_DENYWRITE, MAP_DENYWRITE, MAP_DENYWRITE }, 968 { TARGET_MAP_EXECUTABLE, TARGET_MAP_EXECUTABLE, MAP_EXECUTABLE, MAP_EXECUTABLE }, 969 { TARGET_MAP_LOCKED, TARGET_MAP_LOCKED, MAP_LOCKED, MAP_LOCKED }, 970 { 0, 0, 0, 0 } 971 }; 972 973 #ifdef TARGET_I386 974 975 /* NOTE: there is really one LDT for all the threads */ 976 uint8_t *ldt_table; 977 978 static int read_ldt(void *ptr, unsigned long bytecount) 979 { 980 int size; 981 982 if (!ldt_table) 983 return 0; 984 size = TARGET_LDT_ENTRIES * TARGET_LDT_ENTRY_SIZE; 985 if (size > bytecount) 986 size = bytecount; 987 memcpy(ptr, ldt_table, size); 988 return size; 989 } 990 991 /* XXX: add locking support */ 992 static int write_ldt(CPUX86State *env, 993 void *ptr, unsigned long bytecount, int oldmode) 994 { 995 struct target_modify_ldt_ldt_s ldt_info; 996 int seg_32bit, contents, read_exec_only, limit_in_pages; 997 int seg_not_present, useable; 998 uint32_t *lp, entry_1, entry_2; 999 1000 if (bytecount != sizeof(ldt_info)) 1001 return -EINVAL; 1002 memcpy(&ldt_info, ptr, sizeof(ldt_info)); 1003 tswap32s(&ldt_info.entry_number); 1004 tswapls((long *)&ldt_info.base_addr); 1005 tswap32s(&ldt_info.limit); 1006 tswap32s(&ldt_info.flags); 1007 1008 if (ldt_info.entry_number >= TARGET_LDT_ENTRIES) 1009 return -EINVAL; 1010 seg_32bit = ldt_info.flags & 1; 1011 contents = (ldt_info.flags >> 1) & 3; 1012 read_exec_only = (ldt_info.flags >> 3) & 1; 1013 limit_in_pages = (ldt_info.flags >> 4) & 1; 1014 seg_not_present = (ldt_info.flags >> 5) & 1; 1015 useable = (ldt_info.flags >> 6) & 1; 1016 1017 if (contents == 3) { 1018 if (oldmode) 1019 return -EINVAL; 1020 if (seg_not_present == 0) 1021 return -EINVAL; 1022 } 1023 /* allocate the LDT */ 1024 if (!ldt_table) { 1025 ldt_table = malloc(TARGET_LDT_ENTRIES * TARGET_LDT_ENTRY_SIZE); 1026 if (!ldt_table) 1027 return -ENOMEM; 1028 memset(ldt_table, 0, TARGET_LDT_ENTRIES * TARGET_LDT_ENTRY_SIZE); 1029 env->ldt.base = ldt_table; 1030 env->ldt.limit = 0xffff; 1031 } 1032 1033 /* NOTE: same code as Linux kernel */ 1034 /* Allow LDTs to be cleared by the user. */ 1035 if (ldt_info.base_addr == 0 && ldt_info.limit == 0) { 1036 if (oldmode || 1037 (contents == 0 && 1038 read_exec_only == 1 && 1039 seg_32bit == 0 && 1040 limit_in_pages == 0 && 1041 seg_not_present == 1 && 1042 useable == 0 )) { 1043 entry_1 = 0; 1044 entry_2 = 0; 1045 goto install; 1046 } 1047 } 1048 1049 entry_1 = ((ldt_info.base_addr & 0x0000ffff) << 16) | 1050 (ldt_info.limit & 0x0ffff); 1051 entry_2 = (ldt_info.base_addr & 0xff000000) | 1052 ((ldt_info.base_addr & 0x00ff0000) >> 16) | 1053 (ldt_info.limit & 0xf0000) | 1054 ((read_exec_only ^ 1) << 9) | 1055 (contents << 10) | 1056 ((seg_not_present ^ 1) << 15) | 1057 (seg_32bit << 22) | 1058 (limit_in_pages << 23) | 1059 0x7000; 1060 if (!oldmode) 1061 entry_2 |= (useable << 20); 1062 1063 /* Install the new entry ... */ 1064 install: 1065 lp = (uint32_t *)(ldt_table + (ldt_info.entry_number << 3)); 1066 lp[0] = tswap32(entry_1); 1067 lp[1] = tswap32(entry_2); 1068 return 0; 1069 } 1070 1071 /* specific and weird i386 syscalls */ 1072 int do_modify_ldt(CPUX86State *env, int func, void *ptr, unsigned long bytecount) 1073 { 1074 int ret = -ENOSYS; 1075 1076 switch (func) { 1077 case 0: 1078 ret = read_ldt(ptr, bytecount); 1079 break; 1080 case 1: 1081 ret = write_ldt(env, ptr, bytecount, 1); 1082 break; 1083 case 0x11: 1084 ret = write_ldt(env, ptr, bytecount, 0); 1085 break; 1086 } 1087 return ret; 1088 } 1089 1090 /* this stack is the equivalent of the kernel stack associated with a 1091 thread/process */ 1092 #define NEW_STACK_SIZE 8192 1093 1094 static int clone_func(void *arg) 1095 { 1096 CPUX86State *env = arg; 1097 cpu_loop(env); 1098 /* never exits */ 1099 return 0; 1100 } 1101 1102 int do_fork(CPUX86State *env, unsigned int flags, unsigned long newsp) 1103 { 1104 int ret; 1105 TaskState *ts; 1106 uint8_t *new_stack; 1107 CPUX86State *new_env; 1108 1109 if (flags & CLONE_VM) { 1110 if (!newsp) 1111 newsp = env->regs[R_ESP]; 1112 ts = malloc(sizeof(TaskState) + NEW_STACK_SIZE); 1113 memset(ts, 0, sizeof(TaskState)); 1114 new_stack = ts->stack; 1115 ts->used = 1; 1116 /* add in task state list */ 1117 ts->next = first_task_state; 1118 first_task_state = ts; 1119 /* we create a new CPU instance. */ 1120 new_env = cpu_x86_init(); 1121 memcpy(new_env, env, sizeof(CPUX86State)); 1122 new_env->regs[R_ESP] = newsp; 1123 new_env->regs[R_EAX] = 0; 1124 new_env->opaque = ts; 1125 #ifdef __ia64__ 1126 ret = clone2(clone_func, new_stack + NEW_STACK_SIZE, flags, new_env); 1127 #else 1128 ret = clone(clone_func, new_stack + NEW_STACK_SIZE, flags, new_env); 1129 #endif 1130 } else { 1131 /* if no CLONE_VM, we consider it is a fork */ 1132 if ((flags & ~CSIGNAL) != 0) 1133 return -EINVAL; 1134 ret = fork(); 1135 } 1136 return ret; 1137 } 1138 1139 #endif 1140 1141 static long do_fcntl(int fd, int cmd, unsigned long arg) 1142 { 1143 struct flock fl; 1144 struct target_flock *target_fl = (void *)arg; 1145 long ret; 1146 1147 switch(cmd) { 1148 case TARGET_F_GETLK: 1149 ret = fcntl(fd, cmd, &fl); 1150 if (ret == 0) { 1151 target_fl->l_type = tswap16(fl.l_type); 1152 target_fl->l_whence = tswap16(fl.l_whence); 1153 target_fl->l_start = tswapl(fl.l_start); 1154 target_fl->l_len = tswapl(fl.l_len); 1155 target_fl->l_pid = tswapl(fl.l_pid); 1156 } 1157 break; 1158 1159 case TARGET_F_SETLK: 1160 case TARGET_F_SETLKW: 1161 fl.l_type = tswap16(target_fl->l_type); 1162 fl.l_whence = tswap16(target_fl->l_whence); 1163 fl.l_start = tswapl(target_fl->l_start); 1164 fl.l_len = tswapl(target_fl->l_len); 1165 fl.l_pid = tswapl(target_fl->l_pid); 1166 ret = fcntl(fd, cmd, &fl); 1167 break; 1168 1169 case TARGET_F_GETLK64: 1170 case TARGET_F_SETLK64: 1171 case TARGET_F_SETLKW64: 1172 ret = -1; 1173 errno = EINVAL; 1174 break; 1175 1176 default: 1177 ret = fcntl(fd, cmd, arg); 1178 break; 1179 } 1180 return ret; 1181 } 1182 1183 1184 #define high2lowuid(x) (x) 1185 #define high2lowgid(x) (x) 1186 #define low2highuid(x) (x) 1187 #define low2highgid(x) (x) 1188 1189 void syscall_init(void) 1190 { 1191 #define STRUCT(name, list...) thunk_register_struct(STRUCT_ ## name, #name, struct_ ## name ## _def); 1192 #define STRUCT_SPECIAL(name) thunk_register_struct_direct(STRUCT_ ## name, #name, &struct_ ## name ## _def); 1193 #include "syscall_types.h" 1194 #undef STRUCT 1195 #undef STRUCT_SPECIAL 1196 } 1197 1198 long do_syscall(void *cpu_env, int num, long arg1, long arg2, long arg3, 1199 long arg4, long arg5, long arg6) 1200 { 1201 long ret; 1202 struct stat st; 1203 struct kernel_statfs *stfs; 1204 1205 #ifdef DEBUG 1206 gemu_log("syscall %d\n", num); 1207 #endif 1208 switch(num) { 1209 case TARGET_NR_exit: 1210 #ifdef HAVE_GPROF 1211 _mcleanup(); 1212 #endif 1213 /* XXX: should free thread stack and CPU env */ 1214 _exit(arg1); 1215 ret = 0; /* avoid warning */ 1216 break; 1217 case TARGET_NR_read: 1218 page_unprotect_range((void *)arg2, arg3); 1219 ret = get_errno(read(arg1, (void *)arg2, arg3)); 1220 break; 1221 case TARGET_NR_write: 1222 ret = get_errno(write(arg1, (void *)arg2, arg3)); 1223 break; 1224 case TARGET_NR_open: 1225 ret = get_errno(open(path((const char *)arg1), arg2, arg3)); 1226 break; 1227 case TARGET_NR_close: 1228 ret = get_errno(close(arg1)); 1229 break; 1230 case TARGET_NR_brk: 1231 ret = do_brk((char *)arg1); 1232 break; 1233 case TARGET_NR_fork: 1234 ret = get_errno(do_fork(cpu_env, SIGCHLD, 0)); 1235 break; 1236 case TARGET_NR_waitpid: 1237 { 1238 int *status = (int *)arg2; 1239 ret = get_errno(waitpid(arg1, status, arg3)); 1240 if (!is_error(ret) && status) 1241 tswapls((long *)&status); 1242 } 1243 break; 1244 case TARGET_NR_creat: 1245 ret = get_errno(creat((const char *)arg1, arg2)); 1246 break; 1247 case TARGET_NR_link: 1248 ret = get_errno(link((const char *)arg1, (const char *)arg2)); 1249 break; 1250 case TARGET_NR_unlink: 1251 ret = get_errno(unlink((const char *)arg1)); 1252 break; 1253 case TARGET_NR_execve: 1254 { 1255 char **argp, **envp; 1256 int argc, envc; 1257 uint32_t *p; 1258 char **q; 1259 1260 argc = 0; 1261 for (p = (void *)arg2; *p; p++) 1262 argc++; 1263 envc = 0; 1264 for (p = (void *)arg3; *p; p++) 1265 envc++; 1266 1267 argp = alloca((argc + 1) * sizeof(void *)); 1268 envp = alloca((envc + 1) * sizeof(void *)); 1269 1270 for (p = (void *)arg2, q = argp; *p; p++, q++) 1271 *q = (void *)tswap32(*p); 1272 *q = NULL; 1273 1274 for (p = (void *)arg3, q = envp; *p; p++, q++) 1275 *q = (void *)tswap32(*p); 1276 *q = NULL; 1277 1278 ret = get_errno(execve((const char *)arg1, argp, envp)); 1279 } 1280 break; 1281 case TARGET_NR_chdir: 1282 ret = get_errno(chdir((const char *)arg1)); 1283 break; 1284 case TARGET_NR_time: 1285 { 1286 int *time_ptr = (int *)arg1; 1287 ret = get_errno(time((time_t *)time_ptr)); 1288 if (!is_error(ret) && time_ptr) 1289 tswap32s(time_ptr); 1290 } 1291 break; 1292 case TARGET_NR_mknod: 1293 ret = get_errno(mknod((const char *)arg1, arg2, arg3)); 1294 break; 1295 case TARGET_NR_chmod: 1296 ret = get_errno(chmod((const char *)arg1, arg2)); 1297 break; 1298 case TARGET_NR_lchown: 1299 ret = get_errno(chown((const char *)arg1, arg2, arg3)); 1300 break; 1301 case TARGET_NR_break: 1302 goto unimplemented; 1303 case TARGET_NR_oldstat: 1304 goto unimplemented; 1305 case TARGET_NR_lseek: 1306 ret = get_errno(lseek(arg1, arg2, arg3)); 1307 break; 1308 case TARGET_NR_getpid: 1309 ret = get_errno(getpid()); 1310 break; 1311 case TARGET_NR_mount: 1312 /* need to look at the data field */ 1313 goto unimplemented; 1314 case TARGET_NR_umount: 1315 ret = get_errno(umount((const char *)arg1)); 1316 break; 1317 case TARGET_NR_setuid: 1318 ret = get_errno(setuid(low2highuid(arg1))); 1319 break; 1320 case TARGET_NR_getuid: 1321 ret = get_errno(getuid()); 1322 break; 1323 case TARGET_NR_stime: 1324 { 1325 int *time_ptr = (int *)arg1; 1326 if (time_ptr) 1327 tswap32s(time_ptr); 1328 ret = get_errno(stime((time_t *)time_ptr)); 1329 } 1330 break; 1331 case TARGET_NR_ptrace: 1332 goto unimplemented; 1333 case TARGET_NR_alarm: 1334 ret = alarm(arg1); 1335 break; 1336 case TARGET_NR_oldfstat: 1337 goto unimplemented; 1338 case TARGET_NR_pause: 1339 ret = get_errno(pause()); 1340 break; 1341 case TARGET_NR_utime: 1342 goto unimplemented; 1343 case TARGET_NR_stty: 1344 goto unimplemented; 1345 case TARGET_NR_gtty: 1346 goto unimplemented; 1347 case TARGET_NR_access: 1348 ret = get_errno(access((const char *)arg1, arg2)); 1349 break; 1350 case TARGET_NR_nice: 1351 ret = get_errno(nice(arg1)); 1352 break; 1353 case TARGET_NR_ftime: 1354 goto unimplemented; 1355 case TARGET_NR_sync: 1356 sync(); 1357 ret = 0; 1358 break; 1359 case TARGET_NR_kill: 1360 ret = get_errno(kill(arg1, arg2)); 1361 break; 1362 case TARGET_NR_rename: 1363 ret = get_errno(rename((const char *)arg1, (const char *)arg2)); 1364 break; 1365 case TARGET_NR_mkdir: 1366 ret = get_errno(mkdir((const char *)arg1, arg2)); 1367 break; 1368 case TARGET_NR_rmdir: 1369 ret = get_errno(rmdir((const char *)arg1)); 1370 break; 1371 case TARGET_NR_dup: 1372 ret = get_errno(dup(arg1)); 1373 break; 1374 case TARGET_NR_pipe: 1375 { 1376 int *pipe_ptr = (int *)arg1; 1377 ret = get_errno(pipe(pipe_ptr)); 1378 if (!is_error(ret)) { 1379 tswap32s(&pipe_ptr[0]); 1380 tswap32s(&pipe_ptr[1]); 1381 } 1382 } 1383 break; 1384 case TARGET_NR_times: 1385 { 1386 struct target_tms *tmsp = (void *)arg1; 1387 struct tms tms; 1388 ret = get_errno(times(&tms)); 1389 if (tmsp) { 1390 tmsp->tms_utime = tswapl(tms.tms_utime); 1391 tmsp->tms_stime = tswapl(tms.tms_stime); 1392 tmsp->tms_cutime = tswapl(tms.tms_cutime); 1393 tmsp->tms_cstime = tswapl(tms.tms_cstime); 1394 } 1395 } 1396 break; 1397 case TARGET_NR_prof: 1398 goto unimplemented; 1399 case TARGET_NR_setgid: 1400 ret = get_errno(setgid(low2highgid(arg1))); 1401 break; 1402 case TARGET_NR_getgid: 1403 ret = get_errno(getgid()); 1404 break; 1405 case TARGET_NR_signal: 1406 goto unimplemented; 1407 case TARGET_NR_geteuid: 1408 ret = get_errno(geteuid()); 1409 break; 1410 case TARGET_NR_getegid: 1411 ret = get_errno(getegid()); 1412 break; 1413 case TARGET_NR_acct: 1414 goto unimplemented; 1415 case TARGET_NR_umount2: 1416 ret = get_errno(umount2((const char *)arg1, arg2)); 1417 break; 1418 case TARGET_NR_lock: 1419 goto unimplemented; 1420 case TARGET_NR_ioctl: 1421 ret = do_ioctl(arg1, arg2, arg3); 1422 break; 1423 case TARGET_NR_fcntl: 1424 ret = get_errno(do_fcntl(arg1, arg2, arg3)); 1425 break; 1426 case TARGET_NR_mpx: 1427 goto unimplemented; 1428 case TARGET_NR_setpgid: 1429 ret = get_errno(setpgid(arg1, arg2)); 1430 break; 1431 case TARGET_NR_ulimit: 1432 goto unimplemented; 1433 case TARGET_NR_oldolduname: 1434 goto unimplemented; 1435 case TARGET_NR_umask: 1436 ret = get_errno(umask(arg1)); 1437 break; 1438 case TARGET_NR_chroot: 1439 ret = get_errno(chroot((const char *)arg1)); 1440 break; 1441 case TARGET_NR_ustat: 1442 goto unimplemented; 1443 case TARGET_NR_dup2: 1444 ret = get_errno(dup2(arg1, arg2)); 1445 break; 1446 case TARGET_NR_getppid: 1447 ret = get_errno(getppid()); 1448 break; 1449 case TARGET_NR_getpgrp: 1450 ret = get_errno(getpgrp()); 1451 break; 1452 case TARGET_NR_setsid: 1453 ret = get_errno(setsid()); 1454 break; 1455 case TARGET_NR_sigaction: 1456 { 1457 struct target_old_sigaction *old_act = (void *)arg2; 1458 struct target_old_sigaction *old_oact = (void *)arg3; 1459 struct target_sigaction act, oact, *pact; 1460 if (old_act) { 1461 act._sa_handler = old_act->_sa_handler; 1462 target_siginitset(&act.sa_mask, old_act->sa_mask); 1463 act.sa_flags = old_act->sa_flags; 1464 act.sa_restorer = old_act->sa_restorer; 1465 pact = &act; 1466 } else { 1467 pact = NULL; 1468 } 1469 ret = get_errno(do_sigaction(arg1, pact, &oact)); 1470 if (!is_error(ret) && old_oact) { 1471 old_oact->_sa_handler = oact._sa_handler; 1472 old_oact->sa_mask = oact.sa_mask.sig[0]; 1473 old_oact->sa_flags = oact.sa_flags; 1474 old_oact->sa_restorer = oact.sa_restorer; 1475 } 1476 } 1477 break; 1478 case TARGET_NR_rt_sigaction: 1479 ret = get_errno(do_sigaction(arg1, (void *)arg2, (void *)arg3)); 1480 break; 1481 case TARGET_NR_sgetmask: 1482 { 1483 sigset_t cur_set; 1484 target_ulong target_set; 1485 sigprocmask(0, NULL, &cur_set); 1486 host_to_target_old_sigset(&target_set, &cur_set); 1487 ret = target_set; 1488 } 1489 break; 1490 case TARGET_NR_ssetmask: 1491 { 1492 sigset_t set, oset, cur_set; 1493 target_ulong target_set = arg1; 1494 sigprocmask(0, NULL, &cur_set); 1495 target_to_host_old_sigset(&set, &target_set); 1496 sigorset(&set, &set, &cur_set); 1497 sigprocmask(SIG_SETMASK, &set, &oset); 1498 host_to_target_old_sigset(&target_set, &oset); 1499 ret = target_set; 1500 } 1501 break; 1502 case TARGET_NR_sigprocmask: 1503 { 1504 int how = arg1; 1505 sigset_t set, oldset, *set_ptr; 1506 target_ulong *pset = (void *)arg2, *poldset = (void *)arg3; 1507 1508 if (pset) { 1509 switch(how) { 1510 case TARGET_SIG_BLOCK: 1511 how = SIG_BLOCK; 1512 break; 1513 case TARGET_SIG_UNBLOCK: 1514 how = SIG_UNBLOCK; 1515 break; 1516 case TARGET_SIG_SETMASK: 1517 how = SIG_SETMASK; 1518 break; 1519 default: 1520 ret = -EINVAL; 1521 goto fail; 1522 } 1523 target_to_host_old_sigset(&set, pset); 1524 set_ptr = &set; 1525 } else { 1526 how = 0; 1527 set_ptr = NULL; 1528 } 1529 ret = get_errno(sigprocmask(arg1, set_ptr, &oldset)); 1530 if (!is_error(ret) && poldset) { 1531 host_to_target_old_sigset(poldset, &oldset); 1532 } 1533 } 1534 break; 1535 case TARGET_NR_rt_sigprocmask: 1536 { 1537 int how = arg1; 1538 sigset_t set, oldset, *set_ptr; 1539 target_sigset_t *pset = (void *)arg2; 1540 target_sigset_t *poldset = (void *)arg3; 1541 1542 if (pset) { 1543 switch(how) { 1544 case TARGET_SIG_BLOCK: 1545 how = SIG_BLOCK; 1546 break; 1547 case TARGET_SIG_UNBLOCK: 1548 how = SIG_UNBLOCK; 1549 break; 1550 case TARGET_SIG_SETMASK: 1551 how = SIG_SETMASK; 1552 break; 1553 default: 1554 ret = -EINVAL; 1555 goto fail; 1556 } 1557 target_to_host_sigset(&set, pset); 1558 set_ptr = &set; 1559 } else { 1560 how = 0; 1561 set_ptr = NULL; 1562 } 1563 ret = get_errno(sigprocmask(how, set_ptr, &oldset)); 1564 if (!is_error(ret) && poldset) { 1565 host_to_target_sigset(poldset, &oldset); 1566 } 1567 } 1568 break; 1569 case TARGET_NR_sigpending: 1570 { 1571 sigset_t set; 1572 ret = get_errno(sigpending(&set)); 1573 if (!is_error(ret)) { 1574 host_to_target_old_sigset((target_ulong *)arg1, &set); 1575 } 1576 } 1577 break; 1578 case TARGET_NR_rt_sigpending: 1579 { 1580 sigset_t set; 1581 ret = get_errno(sigpending(&set)); 1582 if (!is_error(ret)) { 1583 host_to_target_sigset((target_sigset_t *)arg1, &set); 1584 } 1585 } 1586 break; 1587 case TARGET_NR_sigsuspend: 1588 { 1589 sigset_t set; 1590 target_to_host_old_sigset(&set, (target_ulong *)arg1); 1591 ret = get_errno(sigsuspend(&set)); 1592 } 1593 break; 1594 case TARGET_NR_rt_sigsuspend: 1595 { 1596 sigset_t set; 1597 target_to_host_sigset(&set, (target_sigset_t *)arg1); 1598 ret = get_errno(sigsuspend(&set)); 1599 } 1600 break; 1601 case TARGET_NR_rt_sigtimedwait: 1602 { 1603 target_sigset_t *target_set = (void *)arg1; 1604 target_siginfo_t *target_uinfo = (void *)arg2; 1605 struct target_timespec *target_uts = (void *)arg3; 1606 sigset_t set; 1607 struct timespec uts, *puts; 1608 siginfo_t uinfo; 1609 1610 target_to_host_sigset(&set, target_set); 1611 if (target_uts) { 1612 puts = &uts; 1613 puts->tv_sec = tswapl(target_uts->tv_sec); 1614 puts->tv_nsec = tswapl(target_uts->tv_nsec); 1615 } else { 1616 puts = NULL; 1617 } 1618 ret = get_errno(sigtimedwait(&set, &uinfo, puts)); 1619 if (!is_error(ret) && target_uinfo) { 1620 host_to_target_siginfo(target_uinfo, &uinfo); 1621 } 1622 } 1623 break; 1624 case TARGET_NR_rt_sigqueueinfo: 1625 { 1626 siginfo_t uinfo; 1627 target_to_host_siginfo(&uinfo, (target_siginfo_t *)arg3); 1628 ret = get_errno(sys_rt_sigqueueinfo(arg1, arg2, &uinfo)); 1629 } 1630 break; 1631 case TARGET_NR_sigreturn: 1632 /* NOTE: ret is eax, so not transcoding must be done */ 1633 ret = do_sigreturn(cpu_env); 1634 break; 1635 case TARGET_NR_rt_sigreturn: 1636 /* NOTE: ret is eax, so not transcoding must be done */ 1637 ret = do_rt_sigreturn(cpu_env); 1638 break; 1639 case TARGET_NR_setreuid: 1640 ret = get_errno(setreuid(arg1, arg2)); 1641 break; 1642 case TARGET_NR_setregid: 1643 ret = get_errno(setregid(arg1, arg2)); 1644 break; 1645 case TARGET_NR_sethostname: 1646 ret = get_errno(sethostname((const char *)arg1, arg2)); 1647 break; 1648 case TARGET_NR_setrlimit: 1649 { 1650 /* XXX: convert resource ? */ 1651 int resource = arg1; 1652 struct target_rlimit *target_rlim = (void *)arg2; 1653 struct rlimit rlim; 1654 rlim.rlim_cur = tswapl(target_rlim->rlim_cur); 1655 rlim.rlim_max = tswapl(target_rlim->rlim_max); 1656 ret = get_errno(setrlimit(resource, &rlim)); 1657 } 1658 break; 1659 case TARGET_NR_getrlimit: 1660 { 1661 /* XXX: convert resource ? */ 1662 int resource = arg1; 1663 struct target_rlimit *target_rlim = (void *)arg2; 1664 struct rlimit rlim; 1665 1666 ret = get_errno(getrlimit(resource, &rlim)); 1667 if (!is_error(ret)) { 1668 target_rlim->rlim_cur = tswapl(rlim.rlim_cur); 1669 target_rlim->rlim_max = tswapl(rlim.rlim_max); 1670 } 1671 } 1672 break; 1673 case TARGET_NR_getrusage: 1674 { 1675 struct rusage rusage; 1676 struct target_rusage *target_rusage = (void *)arg2; 1677 ret = get_errno(getrusage(arg1, &rusage)); 1678 if (!is_error(ret)) { 1679 host_to_target_rusage(target_rusage, &rusage); 1680 } 1681 } 1682 break; 1683 case TARGET_NR_gettimeofday: 1684 { 1685 struct target_timeval *target_tv = (void *)arg1; 1686 struct timeval tv; 1687 ret = get_errno(gettimeofday(&tv, NULL)); 1688 if (!is_error(ret)) { 1689 host_to_target_timeval(target_tv, &tv); 1690 } 1691 } 1692 break; 1693 case TARGET_NR_settimeofday: 1694 { 1695 struct target_timeval *target_tv = (void *)arg1; 1696 struct timeval tv; 1697 target_to_host_timeval(&tv, target_tv); 1698 ret = get_errno(settimeofday(&tv, NULL)); 1699 } 1700 break; 1701 case TARGET_NR_getgroups: 1702 { 1703 int gidsetsize = arg1; 1704 uint16_t *target_grouplist = (void *)arg2; 1705 gid_t *grouplist; 1706 int i; 1707 1708 grouplist = alloca(gidsetsize * sizeof(gid_t)); 1709 ret = get_errno(getgroups(gidsetsize, grouplist)); 1710 if (!is_error(ret)) { 1711 for(i = 0;i < gidsetsize; i++) 1712 target_grouplist[i] = tswap16(grouplist[i]); 1713 } 1714 } 1715 break; 1716 case TARGET_NR_setgroups: 1717 { 1718 int gidsetsize = arg1; 1719 uint16_t *target_grouplist = (void *)arg2; 1720 gid_t *grouplist; 1721 int i; 1722 1723 grouplist = alloca(gidsetsize * sizeof(gid_t)); 1724 for(i = 0;i < gidsetsize; i++) 1725 grouplist[i] = tswap16(target_grouplist[i]); 1726 ret = get_errno(setgroups(gidsetsize, grouplist)); 1727 } 1728 break; 1729 case TARGET_NR_select: 1730 goto unimplemented; 1731 case TARGET_NR_symlink: 1732 ret = get_errno(symlink((const char *)arg1, (const char *)arg2)); 1733 break; 1734 case TARGET_NR_oldlstat: 1735 goto unimplemented; 1736 case TARGET_NR_readlink: 1737 ret = get_errno(readlink(path((const char *)arg1), (char *)arg2, arg3)); 1738 break; 1739 case TARGET_NR_uselib: 1740 goto unimplemented; 1741 case TARGET_NR_swapon: 1742 ret = get_errno(swapon((const char *)arg1, arg2)); 1743 break; 1744 case TARGET_NR_reboot: 1745 goto unimplemented; 1746 case TARGET_NR_readdir: 1747 goto unimplemented; 1748 #ifdef TARGET_I386 1749 case TARGET_NR_mmap: 1750 { 1751 uint32_t v1, v2, v3, v4, v5, v6, *vptr; 1752 vptr = (uint32_t *)arg1; 1753 v1 = tswap32(vptr[0]); 1754 v2 = tswap32(vptr[1]); 1755 v3 = tswap32(vptr[2]); 1756 v4 = tswap32(vptr[3]); 1757 v5 = tswap32(vptr[4]); 1758 v6 = tswap32(vptr[5]); 1759 ret = get_errno(target_mmap(v1, v2, v3, 1760 target_to_host_bitmask(v4, mmap_flags_tbl), 1761 v5, v6)); 1762 } 1763 break; 1764 #endif 1765 #ifdef TARGET_I386 1766 case TARGET_NR_mmap2: 1767 #else 1768 case TARGET_NR_mmap: 1769 #endif 1770 ret = get_errno(target_mmap(arg1, arg2, arg3, 1771 target_to_host_bitmask(arg4, mmap_flags_tbl), 1772 arg5, 1773 arg6 << TARGET_PAGE_BITS)); 1774 break; 1775 case TARGET_NR_munmap: 1776 ret = get_errno(target_munmap(arg1, arg2)); 1777 break; 1778 case TARGET_NR_mprotect: 1779 ret = get_errno(target_mprotect(arg1, arg2, arg3)); 1780 break; 1781 case TARGET_NR_mremap: 1782 ret = get_errno(target_mremap(arg1, arg2, arg3, arg4, arg5)); 1783 break; 1784 case TARGET_NR_msync: 1785 ret = get_errno(msync((void *)arg1, arg2, arg3)); 1786 break; 1787 case TARGET_NR_mlock: 1788 ret = get_errno(mlock((void *)arg1, arg2)); 1789 break; 1790 case TARGET_NR_munlock: 1791 ret = get_errno(munlock((void *)arg1, arg2)); 1792 break; 1793 case TARGET_NR_mlockall: 1794 ret = get_errno(mlockall(arg1)); 1795 break; 1796 case TARGET_NR_munlockall: 1797 ret = get_errno(munlockall()); 1798 break; 1799 case TARGET_NR_truncate: 1800 ret = get_errno(truncate((const char *)arg1, arg2)); 1801 break; 1802 case TARGET_NR_ftruncate: 1803 ret = get_errno(ftruncate(arg1, arg2)); 1804 break; 1805 case TARGET_NR_fchmod: 1806 ret = get_errno(fchmod(arg1, arg2)); 1807 break; 1808 case TARGET_NR_fchown: 1809 ret = get_errno(fchown(arg1, arg2, arg3)); 1810 break; 1811 case TARGET_NR_getpriority: 1812 ret = get_errno(getpriority(arg1, arg2)); 1813 break; 1814 case TARGET_NR_setpriority: 1815 ret = get_errno(setpriority(arg1, arg2, arg3)); 1816 break; 1817 case TARGET_NR_profil: 1818 goto unimplemented; 1819 case TARGET_NR_statfs: 1820 stfs = (void *)arg2; 1821 ret = get_errno(sys_statfs(path((const char *)arg1), stfs)); 1822 convert_statfs: 1823 if (!is_error(ret)) { 1824 tswap32s(&stfs->f_type); 1825 tswap32s(&stfs->f_bsize); 1826 tswap32s(&stfs->f_blocks); 1827 tswap32s(&stfs->f_bfree); 1828 tswap32s(&stfs->f_bavail); 1829 tswap32s(&stfs->f_files); 1830 tswap32s(&stfs->f_ffree); 1831 tswap32s(&stfs->f_fsid.val[0]); 1832 tswap32s(&stfs->f_fsid.val[1]); 1833 tswap32s(&stfs->f_namelen); 1834 } 1835 break; 1836 case TARGET_NR_fstatfs: 1837 stfs = (void *)arg2; 1838 ret = get_errno(sys_fstatfs(arg1, stfs)); 1839 goto convert_statfs; 1840 case TARGET_NR_ioperm: 1841 goto unimplemented; 1842 case TARGET_NR_socketcall: 1843 ret = do_socketcall(arg1, (int32_t *)arg2); 1844 break; 1845 case TARGET_NR_syslog: 1846 goto unimplemented; 1847 case TARGET_NR_setitimer: 1848 { 1849 struct target_itimerval *target_value = (void *)arg2; 1850 struct target_itimerval *target_ovalue = (void *)arg3; 1851 struct itimerval value, ovalue, *pvalue; 1852 1853 if (target_value) { 1854 pvalue = &value; 1855 target_to_host_timeval(&pvalue->it_interval, 1856 &target_value->it_interval); 1857 target_to_host_timeval(&pvalue->it_value, 1858 &target_value->it_value); 1859 } else { 1860 pvalue = NULL; 1861 } 1862 ret = get_errno(setitimer(arg1, pvalue, &ovalue)); 1863 if (!is_error(ret) && target_ovalue) { 1864 host_to_target_timeval(&target_ovalue->it_interval, 1865 &ovalue.it_interval); 1866 host_to_target_timeval(&target_ovalue->it_value, 1867 &ovalue.it_value); 1868 } 1869 } 1870 break; 1871 case TARGET_NR_getitimer: 1872 { 1873 struct target_itimerval *target_value = (void *)arg2; 1874 struct itimerval value; 1875 1876 ret = get_errno(getitimer(arg1, &value)); 1877 if (!is_error(ret) && target_value) { 1878 host_to_target_timeval(&target_value->it_interval, 1879 &value.it_interval); 1880 host_to_target_timeval(&target_value->it_value, 1881 &value.it_value); 1882 } 1883 } 1884 break; 1885 case TARGET_NR_stat: 1886 ret = get_errno(stat(path((const char *)arg1), &st)); 1887 goto do_stat; 1888 case TARGET_NR_lstat: 1889 ret = get_errno(lstat(path((const char *)arg1), &st)); 1890 goto do_stat; 1891 case TARGET_NR_fstat: 1892 { 1893 ret = get_errno(fstat(arg1, &st)); 1894 do_stat: 1895 if (!is_error(ret)) { 1896 struct target_stat *target_st = (void *)arg2; 1897 target_st->st_dev = tswap16(st.st_dev); 1898 target_st->st_ino = tswapl(st.st_ino); 1899 target_st->st_mode = tswap16(st.st_mode); 1900 target_st->st_nlink = tswap16(st.st_nlink); 1901 target_st->st_uid = tswap16(st.st_uid); 1902 target_st->st_gid = tswap16(st.st_gid); 1903 target_st->st_rdev = tswap16(st.st_rdev); 1904 target_st->st_size = tswapl(st.st_size); 1905 target_st->st_blksize = tswapl(st.st_blksize); 1906 target_st->st_blocks = tswapl(st.st_blocks); 1907 target_st->target_st_atime = tswapl(st.st_atime); 1908 target_st->target_st_mtime = tswapl(st.st_mtime); 1909 target_st->target_st_ctime = tswapl(st.st_ctime); 1910 } 1911 } 1912 break; 1913 case TARGET_NR_olduname: 1914 goto unimplemented; 1915 case TARGET_NR_iopl: 1916 goto unimplemented; 1917 case TARGET_NR_vhangup: 1918 ret = get_errno(vhangup()); 1919 break; 1920 case TARGET_NR_idle: 1921 goto unimplemented; 1922 case TARGET_NR_wait4: 1923 { 1924 int status; 1925 target_long *status_ptr = (void *)arg2; 1926 struct rusage rusage, *rusage_ptr; 1927 struct target_rusage *target_rusage = (void *)arg4; 1928 if (target_rusage) 1929 rusage_ptr = &rusage; 1930 else 1931 rusage_ptr = NULL; 1932 ret = get_errno(wait4(arg1, &status, arg3, rusage_ptr)); 1933 if (!is_error(ret)) { 1934 if (status_ptr) 1935 *status_ptr = tswap32(status); 1936 if (target_rusage) { 1937 host_to_target_rusage(target_rusage, &rusage); 1938 } 1939 } 1940 } 1941 break; 1942 case TARGET_NR_swapoff: 1943 ret = get_errno(swapoff((const char *)arg1)); 1944 break; 1945 case TARGET_NR_sysinfo: 1946 goto unimplemented; 1947 case TARGET_NR_ipc: 1948 goto unimplemented; 1949 case TARGET_NR_fsync: 1950 ret = get_errno(fsync(arg1)); 1951 break; 1952 case TARGET_NR_clone: 1953 ret = get_errno(do_fork(cpu_env, arg1, arg2)); 1954 break; 1955 #ifdef __NR_exit_group 1956 /* new thread calls */ 1957 case TARGET_NR_exit_group: 1958 ret = get_errno(exit_group(arg1)); 1959 break; 1960 #endif 1961 case TARGET_NR_setdomainname: 1962 ret = get_errno(setdomainname((const char *)arg1, arg2)); 1963 break; 1964 case TARGET_NR_uname: 1965 /* no need to transcode because we use the linux syscall */ 1966 ret = get_errno(sys_uname((struct new_utsname *)arg1)); 1967 break; 1968 #ifdef TARGET_I386 1969 case TARGET_NR_modify_ldt: 1970 ret = get_errno(do_modify_ldt(cpu_env, arg1, (void *)arg2, arg3)); 1971 break; 1972 case TARGET_NR_vm86old: 1973 goto unimplemented; 1974 case TARGET_NR_vm86: 1975 ret = do_vm86(cpu_env, arg1, (void *)arg2); 1976 break; 1977 #endif 1978 case TARGET_NR_adjtimex: 1979 goto unimplemented; 1980 case TARGET_NR_create_module: 1981 case TARGET_NR_init_module: 1982 case TARGET_NR_delete_module: 1983 case TARGET_NR_get_kernel_syms: 1984 goto unimplemented; 1985 case TARGET_NR_quotactl: 1986 goto unimplemented; 1987 case TARGET_NR_getpgid: 1988 ret = get_errno(getpgid(arg1)); 1989 break; 1990 case TARGET_NR_fchdir: 1991 ret = get_errno(fchdir(arg1)); 1992 break; 1993 case TARGET_NR_bdflush: 1994 goto unimplemented; 1995 case TARGET_NR_sysfs: 1996 goto unimplemented; 1997 case TARGET_NR_personality: 1998 ret = get_errno(personality(arg1)); 1999 break; 2000 case TARGET_NR_afs_syscall: 2001 goto unimplemented; 2002 case TARGET_NR_setfsuid: 2003 ret = get_errno(setfsuid(arg1)); 2004 break; 2005 case TARGET_NR_setfsgid: 2006 ret = get_errno(setfsgid(arg1)); 2007 break; 2008 case TARGET_NR__llseek: 2009 { 2010 int64_t res; 2011 ret = get_errno(_llseek(arg1, arg2, arg3, &res, arg5)); 2012 *(int64_t *)arg4 = tswap64(res); 2013 } 2014 break; 2015 case TARGET_NR_getdents: 2016 #if TARGET_LONG_SIZE != 4 2017 #error not supported 2018 #endif 2019 { 2020 struct dirent *dirp = (void *)arg2; 2021 long count = arg3; 2022 2023 ret = get_errno(sys_getdents(arg1, dirp, count)); 2024 if (!is_error(ret)) { 2025 struct dirent *de; 2026 int len = ret; 2027 int reclen; 2028 de = dirp; 2029 while (len > 0) { 2030 reclen = de->d_reclen; 2031 if (reclen > len) 2032 break; 2033 de->d_reclen = tswap16(reclen); 2034 tswapls(&de->d_ino); 2035 tswapls(&de->d_off); 2036 de = (struct dirent *)((char *)de + reclen); 2037 len -= reclen; 2038 } 2039 } 2040 } 2041 break; 2042 case TARGET_NR_getdents64: 2043 { 2044 struct dirent64 *dirp = (void *)arg2; 2045 long count = arg3; 2046 ret = get_errno(sys_getdents64(arg1, dirp, count)); 2047 if (!is_error(ret)) { 2048 struct dirent64 *de; 2049 int len = ret; 2050 int reclen; 2051 de = dirp; 2052 while (len > 0) { 2053 reclen = de->d_reclen; 2054 if (reclen > len) 2055 break; 2056 de->d_reclen = tswap16(reclen); 2057 tswap64s(&de->d_ino); 2058 tswap64s(&de->d_off); 2059 de = (struct dirent64 *)((char *)de + reclen); 2060 len -= reclen; 2061 } 2062 } 2063 } 2064 break; 2065 case TARGET_NR__newselect: 2066 ret = do_select(arg1, (void *)arg2, (void *)arg3, (void *)arg4, 2067 (void *)arg5); 2068 break; 2069 case TARGET_NR_poll: 2070 { 2071 struct target_pollfd *target_pfd = (void *)arg1; 2072 unsigned int nfds = arg2; 2073 int timeout = arg3; 2074 struct pollfd *pfd; 2075 unsigned int i; 2076 2077 pfd = alloca(sizeof(struct pollfd) * nfds); 2078 for(i = 0; i < nfds; i++) { 2079 pfd[i].fd = tswap32(target_pfd[i].fd); 2080 pfd[i].events = tswap16(target_pfd[i].events); 2081 } 2082 ret = get_errno(poll(pfd, nfds, timeout)); 2083 if (!is_error(ret)) { 2084 for(i = 0; i < nfds; i++) { 2085 target_pfd[i].revents = tswap16(pfd[i].revents); 2086 } 2087 } 2088 } 2089 break; 2090 case TARGET_NR_flock: 2091 /* NOTE: the flock constant seems to be the same for every 2092 Linux platform */ 2093 ret = get_errno(flock(arg1, arg2)); 2094 break; 2095 case TARGET_NR_readv: 2096 { 2097 int count = arg3; 2098 int i; 2099 struct iovec *vec; 2100 struct target_iovec *target_vec = (void *)arg2; 2101 2102 vec = alloca(count * sizeof(struct iovec)); 2103 for(i = 0;i < count; i++) { 2104 vec[i].iov_base = (void *)tswapl(target_vec[i].iov_base); 2105 vec[i].iov_len = tswapl(target_vec[i].iov_len); 2106 } 2107 ret = get_errno(readv(arg1, vec, count)); 2108 } 2109 break; 2110 case TARGET_NR_writev: 2111 { 2112 int count = arg3; 2113 int i; 2114 struct iovec *vec; 2115 struct target_iovec *target_vec = (void *)arg2; 2116 2117 vec = alloca(count * sizeof(struct iovec)); 2118 for(i = 0;i < count; i++) { 2119 vec[i].iov_base = (void *)tswapl(target_vec[i].iov_base); 2120 vec[i].iov_len = tswapl(target_vec[i].iov_len); 2121 } 2122 ret = get_errno(writev(arg1, vec, count)); 2123 } 2124 break; 2125 case TARGET_NR_getsid: 2126 ret = get_errno(getsid(arg1)); 2127 break; 2128 case TARGET_NR_fdatasync: 2129 ret = get_errno(fdatasync(arg1)); 2130 break; 2131 case TARGET_NR__sysctl: 2132 goto unimplemented; 2133 case TARGET_NR_sched_setparam: 2134 { 2135 struct sched_param *target_schp = (void *)arg2; 2136 struct sched_param schp; 2137 schp.sched_priority = tswap32(target_schp->sched_priority); 2138 ret = get_errno(sched_setparam(arg1, &schp)); 2139 } 2140 break; 2141 case TARGET_NR_sched_getparam: 2142 { 2143 struct sched_param *target_schp = (void *)arg2; 2144 struct sched_param schp; 2145 ret = get_errno(sched_getparam(arg1, &schp)); 2146 if (!is_error(ret)) { 2147 target_schp->sched_priority = tswap32(schp.sched_priority); 2148 } 2149 } 2150 break; 2151 case TARGET_NR_sched_setscheduler: 2152 { 2153 struct sched_param *target_schp = (void *)arg3; 2154 struct sched_param schp; 2155 schp.sched_priority = tswap32(target_schp->sched_priority); 2156 ret = get_errno(sched_setscheduler(arg1, arg2, &schp)); 2157 } 2158 break; 2159 case TARGET_NR_sched_getscheduler: 2160 ret = get_errno(sched_getscheduler(arg1)); 2161 break; 2162 case TARGET_NR_sched_yield: 2163 ret = get_errno(sched_yield()); 2164 break; 2165 case TARGET_NR_sched_get_priority_max: 2166 ret = get_errno(sched_get_priority_max(arg1)); 2167 break; 2168 case TARGET_NR_sched_get_priority_min: 2169 ret = get_errno(sched_get_priority_min(arg1)); 2170 break; 2171 case TARGET_NR_sched_rr_get_interval: 2172 { 2173 struct target_timespec *target_ts = (void *)arg2; 2174 struct timespec ts; 2175 ret = get_errno(sched_rr_get_interval(arg1, &ts)); 2176 if (!is_error(ret)) { 2177 target_ts->tv_sec = tswapl(ts.tv_sec); 2178 target_ts->tv_nsec = tswapl(ts.tv_nsec); 2179 } 2180 } 2181 break; 2182 case TARGET_NR_nanosleep: 2183 { 2184 struct target_timespec *target_req = (void *)arg1; 2185 struct target_timespec *target_rem = (void *)arg2; 2186 struct timespec req, rem; 2187 req.tv_sec = tswapl(target_req->tv_sec); 2188 req.tv_nsec = tswapl(target_req->tv_nsec); 2189 ret = get_errno(nanosleep(&req, &rem)); 2190 if (target_rem) { 2191 target_rem->tv_sec = tswapl(rem.tv_sec); 2192 target_rem->tv_nsec = tswapl(rem.tv_nsec); 2193 } 2194 } 2195 break; 2196 case TARGET_NR_setresuid: 2197 ret = get_errno(setresuid(low2highuid(arg1), 2198 low2highuid(arg2), 2199 low2highuid(arg3))); 2200 break; 2201 case TARGET_NR_getresuid: 2202 { 2203 int ruid, euid, suid; 2204 ret = get_errno(getresuid(&ruid, &euid, &suid)); 2205 if (!is_error(ret)) { 2206 *(uint16_t *)arg1 = tswap16(high2lowuid(ruid)); 2207 *(uint16_t *)arg2 = tswap16(high2lowuid(euid)); 2208 *(uint16_t *)arg3 = tswap16(high2lowuid(suid)); 2209 } 2210 } 2211 break; 2212 case TARGET_NR_setresgid: 2213 ret = get_errno(setresgid(low2highgid(arg1), 2214 low2highgid(arg2), 2215 low2highgid(arg3))); 2216 break; 2217 case TARGET_NR_getresgid: 2218 { 2219 int rgid, egid, sgid; 2220 ret = get_errno(getresgid(&rgid, &egid, &sgid)); 2221 if (!is_error(ret)) { 2222 *(uint16_t *)arg1 = high2lowgid(tswap16(rgid)); 2223 *(uint16_t *)arg2 = high2lowgid(tswap16(egid)); 2224 *(uint16_t *)arg3 = high2lowgid(tswap16(sgid)); 2225 } 2226 } 2227 break; 2228 case TARGET_NR_query_module: 2229 goto unimplemented; 2230 case TARGET_NR_nfsservctl: 2231 goto unimplemented; 2232 case TARGET_NR_prctl: 2233 goto unimplemented; 2234 case TARGET_NR_pread: 2235 page_unprotect_range((void *)arg2, arg3); 2236 ret = get_errno(pread(arg1, (void *)arg2, arg3, arg4)); 2237 break; 2238 case TARGET_NR_pwrite: 2239 ret = get_errno(pwrite(arg1, (void *)arg2, arg3, arg4)); 2240 break; 2241 case TARGET_NR_chown: 2242 ret = get_errno(chown((const char *)arg1, arg2, arg3)); 2243 break; 2244 case TARGET_NR_getcwd: 2245 ret = get_errno(sys_getcwd1((char *)arg1, arg2)); 2246 break; 2247 case TARGET_NR_capget: 2248 goto unimplemented; 2249 case TARGET_NR_capset: 2250 goto unimplemented; 2251 case TARGET_NR_sigaltstack: 2252 goto unimplemented; 2253 case TARGET_NR_sendfile: 2254 goto unimplemented; 2255 case TARGET_NR_getpmsg: 2256 goto unimplemented; 2257 case TARGET_NR_putpmsg: 2258 goto unimplemented; 2259 case TARGET_NR_vfork: 2260 ret = get_errno(do_fork(cpu_env, CLONE_VFORK | CLONE_VM | SIGCHLD, 0)); 2261 break; 2262 case TARGET_NR_ugetrlimit: 2263 { 2264 struct rlimit rlim; 2265 ret = get_errno(getrlimit(arg1, &rlim)); 2266 if (!is_error(ret)) { 2267 struct target_rlimit *target_rlim = (void *)arg2; 2268 target_rlim->rlim_cur = tswapl(rlim.rlim_cur); 2269 target_rlim->rlim_max = tswapl(rlim.rlim_max); 2270 } 2271 break; 2272 } 2273 case TARGET_NR_truncate64: 2274 goto unimplemented; 2275 case TARGET_NR_ftruncate64: 2276 goto unimplemented; 2277 case TARGET_NR_stat64: 2278 ret = get_errno(stat(path((const char *)arg1), &st)); 2279 goto do_stat64; 2280 case TARGET_NR_lstat64: 2281 ret = get_errno(lstat(path((const char *)arg1), &st)); 2282 goto do_stat64; 2283 case TARGET_NR_fstat64: 2284 { 2285 ret = get_errno(fstat(arg1, &st)); 2286 do_stat64: 2287 if (!is_error(ret)) { 2288 struct target_stat64 *target_st = (void *)arg2; 2289 memset(target_st, 0, sizeof(struct target_stat64)); 2290 target_st->st_dev = tswap16(st.st_dev); 2291 target_st->st_ino = tswap64(st.st_ino); 2292 #ifdef TARGET_STAT64_HAS_BROKEN_ST_INO 2293 target_st->__st_ino = tswapl(st.st_ino); 2294 #endif 2295 target_st->st_mode = tswap32(st.st_mode); 2296 target_st->st_nlink = tswap32(st.st_nlink); 2297 target_st->st_uid = tswapl(st.st_uid); 2298 target_st->st_gid = tswapl(st.st_gid); 2299 target_st->st_rdev = tswap16(st.st_rdev); 2300 /* XXX: better use of kernel struct */ 2301 target_st->st_size = tswap64(st.st_size); 2302 target_st->st_blksize = tswapl(st.st_blksize); 2303 target_st->st_blocks = tswapl(st.st_blocks); 2304 target_st->target_st_atime = tswapl(st.st_atime); 2305 target_st->target_st_mtime = tswapl(st.st_mtime); 2306 target_st->target_st_ctime = tswapl(st.st_ctime); 2307 } 2308 } 2309 break; 2310 2311 case TARGET_NR_lchown32: 2312 ret = get_errno(lchown((const char *)arg1, arg2, arg3)); 2313 break; 2314 case TARGET_NR_getuid32: 2315 ret = get_errno(getuid()); 2316 break; 2317 case TARGET_NR_getgid32: 2318 ret = get_errno(getgid()); 2319 break; 2320 case TARGET_NR_geteuid32: 2321 ret = get_errno(geteuid()); 2322 break; 2323 case TARGET_NR_getegid32: 2324 ret = get_errno(getegid()); 2325 break; 2326 case TARGET_NR_setreuid32: 2327 ret = get_errno(setreuid(arg1, arg2)); 2328 break; 2329 case TARGET_NR_setregid32: 2330 ret = get_errno(setregid(arg1, arg2)); 2331 break; 2332 case TARGET_NR_getgroups32: 2333 goto unimplemented; 2334 case TARGET_NR_setgroups32: 2335 goto unimplemented; 2336 case TARGET_NR_fchown32: 2337 ret = get_errno(fchown(arg1, arg2, arg3)); 2338 break; 2339 case TARGET_NR_setresuid32: 2340 ret = get_errno(setresuid(arg1, arg2, arg3)); 2341 break; 2342 case TARGET_NR_getresuid32: 2343 { 2344 int ruid, euid, suid; 2345 ret = get_errno(getresuid(&ruid, &euid, &suid)); 2346 if (!is_error(ret)) { 2347 *(uint32_t *)arg1 = tswap32(ruid); 2348 *(uint32_t *)arg2 = tswap32(euid); 2349 *(uint32_t *)arg3 = tswap32(suid); 2350 } 2351 } 2352 break; 2353 case TARGET_NR_setresgid32: 2354 ret = get_errno(setresgid(arg1, arg2, arg3)); 2355 break; 2356 case TARGET_NR_getresgid32: 2357 { 2358 int rgid, egid, sgid; 2359 ret = get_errno(getresgid(&rgid, &egid, &sgid)); 2360 if (!is_error(ret)) { 2361 *(uint32_t *)arg1 = tswap32(rgid); 2362 *(uint32_t *)arg2 = tswap32(egid); 2363 *(uint32_t *)arg3 = tswap32(sgid); 2364 } 2365 } 2366 break; 2367 case TARGET_NR_chown32: 2368 ret = get_errno(chown((const char *)arg1, arg2, arg3)); 2369 break; 2370 case TARGET_NR_setuid32: 2371 ret = get_errno(setuid(arg1)); 2372 break; 2373 case TARGET_NR_setgid32: 2374 ret = get_errno(setgid(arg1)); 2375 break; 2376 case TARGET_NR_setfsuid32: 2377 ret = get_errno(setfsuid(arg1)); 2378 break; 2379 case TARGET_NR_setfsgid32: 2380 ret = get_errno(setfsgid(arg1)); 2381 break; 2382 case TARGET_NR_pivot_root: 2383 goto unimplemented; 2384 case TARGET_NR_mincore: 2385 goto unimplemented; 2386 case TARGET_NR_madvise: 2387 goto unimplemented; 2388 #if TARGET_LONG_BITS == 32 2389 case TARGET_NR_fcntl64: 2390 { 2391 struct flock64 fl; 2392 struct target_flock64 *target_fl = (void *)arg3; 2393 2394 switch(arg2) { 2395 case F_GETLK64: 2396 ret = get_errno(fcntl(arg1, arg2, &fl)); 2397 if (ret == 0) { 2398 target_fl->l_type = tswap16(fl.l_type); 2399 target_fl->l_whence = tswap16(fl.l_whence); 2400 target_fl->l_start = tswap64(fl.l_start); 2401 target_fl->l_len = tswap64(fl.l_len); 2402 target_fl->l_pid = tswapl(fl.l_pid); 2403 } 2404 break; 2405 2406 case F_SETLK64: 2407 case F_SETLKW64: 2408 fl.l_type = tswap16(target_fl->l_type); 2409 fl.l_whence = tswap16(target_fl->l_whence); 2410 fl.l_start = tswap64(target_fl->l_start); 2411 fl.l_len = tswap64(target_fl->l_len); 2412 fl.l_pid = tswapl(target_fl->l_pid); 2413 ret = get_errno(fcntl(arg1, arg2, &fl)); 2414 break; 2415 default: 2416 ret = get_errno(do_fcntl(arg1, arg2, arg3)); 2417 break; 2418 } 2419 break; 2420 } 2421 #endif 2422 case TARGET_NR_security: 2423 goto unimplemented; 2424 case TARGET_NR_gettid: 2425 ret = get_errno(gettid()); 2426 break; 2427 case TARGET_NR_readahead: 2428 goto unimplemented; 2429 case TARGET_NR_setxattr: 2430 case TARGET_NR_lsetxattr: 2431 case TARGET_NR_fsetxattr: 2432 case TARGET_NR_getxattr: 2433 case TARGET_NR_lgetxattr: 2434 case TARGET_NR_fgetxattr: 2435 case TARGET_NR_listxattr: 2436 case TARGET_NR_llistxattr: 2437 case TARGET_NR_flistxattr: 2438 case TARGET_NR_removexattr: 2439 case TARGET_NR_lremovexattr: 2440 case TARGET_NR_fremovexattr: 2441 goto unimplemented_nowarn; 2442 case TARGET_NR_set_thread_area: 2443 case TARGET_NR_get_thread_area: 2444 goto unimplemented_nowarn; 2445 default: 2446 unimplemented: 2447 gemu_log("qemu: Unsupported syscall: %d\n", num); 2448 unimplemented_nowarn: 2449 ret = -ENOSYS; 2450 break; 2451 } 2452 fail: 2453 return ret; 2454 } 2455 2456