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/shm.h> 45 #include <sys/statfs.h> 46 #include <utime.h> 47 #include <sys/sysinfo.h> 48 //#include <sys/user.h> 49 #include <netinet/ip.h> 50 #include <netinet/tcp.h> 51 52 #define termios host_termios 53 #define winsize host_winsize 54 #define termio host_termio 55 #define sgttyb host_sgttyb /* same as target */ 56 #define tchars host_tchars /* same as target */ 57 #define ltchars host_ltchars /* same as target */ 58 59 #include <linux/termios.h> 60 #include <linux/unistd.h> 61 #include <linux/utsname.h> 62 #include <linux/cdrom.h> 63 #include <linux/hdreg.h> 64 #include <linux/soundcard.h> 65 #include <linux/dirent.h> 66 #include <linux/kd.h> 67 68 #include "qemu.h" 69 70 //#define DEBUG 71 72 #if defined(TARGET_I386) || defined(TARGET_ARM) || defined(TARGET_SPARC) 73 /* 16 bit uid wrappers emulation */ 74 #define USE_UID16 75 #endif 76 77 //#include <linux/msdos_fs.h> 78 #define VFAT_IOCTL_READDIR_BOTH _IOR('r', 1, struct dirent [2]) 79 #define VFAT_IOCTL_READDIR_SHORT _IOR('r', 2, struct dirent [2]) 80 81 82 #undef _syscall0 83 #undef _syscall1 84 #undef _syscall2 85 #undef _syscall3 86 #undef _syscall4 87 #undef _syscall5 88 #undef _syscall6 89 90 #define _syscall0(type,name) \ 91 type name (void) \ 92 { \ 93 return syscall(__NR_##name); \ 94 } 95 96 #define _syscall1(type,name,type1,arg1) \ 97 type name (type1 arg1) \ 98 { \ 99 return syscall(__NR_##name, arg1); \ 100 } 101 102 #define _syscall2(type,name,type1,arg1,type2,arg2) \ 103 type name (type1 arg1,type2 arg2) \ 104 { \ 105 return syscall(__NR_##name, arg1, arg2); \ 106 } 107 108 #define _syscall3(type,name,type1,arg1,type2,arg2,type3,arg3) \ 109 type name (type1 arg1,type2 arg2,type3 arg3) \ 110 { \ 111 return syscall(__NR_##name, arg1, arg2, arg3); \ 112 } 113 114 #define _syscall4(type,name,type1,arg1,type2,arg2,type3,arg3,type4,arg4) \ 115 type name (type1 arg1,type2 arg2,type3 arg3,type4 arg4) \ 116 { \ 117 return syscall(__NR_##name, arg1, arg2, arg3, arg4); \ 118 } 119 120 #define _syscall5(type,name,type1,arg1,type2,arg2,type3,arg3,type4,arg4, \ 121 type5,arg5) \ 122 type name (type1 arg1,type2 arg2,type3 arg3,type4 arg4,type5 arg5) \ 123 { \ 124 return syscall(__NR_##name, arg1, arg2, arg3, arg4, arg5); \ 125 } 126 127 128 #define _syscall6(type,name,type1,arg1,type2,arg2,type3,arg3,type4,arg4, \ 129 type5,arg5,type6,arg6) \ 130 type name (type1 arg1,type2 arg2,type3 arg3,type4 arg4,type5 arg5,type6 arg6) \ 131 { \ 132 return syscall(__NR_##name, arg1, arg2, arg3, arg4, arg5, arg6); \ 133 } 134 135 136 #define __NR_sys_uname __NR_uname 137 #define __NR_sys_getcwd1 __NR_getcwd 138 #define __NR_sys_getdents __NR_getdents 139 #define __NR_sys_getdents64 __NR_getdents64 140 #define __NR_sys_rt_sigqueueinfo __NR_rt_sigqueueinfo 141 142 #if defined(__alpha__) || defined (__ia64__) || defined(__x86_64__) 143 #define __NR__llseek __NR_lseek 144 #endif 145 146 #ifdef __NR_gettid 147 _syscall0(int, gettid) 148 #else 149 static int gettid(void) { 150 return -ENOSYS; 151 } 152 #endif 153 _syscall1(int,sys_uname,struct new_utsname *,buf) 154 _syscall2(int,sys_getcwd1,char *,buf,size_t,size) 155 _syscall3(int, sys_getdents, uint, fd, struct dirent *, dirp, uint, count); 156 _syscall3(int, sys_getdents64, uint, fd, struct dirent64 *, dirp, uint, count); 157 _syscall5(int, _llseek, uint, fd, ulong, hi, ulong, lo, 158 loff_t *, res, uint, wh); 159 _syscall3(int,sys_rt_sigqueueinfo,int,pid,int,sig,siginfo_t *,uinfo) 160 #ifdef __NR_exit_group 161 _syscall1(int,exit_group,int,error_code) 162 #endif 163 164 extern int personality(int); 165 extern int flock(int, int); 166 extern int setfsuid(int); 167 extern int setfsgid(int); 168 extern int setresuid(uid_t, uid_t, uid_t); 169 extern int getresuid(uid_t *, uid_t *, uid_t *); 170 extern int setresgid(gid_t, gid_t, gid_t); 171 extern int getresgid(gid_t *, gid_t *, gid_t *); 172 extern int setgroups(int, gid_t *); 173 174 static inline long get_errno(long ret) 175 { 176 if (ret == -1) 177 return -errno; 178 else 179 return ret; 180 } 181 182 static inline int is_error(long ret) 183 { 184 return (unsigned long)ret >= (unsigned long)(-4096); 185 } 186 187 static target_ulong target_brk; 188 static target_ulong target_original_brk; 189 190 void target_set_brk(target_ulong new_brk) 191 { 192 target_original_brk = target_brk = new_brk; 193 } 194 195 long do_brk(target_ulong new_brk) 196 { 197 target_ulong brk_page; 198 long mapped_addr; 199 int new_alloc_size; 200 201 if (!new_brk) 202 return target_brk; 203 if (new_brk < target_original_brk) 204 return -ENOMEM; 205 206 brk_page = HOST_PAGE_ALIGN(target_brk); 207 208 /* If the new brk is less than this, set it and we're done... */ 209 if (new_brk < brk_page) { 210 target_brk = new_brk; 211 return target_brk; 212 } 213 214 /* We need to allocate more memory after the brk... */ 215 new_alloc_size = HOST_PAGE_ALIGN(new_brk - brk_page + 1); 216 mapped_addr = get_errno(target_mmap(brk_page, new_alloc_size, 217 PROT_READ|PROT_WRITE, 218 MAP_ANON|MAP_FIXED|MAP_PRIVATE, 0, 0)); 219 if (is_error(mapped_addr)) { 220 return mapped_addr; 221 } else { 222 target_brk = new_brk; 223 return target_brk; 224 } 225 } 226 227 static inline fd_set *target_to_host_fds(fd_set *fds, 228 target_long *target_fds, int n) 229 { 230 #if !defined(BSWAP_NEEDED) && !defined(WORDS_BIGENDIAN) 231 return (fd_set *)target_fds; 232 #else 233 int i, b; 234 if (target_fds) { 235 FD_ZERO(fds); 236 for(i = 0;i < n; i++) { 237 b = (tswapl(target_fds[i / TARGET_LONG_BITS]) >> 238 (i & (TARGET_LONG_BITS - 1))) & 1; 239 if (b) 240 FD_SET(i, fds); 241 } 242 return fds; 243 } else { 244 return NULL; 245 } 246 #endif 247 } 248 249 static inline void host_to_target_fds(target_long *target_fds, 250 fd_set *fds, int n) 251 { 252 #if !defined(BSWAP_NEEDED) && !defined(WORDS_BIGENDIAN) 253 /* nothing to do */ 254 #else 255 int i, nw, j, k; 256 target_long v; 257 258 if (target_fds) { 259 nw = (n + TARGET_LONG_BITS - 1) / TARGET_LONG_BITS; 260 k = 0; 261 for(i = 0;i < nw; i++) { 262 v = 0; 263 for(j = 0; j < TARGET_LONG_BITS; j++) { 264 v |= ((FD_ISSET(k, fds) != 0) << j); 265 k++; 266 } 267 target_fds[i] = tswapl(v); 268 } 269 } 270 #endif 271 } 272 273 #if defined(__alpha__) 274 #define HOST_HZ 1024 275 #else 276 #define HOST_HZ 100 277 #endif 278 279 static inline long host_to_target_clock_t(long ticks) 280 { 281 #if HOST_HZ == TARGET_HZ 282 return ticks; 283 #else 284 return ((int64_t)ticks * TARGET_HZ) / HOST_HZ; 285 #endif 286 } 287 288 static inline void host_to_target_rusage(target_ulong target_addr, 289 const struct rusage *rusage) 290 { 291 struct target_rusage *target_rusage; 292 293 lock_user_struct(target_rusage, target_addr, 0); 294 target_rusage->ru_utime.tv_sec = tswapl(rusage->ru_utime.tv_sec); 295 target_rusage->ru_utime.tv_usec = tswapl(rusage->ru_utime.tv_usec); 296 target_rusage->ru_stime.tv_sec = tswapl(rusage->ru_stime.tv_sec); 297 target_rusage->ru_stime.tv_usec = tswapl(rusage->ru_stime.tv_usec); 298 target_rusage->ru_maxrss = tswapl(rusage->ru_maxrss); 299 target_rusage->ru_ixrss = tswapl(rusage->ru_ixrss); 300 target_rusage->ru_idrss = tswapl(rusage->ru_idrss); 301 target_rusage->ru_isrss = tswapl(rusage->ru_isrss); 302 target_rusage->ru_minflt = tswapl(rusage->ru_minflt); 303 target_rusage->ru_majflt = tswapl(rusage->ru_majflt); 304 target_rusage->ru_nswap = tswapl(rusage->ru_nswap); 305 target_rusage->ru_inblock = tswapl(rusage->ru_inblock); 306 target_rusage->ru_oublock = tswapl(rusage->ru_oublock); 307 target_rusage->ru_msgsnd = tswapl(rusage->ru_msgsnd); 308 target_rusage->ru_msgrcv = tswapl(rusage->ru_msgrcv); 309 target_rusage->ru_nsignals = tswapl(rusage->ru_nsignals); 310 target_rusage->ru_nvcsw = tswapl(rusage->ru_nvcsw); 311 target_rusage->ru_nivcsw = tswapl(rusage->ru_nivcsw); 312 unlock_user_struct(target_rusage, target_addr, 1); 313 } 314 315 static inline void target_to_host_timeval(struct timeval *tv, 316 target_ulong target_addr) 317 { 318 struct target_timeval *target_tv; 319 320 lock_user_struct(target_tv, target_addr, 1); 321 tv->tv_sec = tswapl(target_tv->tv_sec); 322 tv->tv_usec = tswapl(target_tv->tv_usec); 323 unlock_user_struct(target_tv, target_addr, 0); 324 } 325 326 static inline void host_to_target_timeval(target_ulong target_addr, 327 const struct timeval *tv) 328 { 329 struct target_timeval *target_tv; 330 331 lock_user_struct(target_tv, target_addr, 0); 332 target_tv->tv_sec = tswapl(tv->tv_sec); 333 target_tv->tv_usec = tswapl(tv->tv_usec); 334 unlock_user_struct(target_tv, target_addr, 1); 335 } 336 337 338 static long do_select(long n, 339 target_ulong rfd_p, target_ulong wfd_p, 340 target_ulong efd_p, target_ulong target_tv) 341 { 342 fd_set rfds, wfds, efds; 343 fd_set *rfds_ptr, *wfds_ptr, *efds_ptr; 344 target_long *target_rfds, *target_wfds, *target_efds; 345 struct timeval tv, *tv_ptr; 346 long ret; 347 int ok; 348 349 if (rfd_p) { 350 target_rfds = lock_user(rfd_p, sizeof(target_long) * n, 1); 351 rfds_ptr = target_to_host_fds(&rfds, target_rfds, n); 352 } else { 353 target_rfds = NULL; 354 rfds_ptr = NULL; 355 } 356 if (wfd_p) { 357 target_wfds = lock_user(wfd_p, sizeof(target_long) * n, 1); 358 wfds_ptr = target_to_host_fds(&wfds, target_wfds, n); 359 } else { 360 target_wfds = NULL; 361 wfds_ptr = NULL; 362 } 363 if (efd_p) { 364 target_efds = lock_user(efd_p, sizeof(target_long) * n, 1); 365 efds_ptr = target_to_host_fds(&efds, target_efds, n); 366 } else { 367 target_efds = NULL; 368 efds_ptr = NULL; 369 } 370 371 if (target_tv) { 372 target_to_host_timeval(&tv, target_tv); 373 tv_ptr = &tv; 374 } else { 375 tv_ptr = NULL; 376 } 377 ret = get_errno(select(n, rfds_ptr, wfds_ptr, efds_ptr, tv_ptr)); 378 ok = !is_error(ret); 379 380 if (ok) { 381 host_to_target_fds(target_rfds, rfds_ptr, n); 382 host_to_target_fds(target_wfds, wfds_ptr, n); 383 host_to_target_fds(target_efds, efds_ptr, n); 384 385 if (target_tv) { 386 host_to_target_timeval(target_tv, &tv); 387 } 388 } 389 if (target_rfds) 390 unlock_user(target_rfds, rfd_p, ok ? sizeof(target_long) * n : 0); 391 if (target_wfds) 392 unlock_user(target_wfds, wfd_p, ok ? sizeof(target_long) * n : 0); 393 if (target_efds) 394 unlock_user(target_efds, efd_p, ok ? sizeof(target_long) * n : 0); 395 396 return ret; 397 } 398 399 static inline void target_to_host_sockaddr(struct sockaddr *addr, 400 target_ulong target_addr, 401 socklen_t len) 402 { 403 struct target_sockaddr *target_saddr; 404 405 target_saddr = lock_user(target_addr, len, 1); 406 memcpy(addr, target_saddr, len); 407 addr->sa_family = tswap16(target_saddr->sa_family); 408 unlock_user(target_saddr, target_addr, 0); 409 } 410 411 static inline void host_to_target_sockaddr(target_ulong target_addr, 412 struct sockaddr *addr, 413 socklen_t len) 414 { 415 struct target_sockaddr *target_saddr; 416 417 target_saddr = lock_user(target_addr, len, 0); 418 memcpy(target_saddr, addr, len); 419 target_saddr->sa_family = tswap16(addr->sa_family); 420 unlock_user(target_saddr, target_addr, len); 421 } 422 423 /* ??? Should this also swap msgh->name? */ 424 static inline void target_to_host_cmsg(struct msghdr *msgh, 425 struct target_msghdr *target_msgh) 426 { 427 struct cmsghdr *cmsg = CMSG_FIRSTHDR(msgh); 428 struct target_cmsghdr *target_cmsg = TARGET_CMSG_FIRSTHDR(target_msgh); 429 socklen_t space = 0; 430 431 while (cmsg && target_cmsg) { 432 void *data = CMSG_DATA(cmsg); 433 void *target_data = TARGET_CMSG_DATA(target_cmsg); 434 435 int len = tswapl(target_cmsg->cmsg_len) 436 - TARGET_CMSG_ALIGN(sizeof (struct target_cmsghdr)); 437 438 space += CMSG_SPACE(len); 439 if (space > msgh->msg_controllen) { 440 space -= CMSG_SPACE(len); 441 gemu_log("Host cmsg overflow\n"); 442 break; 443 } 444 445 cmsg->cmsg_level = tswap32(target_cmsg->cmsg_level); 446 cmsg->cmsg_type = tswap32(target_cmsg->cmsg_type); 447 cmsg->cmsg_len = CMSG_LEN(len); 448 449 if (cmsg->cmsg_level != TARGET_SOL_SOCKET || cmsg->cmsg_type != SCM_RIGHTS) { 450 gemu_log("Unsupported ancillary data: %d/%d\n", cmsg->cmsg_level, cmsg->cmsg_type); 451 memcpy(data, target_data, len); 452 } else { 453 int *fd = (int *)data; 454 int *target_fd = (int *)target_data; 455 int i, numfds = len / sizeof(int); 456 457 for (i = 0; i < numfds; i++) 458 fd[i] = tswap32(target_fd[i]); 459 } 460 461 cmsg = CMSG_NXTHDR(msgh, cmsg); 462 target_cmsg = TARGET_CMSG_NXTHDR(target_msgh, target_cmsg); 463 } 464 465 msgh->msg_controllen = space; 466 } 467 468 /* ??? Should this also swap msgh->name? */ 469 static inline void host_to_target_cmsg(struct target_msghdr *target_msgh, 470 struct msghdr *msgh) 471 { 472 struct cmsghdr *cmsg = CMSG_FIRSTHDR(msgh); 473 struct target_cmsghdr *target_cmsg = TARGET_CMSG_FIRSTHDR(target_msgh); 474 socklen_t space = 0; 475 476 while (cmsg && target_cmsg) { 477 void *data = CMSG_DATA(cmsg); 478 void *target_data = TARGET_CMSG_DATA(target_cmsg); 479 480 int len = cmsg->cmsg_len - CMSG_ALIGN(sizeof (struct cmsghdr)); 481 482 space += TARGET_CMSG_SPACE(len); 483 if (space > tswapl(target_msgh->msg_controllen)) { 484 space -= TARGET_CMSG_SPACE(len); 485 gemu_log("Target cmsg overflow\n"); 486 break; 487 } 488 489 target_cmsg->cmsg_level = tswap32(cmsg->cmsg_level); 490 target_cmsg->cmsg_type = tswap32(cmsg->cmsg_type); 491 target_cmsg->cmsg_len = tswapl(TARGET_CMSG_LEN(len)); 492 493 if (cmsg->cmsg_level != TARGET_SOL_SOCKET || cmsg->cmsg_type != SCM_RIGHTS) { 494 gemu_log("Unsupported ancillary data: %d/%d\n", cmsg->cmsg_level, cmsg->cmsg_type); 495 memcpy(target_data, data, len); 496 } else { 497 int *fd = (int *)data; 498 int *target_fd = (int *)target_data; 499 int i, numfds = len / sizeof(int); 500 501 for (i = 0; i < numfds; i++) 502 target_fd[i] = tswap32(fd[i]); 503 } 504 505 cmsg = CMSG_NXTHDR(msgh, cmsg); 506 target_cmsg = TARGET_CMSG_NXTHDR(target_msgh, target_cmsg); 507 } 508 509 msgh->msg_controllen = tswapl(space); 510 } 511 512 static long do_setsockopt(int sockfd, int level, int optname, 513 target_ulong optval, socklen_t optlen) 514 { 515 int val, ret; 516 517 switch(level) { 518 case SOL_TCP: 519 /* TCP options all take an 'int' value. */ 520 if (optlen < sizeof(uint32_t)) 521 return -EINVAL; 522 523 val = tget32(optval); 524 ret = get_errno(setsockopt(sockfd, level, optname, &val, sizeof(val))); 525 break; 526 case SOL_IP: 527 switch(optname) { 528 case IP_TOS: 529 case IP_TTL: 530 case IP_HDRINCL: 531 case IP_ROUTER_ALERT: 532 case IP_RECVOPTS: 533 case IP_RETOPTS: 534 case IP_PKTINFO: 535 case IP_MTU_DISCOVER: 536 case IP_RECVERR: 537 case IP_RECVTOS: 538 #ifdef IP_FREEBIND 539 case IP_FREEBIND: 540 #endif 541 case IP_MULTICAST_TTL: 542 case IP_MULTICAST_LOOP: 543 val = 0; 544 if (optlen >= sizeof(uint32_t)) { 545 val = tget32(optval); 546 } else if (optlen >= 1) { 547 val = tget8(optval); 548 } 549 ret = get_errno(setsockopt(sockfd, level, optname, &val, sizeof(val))); 550 break; 551 default: 552 goto unimplemented; 553 } 554 break; 555 case TARGET_SOL_SOCKET: 556 switch (optname) { 557 /* Options with 'int' argument. */ 558 case TARGET_SO_DEBUG: 559 optname = SO_DEBUG; 560 break; 561 case TARGET_SO_REUSEADDR: 562 optname = SO_REUSEADDR; 563 break; 564 case TARGET_SO_TYPE: 565 optname = SO_TYPE; 566 break; 567 case TARGET_SO_ERROR: 568 optname = SO_ERROR; 569 break; 570 case TARGET_SO_DONTROUTE: 571 optname = SO_DONTROUTE; 572 break; 573 case TARGET_SO_BROADCAST: 574 optname = SO_BROADCAST; 575 break; 576 case TARGET_SO_SNDBUF: 577 optname = SO_SNDBUF; 578 break; 579 case TARGET_SO_RCVBUF: 580 optname = SO_RCVBUF; 581 break; 582 case TARGET_SO_KEEPALIVE: 583 optname = SO_KEEPALIVE; 584 break; 585 case TARGET_SO_OOBINLINE: 586 optname = SO_OOBINLINE; 587 break; 588 case TARGET_SO_NO_CHECK: 589 optname = SO_NO_CHECK; 590 break; 591 case TARGET_SO_PRIORITY: 592 optname = SO_PRIORITY; 593 break; 594 #ifdef SO_BSDCOMPAT 595 case TARGET_SO_BSDCOMPAT: 596 optname = SO_BSDCOMPAT; 597 break; 598 #endif 599 case TARGET_SO_PASSCRED: 600 optname = SO_PASSCRED; 601 break; 602 case TARGET_SO_TIMESTAMP: 603 optname = SO_TIMESTAMP; 604 break; 605 case TARGET_SO_RCVLOWAT: 606 optname = SO_RCVLOWAT; 607 break; 608 case TARGET_SO_RCVTIMEO: 609 optname = SO_RCVTIMEO; 610 break; 611 case TARGET_SO_SNDTIMEO: 612 optname = SO_SNDTIMEO; 613 break; 614 break; 615 default: 616 goto unimplemented; 617 } 618 if (optlen < sizeof(uint32_t)) 619 return -EINVAL; 620 621 val = tget32(optval); 622 ret = get_errno(setsockopt(sockfd, SOL_SOCKET, optname, &val, sizeof(val))); 623 break; 624 default: 625 unimplemented: 626 gemu_log("Unsupported setsockopt level=%d optname=%d \n", level, optname); 627 ret = -ENOSYS; 628 } 629 return ret; 630 } 631 632 static long do_getsockopt(int sockfd, int level, int optname, 633 target_ulong optval, target_ulong optlen) 634 { 635 int len, lv, val, ret; 636 637 switch(level) { 638 case TARGET_SOL_SOCKET: 639 level = SOL_SOCKET; 640 switch (optname) { 641 case TARGET_SO_LINGER: 642 case TARGET_SO_RCVTIMEO: 643 case TARGET_SO_SNDTIMEO: 644 case TARGET_SO_PEERCRED: 645 case TARGET_SO_PEERNAME: 646 /* These don't just return a single integer */ 647 goto unimplemented; 648 default: 649 goto int_case; 650 } 651 break; 652 case SOL_TCP: 653 /* TCP options all take an 'int' value. */ 654 int_case: 655 len = tget32(optlen); 656 if (len < 0) 657 return -EINVAL; 658 lv = sizeof(int); 659 ret = get_errno(getsockopt(sockfd, level, optname, &val, &lv)); 660 if (ret < 0) 661 return ret; 662 val = tswap32(val); 663 if (len > lv) 664 len = lv; 665 if (len == 4) 666 tput32(optval, val); 667 else 668 tput8(optval, val); 669 tput32(optlen, len); 670 break; 671 case SOL_IP: 672 switch(optname) { 673 case IP_TOS: 674 case IP_TTL: 675 case IP_HDRINCL: 676 case IP_ROUTER_ALERT: 677 case IP_RECVOPTS: 678 case IP_RETOPTS: 679 case IP_PKTINFO: 680 case IP_MTU_DISCOVER: 681 case IP_RECVERR: 682 case IP_RECVTOS: 683 #ifdef IP_FREEBIND 684 case IP_FREEBIND: 685 #endif 686 case IP_MULTICAST_TTL: 687 case IP_MULTICAST_LOOP: 688 len = tget32(optlen); 689 if (len < 0) 690 return -EINVAL; 691 lv = sizeof(int); 692 ret = get_errno(getsockopt(sockfd, level, optname, &val, &lv)); 693 if (ret < 0) 694 return ret; 695 if (len < sizeof(int) && len > 0 && val >= 0 && val < 255) { 696 len = 1; 697 tput32(optlen, len); 698 tput8(optval, val); 699 } else { 700 if (len > sizeof(int)) 701 len = sizeof(int); 702 tput32(optlen, len); 703 tput32(optval, val); 704 } 705 break; 706 default: 707 goto unimplemented; 708 } 709 break; 710 default: 711 unimplemented: 712 gemu_log("getsockopt level=%d optname=%d not yet supported\n", 713 level, optname); 714 ret = -ENOSYS; 715 break; 716 } 717 return ret; 718 } 719 720 static void lock_iovec(struct iovec *vec, target_ulong target_addr, 721 int count, int copy) 722 { 723 struct target_iovec *target_vec; 724 target_ulong base; 725 int i; 726 727 target_vec = lock_user(target_addr, count * sizeof(struct target_iovec), 1); 728 for(i = 0;i < count; i++) { 729 base = tswapl(target_vec[i].iov_base); 730 vec[i].iov_len = tswapl(target_vec[i].iov_len); 731 vec[i].iov_base = lock_user(base, vec[i].iov_len, copy); 732 } 733 unlock_user (target_vec, target_addr, 0); 734 } 735 736 static void unlock_iovec(struct iovec *vec, target_ulong target_addr, 737 int count, int copy) 738 { 739 struct target_iovec *target_vec; 740 target_ulong base; 741 int i; 742 743 target_vec = lock_user(target_addr, count * sizeof(struct target_iovec), 1); 744 for(i = 0;i < count; i++) { 745 base = tswapl(target_vec[i].iov_base); 746 unlock_user(vec[i].iov_base, base, copy ? vec[i].iov_len : 0); 747 } 748 unlock_user (target_vec, target_addr, 0); 749 } 750 751 static long do_socket(int domain, int type, int protocol) 752 { 753 #if defined(TARGET_MIPS) 754 switch(type) { 755 case TARGET_SOCK_DGRAM: 756 type = SOCK_DGRAM; 757 break; 758 case TARGET_SOCK_STREAM: 759 type = SOCK_STREAM; 760 break; 761 case TARGET_SOCK_RAW: 762 type = SOCK_RAW; 763 break; 764 case TARGET_SOCK_RDM: 765 type = SOCK_RDM; 766 break; 767 case TARGET_SOCK_SEQPACKET: 768 type = SOCK_SEQPACKET; 769 break; 770 case TARGET_SOCK_PACKET: 771 type = SOCK_PACKET; 772 break; 773 } 774 #endif 775 return get_errno(socket(domain, type, protocol)); 776 } 777 778 static long do_bind(int sockfd, target_ulong target_addr, 779 socklen_t addrlen) 780 { 781 void *addr = alloca(addrlen); 782 783 target_to_host_sockaddr(addr, target_addr, addrlen); 784 return get_errno(bind(sockfd, addr, addrlen)); 785 } 786 787 static long do_connect(int sockfd, target_ulong target_addr, 788 socklen_t addrlen) 789 { 790 void *addr = alloca(addrlen); 791 792 target_to_host_sockaddr(addr, target_addr, addrlen); 793 return get_errno(connect(sockfd, addr, addrlen)); 794 } 795 796 static long do_sendrecvmsg(int fd, target_ulong target_msg, 797 int flags, int send) 798 { 799 long ret; 800 struct target_msghdr *msgp; 801 struct msghdr msg; 802 int count; 803 struct iovec *vec; 804 target_ulong target_vec; 805 806 lock_user_struct(msgp, target_msg, 1); 807 if (msgp->msg_name) { 808 msg.msg_namelen = tswap32(msgp->msg_namelen); 809 msg.msg_name = alloca(msg.msg_namelen); 810 target_to_host_sockaddr(msg.msg_name, tswapl(msgp->msg_name), 811 msg.msg_namelen); 812 } else { 813 msg.msg_name = NULL; 814 msg.msg_namelen = 0; 815 } 816 msg.msg_controllen = 2 * tswapl(msgp->msg_controllen); 817 msg.msg_control = alloca(msg.msg_controllen); 818 msg.msg_flags = tswap32(msgp->msg_flags); 819 820 count = tswapl(msgp->msg_iovlen); 821 vec = alloca(count * sizeof(struct iovec)); 822 target_vec = tswapl(msgp->msg_iov); 823 lock_iovec(vec, target_vec, count, send); 824 msg.msg_iovlen = count; 825 msg.msg_iov = vec; 826 827 if (send) { 828 target_to_host_cmsg(&msg, msgp); 829 ret = get_errno(sendmsg(fd, &msg, flags)); 830 } else { 831 ret = get_errno(recvmsg(fd, &msg, flags)); 832 if (!is_error(ret)) 833 host_to_target_cmsg(msgp, &msg); 834 } 835 unlock_iovec(vec, target_vec, count, !send); 836 return ret; 837 } 838 839 static long do_socketcall(int num, target_ulong vptr) 840 { 841 long ret; 842 const int n = sizeof(target_ulong); 843 844 switch(num) { 845 case SOCKOP_socket: 846 { 847 int domain = tgetl(vptr); 848 int type = tgetl(vptr + n); 849 int protocol = tgetl(vptr + 2 * n); 850 ret = do_socket(domain, type, protocol); 851 } 852 break; 853 case SOCKOP_bind: 854 { 855 int sockfd = tgetl(vptr); 856 target_ulong target_addr = tgetl(vptr + n); 857 socklen_t addrlen = tgetl(vptr + 2 * n); 858 ret = do_bind(sockfd, target_addr, addrlen); 859 } 860 break; 861 case SOCKOP_connect: 862 { 863 int sockfd = tgetl(vptr); 864 target_ulong target_addr = tgetl(vptr + n); 865 socklen_t addrlen = tgetl(vptr + 2 * n); 866 ret = do_connect(sockfd, target_addr, addrlen); 867 } 868 break; 869 case SOCKOP_listen: 870 { 871 int sockfd = tgetl(vptr); 872 int backlog = tgetl(vptr + n); 873 ret = get_errno(listen(sockfd, backlog)); 874 } 875 break; 876 case SOCKOP_accept: 877 { 878 int sockfd = tgetl(vptr); 879 target_ulong target_addr = tgetl(vptr + n); 880 target_ulong target_addrlen = tgetl(vptr + 2 * n); 881 socklen_t addrlen = tget32(target_addrlen); 882 void *addr = alloca(addrlen); 883 884 ret = get_errno(accept(sockfd, addr, &addrlen)); 885 if (!is_error(ret)) { 886 host_to_target_sockaddr(target_addr, addr, addrlen); 887 tput32(target_addrlen, addrlen); 888 } 889 } 890 break; 891 case SOCKOP_getsockname: 892 { 893 int sockfd = tgetl(vptr); 894 target_ulong target_addr = tgetl(vptr + n); 895 target_ulong target_addrlen = tgetl(vptr + 2 * n); 896 socklen_t addrlen = tget32(target_addrlen); 897 void *addr = alloca(addrlen); 898 899 ret = get_errno(getsockname(sockfd, addr, &addrlen)); 900 if (!is_error(ret)) { 901 host_to_target_sockaddr(target_addr, addr, addrlen); 902 tput32(target_addrlen, addrlen); 903 } 904 } 905 break; 906 case SOCKOP_getpeername: 907 { 908 int sockfd = tgetl(vptr); 909 target_ulong target_addr = tgetl(vptr + n); 910 target_ulong target_addrlen = tgetl(vptr + 2 * n); 911 socklen_t addrlen = tget32(target_addrlen); 912 void *addr = alloca(addrlen); 913 914 ret = get_errno(getpeername(sockfd, addr, &addrlen)); 915 if (!is_error(ret)) { 916 host_to_target_sockaddr(target_addr, addr, addrlen); 917 tput32(target_addrlen, addrlen); 918 } 919 } 920 break; 921 case SOCKOP_socketpair: 922 { 923 int domain = tgetl(vptr); 924 int type = tgetl(vptr + n); 925 int protocol = tgetl(vptr + 2 * n); 926 target_ulong target_tab = tgetl(vptr + 3 * n); 927 int tab[2]; 928 929 ret = get_errno(socketpair(domain, type, protocol, tab)); 930 if (!is_error(ret)) { 931 tput32(target_tab, tab[0]); 932 tput32(target_tab + 4, tab[1]); 933 } 934 } 935 break; 936 case SOCKOP_send: 937 { 938 int sockfd = tgetl(vptr); 939 target_ulong msg = tgetl(vptr + n); 940 size_t len = tgetl(vptr + 2 * n); 941 int flags = tgetl(vptr + 3 * n); 942 void *host_msg; 943 944 host_msg = lock_user(msg, len, 1); 945 ret = get_errno(send(sockfd, host_msg, len, flags)); 946 unlock_user(host_msg, msg, 0); 947 } 948 break; 949 case SOCKOP_recv: 950 { 951 int sockfd = tgetl(vptr); 952 target_ulong msg = tgetl(vptr + n); 953 size_t len = tgetl(vptr + 2 * n); 954 int flags = tgetl(vptr + 3 * n); 955 void *host_msg; 956 957 host_msg = lock_user(msg, len, 0); 958 ret = get_errno(recv(sockfd, host_msg, len, flags)); 959 unlock_user(host_msg, msg, ret); 960 } 961 break; 962 case SOCKOP_sendto: 963 { 964 int sockfd = tgetl(vptr); 965 target_ulong msg = tgetl(vptr + n); 966 size_t len = tgetl(vptr + 2 * n); 967 int flags = tgetl(vptr + 3 * n); 968 target_ulong target_addr = tgetl(vptr + 4 * n); 969 socklen_t addrlen = tgetl(vptr + 5 * n); 970 void *addr = alloca(addrlen); 971 void *host_msg; 972 973 host_msg = lock_user(msg, len, 1); 974 target_to_host_sockaddr(addr, target_addr, addrlen); 975 ret = get_errno(sendto(sockfd, host_msg, len, flags, addr, addrlen)); 976 unlock_user(host_msg, msg, 0); 977 } 978 break; 979 case SOCKOP_recvfrom: 980 { 981 int sockfd = tgetl(vptr); 982 target_ulong msg = tgetl(vptr + n); 983 size_t len = tgetl(vptr + 2 * n); 984 int flags = tgetl(vptr + 3 * n); 985 target_ulong target_addr = tgetl(vptr + 4 * n); 986 target_ulong target_addrlen = tgetl(vptr + 5 * n); 987 socklen_t addrlen = tget32(target_addrlen); 988 void *addr = alloca(addrlen); 989 void *host_msg; 990 991 host_msg = lock_user(msg, len, 0); 992 ret = get_errno(recvfrom(sockfd, host_msg, len, flags, addr, &addrlen)); 993 if (!is_error(ret)) { 994 host_to_target_sockaddr(target_addr, addr, addrlen); 995 tput32(target_addrlen, addrlen); 996 unlock_user(host_msg, msg, len); 997 } else { 998 unlock_user(host_msg, msg, 0); 999 } 1000 } 1001 break; 1002 case SOCKOP_shutdown: 1003 { 1004 int sockfd = tgetl(vptr); 1005 int how = tgetl(vptr + n); 1006 1007 ret = get_errno(shutdown(sockfd, how)); 1008 } 1009 break; 1010 case SOCKOP_sendmsg: 1011 case SOCKOP_recvmsg: 1012 { 1013 int fd; 1014 target_ulong target_msg; 1015 int flags; 1016 1017 fd = tgetl(vptr); 1018 target_msg = tgetl(vptr + n); 1019 flags = tgetl(vptr + 2 * n); 1020 1021 ret = do_sendrecvmsg(fd, target_msg, flags, 1022 (num == SOCKOP_sendmsg)); 1023 } 1024 break; 1025 case SOCKOP_setsockopt: 1026 { 1027 int sockfd = tgetl(vptr); 1028 int level = tgetl(vptr + n); 1029 int optname = tgetl(vptr + 2 * n); 1030 target_ulong optval = tgetl(vptr + 3 * n); 1031 socklen_t optlen = tgetl(vptr + 4 * n); 1032 1033 ret = do_setsockopt(sockfd, level, optname, optval, optlen); 1034 } 1035 break; 1036 case SOCKOP_getsockopt: 1037 { 1038 int sockfd = tgetl(vptr); 1039 int level = tgetl(vptr + n); 1040 int optname = tgetl(vptr + 2 * n); 1041 target_ulong optval = tgetl(vptr + 3 * n); 1042 target_ulong poptlen = tgetl(vptr + 4 * n); 1043 1044 ret = do_getsockopt(sockfd, level, optname, optval, poptlen); 1045 } 1046 break; 1047 default: 1048 gemu_log("Unsupported socketcall: %d\n", num); 1049 ret = -ENOSYS; 1050 break; 1051 } 1052 return ret; 1053 } 1054 1055 /* XXX: suppress this function and call directly the related socket 1056 functions */ 1057 static long do_socketcallwrapper(int num, long arg1, long arg2, long arg3, 1058 long arg4, long arg5, long arg6) 1059 { 1060 target_long args[6]; 1061 1062 tputl(args, arg1); 1063 tputl(args+1, arg2); 1064 tputl(args+2, arg3); 1065 tputl(args+3, arg4); 1066 tputl(args+4, arg5); 1067 tputl(args+5, arg6); 1068 1069 return do_socketcall(num, (target_ulong) args); 1070 } 1071 1072 #define N_SHM_REGIONS 32 1073 1074 static struct shm_region { 1075 uint32_t start; 1076 uint32_t size; 1077 } shm_regions[N_SHM_REGIONS]; 1078 1079 /* ??? This only works with linear mappings. */ 1080 static long do_ipc(long call, long first, long second, long third, 1081 long ptr, long fifth) 1082 { 1083 int version; 1084 long ret = 0; 1085 unsigned long raddr; 1086 struct shmid_ds shm_info; 1087 int i; 1088 1089 version = call >> 16; 1090 call &= 0xffff; 1091 1092 switch (call) { 1093 case IPCOP_shmat: 1094 /* SHM_* flags are the same on all linux platforms */ 1095 ret = get_errno((long) shmat(first, (void *) ptr, second)); 1096 if (is_error(ret)) 1097 break; 1098 raddr = ret; 1099 /* find out the length of the shared memory segment */ 1100 1101 ret = get_errno(shmctl(first, IPC_STAT, &shm_info)); 1102 if (is_error(ret)) { 1103 /* can't get length, bail out */ 1104 shmdt((void *) raddr); 1105 break; 1106 } 1107 page_set_flags(raddr, raddr + shm_info.shm_segsz, 1108 PAGE_VALID | PAGE_READ | 1109 ((second & SHM_RDONLY)? 0: PAGE_WRITE)); 1110 for (i = 0; i < N_SHM_REGIONS; ++i) { 1111 if (shm_regions[i].start == 0) { 1112 shm_regions[i].start = raddr; 1113 shm_regions[i].size = shm_info.shm_segsz; 1114 break; 1115 } 1116 } 1117 if (put_user(raddr, (uint32_t *)third)) 1118 return -EFAULT; 1119 ret = 0; 1120 break; 1121 case IPCOP_shmdt: 1122 for (i = 0; i < N_SHM_REGIONS; ++i) { 1123 if (shm_regions[i].start == ptr) { 1124 shm_regions[i].start = 0; 1125 page_set_flags(ptr, shm_regions[i].size, 0); 1126 break; 1127 } 1128 } 1129 ret = get_errno(shmdt((void *) ptr)); 1130 break; 1131 1132 case IPCOP_shmget: 1133 /* IPC_* flag values are the same on all linux platforms */ 1134 ret = get_errno(shmget(first, second, third)); 1135 break; 1136 1137 /* IPC_* and SHM_* command values are the same on all linux platforms */ 1138 case IPCOP_shmctl: 1139 switch(second) { 1140 case IPC_RMID: 1141 case SHM_LOCK: 1142 case SHM_UNLOCK: 1143 ret = get_errno(shmctl(first, second, NULL)); 1144 break; 1145 default: 1146 goto unimplemented; 1147 } 1148 break; 1149 default: 1150 unimplemented: 1151 gemu_log("Unsupported ipc call: %ld (version %d)\n", call, version); 1152 ret = -ENOSYS; 1153 break; 1154 } 1155 return ret; 1156 } 1157 1158 /* kernel structure types definitions */ 1159 #define IFNAMSIZ 16 1160 1161 #define STRUCT(name, list...) STRUCT_ ## name, 1162 #define STRUCT_SPECIAL(name) STRUCT_ ## name, 1163 enum { 1164 #include "syscall_types.h" 1165 }; 1166 #undef STRUCT 1167 #undef STRUCT_SPECIAL 1168 1169 #define STRUCT(name, list...) const argtype struct_ ## name ## _def[] = { list, TYPE_NULL }; 1170 #define STRUCT_SPECIAL(name) 1171 #include "syscall_types.h" 1172 #undef STRUCT 1173 #undef STRUCT_SPECIAL 1174 1175 typedef struct IOCTLEntry { 1176 unsigned int target_cmd; 1177 unsigned int host_cmd; 1178 const char *name; 1179 int access; 1180 const argtype arg_type[5]; 1181 } IOCTLEntry; 1182 1183 #define IOC_R 0x0001 1184 #define IOC_W 0x0002 1185 #define IOC_RW (IOC_R | IOC_W) 1186 1187 #define MAX_STRUCT_SIZE 4096 1188 1189 IOCTLEntry ioctl_entries[] = { 1190 #define IOCTL(cmd, access, types...) \ 1191 { TARGET_ ## cmd, cmd, #cmd, access, { types } }, 1192 #include "ioctls.h" 1193 { 0, 0, }, 1194 }; 1195 1196 /* ??? Implement proper locking for ioctls. */ 1197 static long do_ioctl(long fd, long cmd, long arg) 1198 { 1199 const IOCTLEntry *ie; 1200 const argtype *arg_type; 1201 long ret; 1202 uint8_t buf_temp[MAX_STRUCT_SIZE]; 1203 int target_size; 1204 void *argptr; 1205 1206 ie = ioctl_entries; 1207 for(;;) { 1208 if (ie->target_cmd == 0) { 1209 gemu_log("Unsupported ioctl: cmd=0x%04lx\n", cmd); 1210 return -ENOSYS; 1211 } 1212 if (ie->target_cmd == cmd) 1213 break; 1214 ie++; 1215 } 1216 arg_type = ie->arg_type; 1217 #if defined(DEBUG) 1218 gemu_log("ioctl: cmd=0x%04lx (%s)\n", cmd, ie->name); 1219 #endif 1220 switch(arg_type[0]) { 1221 case TYPE_NULL: 1222 /* no argument */ 1223 ret = get_errno(ioctl(fd, ie->host_cmd)); 1224 break; 1225 case TYPE_PTRVOID: 1226 case TYPE_INT: 1227 /* int argment */ 1228 ret = get_errno(ioctl(fd, ie->host_cmd, arg)); 1229 break; 1230 case TYPE_PTR: 1231 arg_type++; 1232 target_size = thunk_type_size(arg_type, 0); 1233 switch(ie->access) { 1234 case IOC_R: 1235 ret = get_errno(ioctl(fd, ie->host_cmd, buf_temp)); 1236 if (!is_error(ret)) { 1237 argptr = lock_user(arg, target_size, 0); 1238 thunk_convert(argptr, buf_temp, arg_type, THUNK_TARGET); 1239 unlock_user(argptr, arg, target_size); 1240 } 1241 break; 1242 case IOC_W: 1243 argptr = lock_user(arg, target_size, 1); 1244 thunk_convert(buf_temp, argptr, arg_type, THUNK_HOST); 1245 unlock_user(argptr, arg, 0); 1246 ret = get_errno(ioctl(fd, ie->host_cmd, buf_temp)); 1247 break; 1248 default: 1249 case IOC_RW: 1250 argptr = lock_user(arg, target_size, 1); 1251 thunk_convert(buf_temp, argptr, arg_type, THUNK_HOST); 1252 unlock_user(argptr, arg, 0); 1253 ret = get_errno(ioctl(fd, ie->host_cmd, buf_temp)); 1254 if (!is_error(ret)) { 1255 argptr = lock_user(arg, target_size, 0); 1256 thunk_convert(argptr, buf_temp, arg_type, THUNK_TARGET); 1257 unlock_user(argptr, arg, target_size); 1258 } 1259 break; 1260 } 1261 break; 1262 default: 1263 gemu_log("Unsupported ioctl type: cmd=0x%04lx type=%d\n", cmd, arg_type[0]); 1264 ret = -ENOSYS; 1265 break; 1266 } 1267 return ret; 1268 } 1269 1270 bitmask_transtbl iflag_tbl[] = { 1271 { TARGET_IGNBRK, TARGET_IGNBRK, IGNBRK, IGNBRK }, 1272 { TARGET_BRKINT, TARGET_BRKINT, BRKINT, BRKINT }, 1273 { TARGET_IGNPAR, TARGET_IGNPAR, IGNPAR, IGNPAR }, 1274 { TARGET_PARMRK, TARGET_PARMRK, PARMRK, PARMRK }, 1275 { TARGET_INPCK, TARGET_INPCK, INPCK, INPCK }, 1276 { TARGET_ISTRIP, TARGET_ISTRIP, ISTRIP, ISTRIP }, 1277 { TARGET_INLCR, TARGET_INLCR, INLCR, INLCR }, 1278 { TARGET_IGNCR, TARGET_IGNCR, IGNCR, IGNCR }, 1279 { TARGET_ICRNL, TARGET_ICRNL, ICRNL, ICRNL }, 1280 { TARGET_IUCLC, TARGET_IUCLC, IUCLC, IUCLC }, 1281 { TARGET_IXON, TARGET_IXON, IXON, IXON }, 1282 { TARGET_IXANY, TARGET_IXANY, IXANY, IXANY }, 1283 { TARGET_IXOFF, TARGET_IXOFF, IXOFF, IXOFF }, 1284 { TARGET_IMAXBEL, TARGET_IMAXBEL, IMAXBEL, IMAXBEL }, 1285 { 0, 0, 0, 0 } 1286 }; 1287 1288 bitmask_transtbl oflag_tbl[] = { 1289 { TARGET_OPOST, TARGET_OPOST, OPOST, OPOST }, 1290 { TARGET_OLCUC, TARGET_OLCUC, OLCUC, OLCUC }, 1291 { TARGET_ONLCR, TARGET_ONLCR, ONLCR, ONLCR }, 1292 { TARGET_OCRNL, TARGET_OCRNL, OCRNL, OCRNL }, 1293 { TARGET_ONOCR, TARGET_ONOCR, ONOCR, ONOCR }, 1294 { TARGET_ONLRET, TARGET_ONLRET, ONLRET, ONLRET }, 1295 { TARGET_OFILL, TARGET_OFILL, OFILL, OFILL }, 1296 { TARGET_OFDEL, TARGET_OFDEL, OFDEL, OFDEL }, 1297 { TARGET_NLDLY, TARGET_NL0, NLDLY, NL0 }, 1298 { TARGET_NLDLY, TARGET_NL1, NLDLY, NL1 }, 1299 { TARGET_CRDLY, TARGET_CR0, CRDLY, CR0 }, 1300 { TARGET_CRDLY, TARGET_CR1, CRDLY, CR1 }, 1301 { TARGET_CRDLY, TARGET_CR2, CRDLY, CR2 }, 1302 { TARGET_CRDLY, TARGET_CR3, CRDLY, CR3 }, 1303 { TARGET_TABDLY, TARGET_TAB0, TABDLY, TAB0 }, 1304 { TARGET_TABDLY, TARGET_TAB1, TABDLY, TAB1 }, 1305 { TARGET_TABDLY, TARGET_TAB2, TABDLY, TAB2 }, 1306 { TARGET_TABDLY, TARGET_TAB3, TABDLY, TAB3 }, 1307 { TARGET_BSDLY, TARGET_BS0, BSDLY, BS0 }, 1308 { TARGET_BSDLY, TARGET_BS1, BSDLY, BS1 }, 1309 { TARGET_VTDLY, TARGET_VT0, VTDLY, VT0 }, 1310 { TARGET_VTDLY, TARGET_VT1, VTDLY, VT1 }, 1311 { TARGET_FFDLY, TARGET_FF0, FFDLY, FF0 }, 1312 { TARGET_FFDLY, TARGET_FF1, FFDLY, FF1 }, 1313 { 0, 0, 0, 0 } 1314 }; 1315 1316 bitmask_transtbl cflag_tbl[] = { 1317 { TARGET_CBAUD, TARGET_B0, CBAUD, B0 }, 1318 { TARGET_CBAUD, TARGET_B50, CBAUD, B50 }, 1319 { TARGET_CBAUD, TARGET_B75, CBAUD, B75 }, 1320 { TARGET_CBAUD, TARGET_B110, CBAUD, B110 }, 1321 { TARGET_CBAUD, TARGET_B134, CBAUD, B134 }, 1322 { TARGET_CBAUD, TARGET_B150, CBAUD, B150 }, 1323 { TARGET_CBAUD, TARGET_B200, CBAUD, B200 }, 1324 { TARGET_CBAUD, TARGET_B300, CBAUD, B300 }, 1325 { TARGET_CBAUD, TARGET_B600, CBAUD, B600 }, 1326 { TARGET_CBAUD, TARGET_B1200, CBAUD, B1200 }, 1327 { TARGET_CBAUD, TARGET_B1800, CBAUD, B1800 }, 1328 { TARGET_CBAUD, TARGET_B2400, CBAUD, B2400 }, 1329 { TARGET_CBAUD, TARGET_B4800, CBAUD, B4800 }, 1330 { TARGET_CBAUD, TARGET_B9600, CBAUD, B9600 }, 1331 { TARGET_CBAUD, TARGET_B19200, CBAUD, B19200 }, 1332 { TARGET_CBAUD, TARGET_B38400, CBAUD, B38400 }, 1333 { TARGET_CBAUD, TARGET_B57600, CBAUD, B57600 }, 1334 { TARGET_CBAUD, TARGET_B115200, CBAUD, B115200 }, 1335 { TARGET_CBAUD, TARGET_B230400, CBAUD, B230400 }, 1336 { TARGET_CBAUD, TARGET_B460800, CBAUD, B460800 }, 1337 { TARGET_CSIZE, TARGET_CS5, CSIZE, CS5 }, 1338 { TARGET_CSIZE, TARGET_CS6, CSIZE, CS6 }, 1339 { TARGET_CSIZE, TARGET_CS7, CSIZE, CS7 }, 1340 { TARGET_CSIZE, TARGET_CS8, CSIZE, CS8 }, 1341 { TARGET_CSTOPB, TARGET_CSTOPB, CSTOPB, CSTOPB }, 1342 { TARGET_CREAD, TARGET_CREAD, CREAD, CREAD }, 1343 { TARGET_PARENB, TARGET_PARENB, PARENB, PARENB }, 1344 { TARGET_PARODD, TARGET_PARODD, PARODD, PARODD }, 1345 { TARGET_HUPCL, TARGET_HUPCL, HUPCL, HUPCL }, 1346 { TARGET_CLOCAL, TARGET_CLOCAL, CLOCAL, CLOCAL }, 1347 { TARGET_CRTSCTS, TARGET_CRTSCTS, CRTSCTS, CRTSCTS }, 1348 { 0, 0, 0, 0 } 1349 }; 1350 1351 bitmask_transtbl lflag_tbl[] = { 1352 { TARGET_ISIG, TARGET_ISIG, ISIG, ISIG }, 1353 { TARGET_ICANON, TARGET_ICANON, ICANON, ICANON }, 1354 { TARGET_XCASE, TARGET_XCASE, XCASE, XCASE }, 1355 { TARGET_ECHO, TARGET_ECHO, ECHO, ECHO }, 1356 { TARGET_ECHOE, TARGET_ECHOE, ECHOE, ECHOE }, 1357 { TARGET_ECHOK, TARGET_ECHOK, ECHOK, ECHOK }, 1358 { TARGET_ECHONL, TARGET_ECHONL, ECHONL, ECHONL }, 1359 { TARGET_NOFLSH, TARGET_NOFLSH, NOFLSH, NOFLSH }, 1360 { TARGET_TOSTOP, TARGET_TOSTOP, TOSTOP, TOSTOP }, 1361 { TARGET_ECHOCTL, TARGET_ECHOCTL, ECHOCTL, ECHOCTL }, 1362 { TARGET_ECHOPRT, TARGET_ECHOPRT, ECHOPRT, ECHOPRT }, 1363 { TARGET_ECHOKE, TARGET_ECHOKE, ECHOKE, ECHOKE }, 1364 { TARGET_FLUSHO, TARGET_FLUSHO, FLUSHO, FLUSHO }, 1365 { TARGET_PENDIN, TARGET_PENDIN, PENDIN, PENDIN }, 1366 { TARGET_IEXTEN, TARGET_IEXTEN, IEXTEN, IEXTEN }, 1367 { 0, 0, 0, 0 } 1368 }; 1369 1370 static void target_to_host_termios (void *dst, const void *src) 1371 { 1372 struct host_termios *host = dst; 1373 const struct target_termios *target = src; 1374 1375 host->c_iflag = 1376 target_to_host_bitmask(tswap32(target->c_iflag), iflag_tbl); 1377 host->c_oflag = 1378 target_to_host_bitmask(tswap32(target->c_oflag), oflag_tbl); 1379 host->c_cflag = 1380 target_to_host_bitmask(tswap32(target->c_cflag), cflag_tbl); 1381 host->c_lflag = 1382 target_to_host_bitmask(tswap32(target->c_lflag), lflag_tbl); 1383 host->c_line = target->c_line; 1384 1385 host->c_cc[VINTR] = target->c_cc[TARGET_VINTR]; 1386 host->c_cc[VQUIT] = target->c_cc[TARGET_VQUIT]; 1387 host->c_cc[VERASE] = target->c_cc[TARGET_VERASE]; 1388 host->c_cc[VKILL] = target->c_cc[TARGET_VKILL]; 1389 host->c_cc[VEOF] = target->c_cc[TARGET_VEOF]; 1390 host->c_cc[VTIME] = target->c_cc[TARGET_VTIME]; 1391 host->c_cc[VMIN] = target->c_cc[TARGET_VMIN]; 1392 host->c_cc[VSWTC] = target->c_cc[TARGET_VSWTC]; 1393 host->c_cc[VSTART] = target->c_cc[TARGET_VSTART]; 1394 host->c_cc[VSTOP] = target->c_cc[TARGET_VSTOP]; 1395 host->c_cc[VSUSP] = target->c_cc[TARGET_VSUSP]; 1396 host->c_cc[VEOL] = target->c_cc[TARGET_VEOL]; 1397 host->c_cc[VREPRINT] = target->c_cc[TARGET_VREPRINT]; 1398 host->c_cc[VDISCARD] = target->c_cc[TARGET_VDISCARD]; 1399 host->c_cc[VWERASE] = target->c_cc[TARGET_VWERASE]; 1400 host->c_cc[VLNEXT] = target->c_cc[TARGET_VLNEXT]; 1401 host->c_cc[VEOL2] = target->c_cc[TARGET_VEOL2]; 1402 } 1403 1404 static void host_to_target_termios (void *dst, const void *src) 1405 { 1406 struct target_termios *target = dst; 1407 const struct host_termios *host = src; 1408 1409 target->c_iflag = 1410 tswap32(host_to_target_bitmask(host->c_iflag, iflag_tbl)); 1411 target->c_oflag = 1412 tswap32(host_to_target_bitmask(host->c_oflag, oflag_tbl)); 1413 target->c_cflag = 1414 tswap32(host_to_target_bitmask(host->c_cflag, cflag_tbl)); 1415 target->c_lflag = 1416 tswap32(host_to_target_bitmask(host->c_lflag, lflag_tbl)); 1417 target->c_line = host->c_line; 1418 1419 target->c_cc[TARGET_VINTR] = host->c_cc[VINTR]; 1420 target->c_cc[TARGET_VQUIT] = host->c_cc[VQUIT]; 1421 target->c_cc[TARGET_VERASE] = host->c_cc[VERASE]; 1422 target->c_cc[TARGET_VKILL] = host->c_cc[VKILL]; 1423 target->c_cc[TARGET_VEOF] = host->c_cc[VEOF]; 1424 target->c_cc[TARGET_VTIME] = host->c_cc[VTIME]; 1425 target->c_cc[TARGET_VMIN] = host->c_cc[VMIN]; 1426 target->c_cc[TARGET_VSWTC] = host->c_cc[VSWTC]; 1427 target->c_cc[TARGET_VSTART] = host->c_cc[VSTART]; 1428 target->c_cc[TARGET_VSTOP] = host->c_cc[VSTOP]; 1429 target->c_cc[TARGET_VSUSP] = host->c_cc[VSUSP]; 1430 target->c_cc[TARGET_VEOL] = host->c_cc[VEOL]; 1431 target->c_cc[TARGET_VREPRINT] = host->c_cc[VREPRINT]; 1432 target->c_cc[TARGET_VDISCARD] = host->c_cc[VDISCARD]; 1433 target->c_cc[TARGET_VWERASE] = host->c_cc[VWERASE]; 1434 target->c_cc[TARGET_VLNEXT] = host->c_cc[VLNEXT]; 1435 target->c_cc[TARGET_VEOL2] = host->c_cc[VEOL2]; 1436 } 1437 1438 StructEntry struct_termios_def = { 1439 .convert = { host_to_target_termios, target_to_host_termios }, 1440 .size = { sizeof(struct target_termios), sizeof(struct host_termios) }, 1441 .align = { __alignof__(struct target_termios), __alignof__(struct host_termios) }, 1442 }; 1443 1444 static bitmask_transtbl mmap_flags_tbl[] = { 1445 { TARGET_MAP_SHARED, TARGET_MAP_SHARED, MAP_SHARED, MAP_SHARED }, 1446 { TARGET_MAP_PRIVATE, TARGET_MAP_PRIVATE, MAP_PRIVATE, MAP_PRIVATE }, 1447 { TARGET_MAP_FIXED, TARGET_MAP_FIXED, MAP_FIXED, MAP_FIXED }, 1448 { TARGET_MAP_ANONYMOUS, TARGET_MAP_ANONYMOUS, MAP_ANONYMOUS, MAP_ANONYMOUS }, 1449 { TARGET_MAP_GROWSDOWN, TARGET_MAP_GROWSDOWN, MAP_GROWSDOWN, MAP_GROWSDOWN }, 1450 { TARGET_MAP_DENYWRITE, TARGET_MAP_DENYWRITE, MAP_DENYWRITE, MAP_DENYWRITE }, 1451 { TARGET_MAP_EXECUTABLE, TARGET_MAP_EXECUTABLE, MAP_EXECUTABLE, MAP_EXECUTABLE }, 1452 { TARGET_MAP_LOCKED, TARGET_MAP_LOCKED, MAP_LOCKED, MAP_LOCKED }, 1453 { 0, 0, 0, 0 } 1454 }; 1455 1456 static bitmask_transtbl fcntl_flags_tbl[] = { 1457 { TARGET_O_ACCMODE, TARGET_O_WRONLY, O_ACCMODE, O_WRONLY, }, 1458 { TARGET_O_ACCMODE, TARGET_O_RDWR, O_ACCMODE, O_RDWR, }, 1459 { TARGET_O_CREAT, TARGET_O_CREAT, O_CREAT, O_CREAT, }, 1460 { TARGET_O_EXCL, TARGET_O_EXCL, O_EXCL, O_EXCL, }, 1461 { TARGET_O_NOCTTY, TARGET_O_NOCTTY, O_NOCTTY, O_NOCTTY, }, 1462 { TARGET_O_TRUNC, TARGET_O_TRUNC, O_TRUNC, O_TRUNC, }, 1463 { TARGET_O_APPEND, TARGET_O_APPEND, O_APPEND, O_APPEND, }, 1464 { TARGET_O_NONBLOCK, TARGET_O_NONBLOCK, O_NONBLOCK, O_NONBLOCK, }, 1465 { TARGET_O_SYNC, TARGET_O_SYNC, O_SYNC, O_SYNC, }, 1466 { TARGET_FASYNC, TARGET_FASYNC, FASYNC, FASYNC, }, 1467 { TARGET_O_DIRECTORY, TARGET_O_DIRECTORY, O_DIRECTORY, O_DIRECTORY, }, 1468 { TARGET_O_NOFOLLOW, TARGET_O_NOFOLLOW, O_NOFOLLOW, O_NOFOLLOW, }, 1469 { TARGET_O_LARGEFILE, TARGET_O_LARGEFILE, O_LARGEFILE, O_LARGEFILE, }, 1470 #if defined(O_DIRECT) 1471 { TARGET_O_DIRECT, TARGET_O_DIRECT, O_DIRECT, O_DIRECT, }, 1472 #endif 1473 { 0, 0, 0, 0 } 1474 }; 1475 1476 #if defined(TARGET_I386) 1477 1478 /* NOTE: there is really one LDT for all the threads */ 1479 uint8_t *ldt_table; 1480 1481 static int read_ldt(target_ulong ptr, unsigned long bytecount) 1482 { 1483 int size; 1484 void *p; 1485 1486 if (!ldt_table) 1487 return 0; 1488 size = TARGET_LDT_ENTRIES * TARGET_LDT_ENTRY_SIZE; 1489 if (size > bytecount) 1490 size = bytecount; 1491 p = lock_user(ptr, size, 0); 1492 /* ??? Shoudl this by byteswapped? */ 1493 memcpy(p, ldt_table, size); 1494 unlock_user(p, ptr, size); 1495 return size; 1496 } 1497 1498 /* XXX: add locking support */ 1499 static int write_ldt(CPUX86State *env, 1500 target_ulong ptr, unsigned long bytecount, int oldmode) 1501 { 1502 struct target_modify_ldt_ldt_s ldt_info; 1503 struct target_modify_ldt_ldt_s *target_ldt_info; 1504 int seg_32bit, contents, read_exec_only, limit_in_pages; 1505 int seg_not_present, useable; 1506 uint32_t *lp, entry_1, entry_2; 1507 1508 if (bytecount != sizeof(ldt_info)) 1509 return -EINVAL; 1510 lock_user_struct(target_ldt_info, ptr, 1); 1511 ldt_info.entry_number = tswap32(target_ldt_info->entry_number); 1512 ldt_info.base_addr = tswapl(target_ldt_info->base_addr); 1513 ldt_info.limit = tswap32(target_ldt_info->limit); 1514 ldt_info.flags = tswap32(target_ldt_info->flags); 1515 unlock_user_struct(target_ldt_info, ptr, 0); 1516 1517 if (ldt_info.entry_number >= TARGET_LDT_ENTRIES) 1518 return -EINVAL; 1519 seg_32bit = ldt_info.flags & 1; 1520 contents = (ldt_info.flags >> 1) & 3; 1521 read_exec_only = (ldt_info.flags >> 3) & 1; 1522 limit_in_pages = (ldt_info.flags >> 4) & 1; 1523 seg_not_present = (ldt_info.flags >> 5) & 1; 1524 useable = (ldt_info.flags >> 6) & 1; 1525 1526 if (contents == 3) { 1527 if (oldmode) 1528 return -EINVAL; 1529 if (seg_not_present == 0) 1530 return -EINVAL; 1531 } 1532 /* allocate the LDT */ 1533 if (!ldt_table) { 1534 ldt_table = malloc(TARGET_LDT_ENTRIES * TARGET_LDT_ENTRY_SIZE); 1535 if (!ldt_table) 1536 return -ENOMEM; 1537 memset(ldt_table, 0, TARGET_LDT_ENTRIES * TARGET_LDT_ENTRY_SIZE); 1538 env->ldt.base = h2g(ldt_table); 1539 env->ldt.limit = 0xffff; 1540 } 1541 1542 /* NOTE: same code as Linux kernel */ 1543 /* Allow LDTs to be cleared by the user. */ 1544 if (ldt_info.base_addr == 0 && ldt_info.limit == 0) { 1545 if (oldmode || 1546 (contents == 0 && 1547 read_exec_only == 1 && 1548 seg_32bit == 0 && 1549 limit_in_pages == 0 && 1550 seg_not_present == 1 && 1551 useable == 0 )) { 1552 entry_1 = 0; 1553 entry_2 = 0; 1554 goto install; 1555 } 1556 } 1557 1558 entry_1 = ((ldt_info.base_addr & 0x0000ffff) << 16) | 1559 (ldt_info.limit & 0x0ffff); 1560 entry_2 = (ldt_info.base_addr & 0xff000000) | 1561 ((ldt_info.base_addr & 0x00ff0000) >> 16) | 1562 (ldt_info.limit & 0xf0000) | 1563 ((read_exec_only ^ 1) << 9) | 1564 (contents << 10) | 1565 ((seg_not_present ^ 1) << 15) | 1566 (seg_32bit << 22) | 1567 (limit_in_pages << 23) | 1568 0x7000; 1569 if (!oldmode) 1570 entry_2 |= (useable << 20); 1571 1572 /* Install the new entry ... */ 1573 install: 1574 lp = (uint32_t *)(ldt_table + (ldt_info.entry_number << 3)); 1575 lp[0] = tswap32(entry_1); 1576 lp[1] = tswap32(entry_2); 1577 return 0; 1578 } 1579 1580 /* specific and weird i386 syscalls */ 1581 int do_modify_ldt(CPUX86State *env, int func, target_ulong ptr, unsigned long bytecount) 1582 { 1583 int ret = -ENOSYS; 1584 1585 switch (func) { 1586 case 0: 1587 ret = read_ldt(ptr, bytecount); 1588 break; 1589 case 1: 1590 ret = write_ldt(env, ptr, bytecount, 1); 1591 break; 1592 case 0x11: 1593 ret = write_ldt(env, ptr, bytecount, 0); 1594 break; 1595 } 1596 return ret; 1597 } 1598 1599 #endif /* defined(TARGET_I386) */ 1600 1601 /* this stack is the equivalent of the kernel stack associated with a 1602 thread/process */ 1603 #define NEW_STACK_SIZE 8192 1604 1605 static int clone_func(void *arg) 1606 { 1607 CPUState *env = arg; 1608 cpu_loop(env); 1609 /* never exits */ 1610 return 0; 1611 } 1612 1613 int do_fork(CPUState *env, unsigned int flags, unsigned long newsp) 1614 { 1615 int ret; 1616 TaskState *ts; 1617 uint8_t *new_stack; 1618 CPUState *new_env; 1619 1620 if (flags & CLONE_VM) { 1621 ts = malloc(sizeof(TaskState) + NEW_STACK_SIZE); 1622 memset(ts, 0, sizeof(TaskState)); 1623 new_stack = ts->stack; 1624 ts->used = 1; 1625 /* add in task state list */ 1626 ts->next = first_task_state; 1627 first_task_state = ts; 1628 /* we create a new CPU instance. */ 1629 new_env = cpu_init(); 1630 memcpy(new_env, env, sizeof(CPUState)); 1631 #if defined(TARGET_I386) 1632 if (!newsp) 1633 newsp = env->regs[R_ESP]; 1634 new_env->regs[R_ESP] = newsp; 1635 new_env->regs[R_EAX] = 0; 1636 #elif defined(TARGET_ARM) 1637 if (!newsp) 1638 newsp = env->regs[13]; 1639 new_env->regs[13] = newsp; 1640 new_env->regs[0] = 0; 1641 #elif defined(TARGET_SPARC) 1642 if (!newsp) 1643 newsp = env->regwptr[22]; 1644 new_env->regwptr[22] = newsp; 1645 new_env->regwptr[0] = 0; 1646 /* XXXXX */ 1647 printf ("HELPME: %s:%d\n", __FILE__, __LINE__); 1648 #elif defined(TARGET_MIPS) 1649 printf ("HELPME: %s:%d\n", __FILE__, __LINE__); 1650 #elif defined(TARGET_PPC) 1651 if (!newsp) 1652 newsp = env->gpr[1]; 1653 new_env->gpr[1] = newsp; 1654 { 1655 int i; 1656 for (i = 7; i < 32; i++) 1657 new_env->gpr[i] = 0; 1658 } 1659 #elif defined(TARGET_SH4) 1660 if (!newsp) 1661 newsp = env->gregs[15]; 1662 new_env->gregs[15] = newsp; 1663 /* XXXXX */ 1664 #else 1665 #error unsupported target CPU 1666 #endif 1667 new_env->opaque = ts; 1668 #ifdef __ia64__ 1669 ret = __clone2(clone_func, new_stack + NEW_STACK_SIZE, flags, new_env); 1670 #else 1671 ret = clone(clone_func, new_stack + NEW_STACK_SIZE, flags, new_env); 1672 #endif 1673 } else { 1674 /* if no CLONE_VM, we consider it is a fork */ 1675 if ((flags & ~CSIGNAL) != 0) 1676 return -EINVAL; 1677 ret = fork(); 1678 } 1679 return ret; 1680 } 1681 1682 static long do_fcntl(int fd, int cmd, target_ulong arg) 1683 { 1684 struct flock fl; 1685 struct target_flock *target_fl; 1686 long ret; 1687 1688 switch(cmd) { 1689 case TARGET_F_GETLK: 1690 ret = fcntl(fd, cmd, &fl); 1691 if (ret == 0) { 1692 lock_user_struct(target_fl, arg, 0); 1693 target_fl->l_type = tswap16(fl.l_type); 1694 target_fl->l_whence = tswap16(fl.l_whence); 1695 target_fl->l_start = tswapl(fl.l_start); 1696 target_fl->l_len = tswapl(fl.l_len); 1697 target_fl->l_pid = tswapl(fl.l_pid); 1698 unlock_user_struct(target_fl, arg, 1); 1699 } 1700 break; 1701 1702 case TARGET_F_SETLK: 1703 case TARGET_F_SETLKW: 1704 lock_user_struct(target_fl, arg, 1); 1705 fl.l_type = tswap16(target_fl->l_type); 1706 fl.l_whence = tswap16(target_fl->l_whence); 1707 fl.l_start = tswapl(target_fl->l_start); 1708 fl.l_len = tswapl(target_fl->l_len); 1709 fl.l_pid = tswapl(target_fl->l_pid); 1710 unlock_user_struct(target_fl, arg, 0); 1711 ret = fcntl(fd, cmd, &fl); 1712 break; 1713 1714 case TARGET_F_GETLK64: 1715 case TARGET_F_SETLK64: 1716 case TARGET_F_SETLKW64: 1717 ret = -1; 1718 errno = EINVAL; 1719 break; 1720 1721 case F_GETFL: 1722 ret = fcntl(fd, cmd, arg); 1723 ret = host_to_target_bitmask(ret, fcntl_flags_tbl); 1724 break; 1725 1726 case F_SETFL: 1727 ret = fcntl(fd, cmd, target_to_host_bitmask(arg, fcntl_flags_tbl)); 1728 break; 1729 1730 default: 1731 ret = fcntl(fd, cmd, arg); 1732 break; 1733 } 1734 return ret; 1735 } 1736 1737 #ifdef USE_UID16 1738 1739 static inline int high2lowuid(int uid) 1740 { 1741 if (uid > 65535) 1742 return 65534; 1743 else 1744 return uid; 1745 } 1746 1747 static inline int high2lowgid(int gid) 1748 { 1749 if (gid > 65535) 1750 return 65534; 1751 else 1752 return gid; 1753 } 1754 1755 static inline int low2highuid(int uid) 1756 { 1757 if ((int16_t)uid == -1) 1758 return -1; 1759 else 1760 return uid; 1761 } 1762 1763 static inline int low2highgid(int gid) 1764 { 1765 if ((int16_t)gid == -1) 1766 return -1; 1767 else 1768 return gid; 1769 } 1770 1771 #endif /* USE_UID16 */ 1772 1773 void syscall_init(void) 1774 { 1775 IOCTLEntry *ie; 1776 const argtype *arg_type; 1777 int size; 1778 1779 #define STRUCT(name, list...) thunk_register_struct(STRUCT_ ## name, #name, struct_ ## name ## _def); 1780 #define STRUCT_SPECIAL(name) thunk_register_struct_direct(STRUCT_ ## name, #name, &struct_ ## name ## _def); 1781 #include "syscall_types.h" 1782 #undef STRUCT 1783 #undef STRUCT_SPECIAL 1784 1785 /* we patch the ioctl size if necessary. We rely on the fact that 1786 no ioctl has all the bits at '1' in the size field */ 1787 ie = ioctl_entries; 1788 while (ie->target_cmd != 0) { 1789 if (((ie->target_cmd >> TARGET_IOC_SIZESHIFT) & TARGET_IOC_SIZEMASK) == 1790 TARGET_IOC_SIZEMASK) { 1791 arg_type = ie->arg_type; 1792 if (arg_type[0] != TYPE_PTR) { 1793 fprintf(stderr, "cannot patch size for ioctl 0x%x\n", 1794 ie->target_cmd); 1795 exit(1); 1796 } 1797 arg_type++; 1798 size = thunk_type_size(arg_type, 0); 1799 ie->target_cmd = (ie->target_cmd & 1800 ~(TARGET_IOC_SIZEMASK << TARGET_IOC_SIZESHIFT)) | 1801 (size << TARGET_IOC_SIZESHIFT); 1802 } 1803 /* automatic consistency check if same arch */ 1804 #if defined(__i386__) && defined(TARGET_I386) 1805 if (ie->target_cmd != ie->host_cmd) { 1806 fprintf(stderr, "ERROR: ioctl: target=0x%x host=0x%x\n", 1807 ie->target_cmd, ie->host_cmd); 1808 } 1809 #endif 1810 ie++; 1811 } 1812 } 1813 1814 static inline uint64_t target_offset64(uint32_t word0, uint32_t word1) 1815 { 1816 #ifdef TARGET_WORDS_BIG_ENDIAN 1817 return ((uint64_t)word0 << 32) | word1; 1818 #else 1819 return ((uint64_t)word1 << 32) | word0; 1820 #endif 1821 } 1822 1823 #ifdef TARGET_NR_truncate64 1824 static inline long target_truncate64(void *cpu_env, const char *arg1, 1825 long arg2, long arg3, long arg4) 1826 { 1827 #ifdef TARGET_ARM 1828 if (((CPUARMState *)cpu_env)->eabi) 1829 { 1830 arg2 = arg3; 1831 arg3 = arg4; 1832 } 1833 #endif 1834 return get_errno(truncate64(arg1, target_offset64(arg2, arg3))); 1835 } 1836 #endif 1837 1838 #ifdef TARGET_NR_ftruncate64 1839 static inline long target_ftruncate64(void *cpu_env, long arg1, long arg2, 1840 long arg3, long arg4) 1841 { 1842 #ifdef TARGET_ARM 1843 if (((CPUARMState *)cpu_env)->eabi) 1844 { 1845 arg2 = arg3; 1846 arg3 = arg4; 1847 } 1848 #endif 1849 return get_errno(ftruncate64(arg1, target_offset64(arg2, arg3))); 1850 } 1851 #endif 1852 1853 static inline void target_to_host_timespec(struct timespec *host_ts, 1854 target_ulong target_addr) 1855 { 1856 struct target_timespec *target_ts; 1857 1858 lock_user_struct(target_ts, target_addr, 1); 1859 host_ts->tv_sec = tswapl(target_ts->tv_sec); 1860 host_ts->tv_nsec = tswapl(target_ts->tv_nsec); 1861 unlock_user_struct(target_ts, target_addr, 0); 1862 } 1863 1864 static inline void host_to_target_timespec(target_ulong target_addr, 1865 struct timespec *host_ts) 1866 { 1867 struct target_timespec *target_ts; 1868 1869 lock_user_struct(target_ts, target_addr, 0); 1870 target_ts->tv_sec = tswapl(host_ts->tv_sec); 1871 target_ts->tv_nsec = tswapl(host_ts->tv_nsec); 1872 unlock_user_struct(target_ts, target_addr, 1); 1873 } 1874 1875 long do_syscall(void *cpu_env, int num, long arg1, long arg2, long arg3, 1876 long arg4, long arg5, long arg6) 1877 { 1878 long ret; 1879 struct stat st; 1880 struct statfs stfs; 1881 void *p; 1882 1883 #ifdef DEBUG 1884 gemu_log("syscall %d", num); 1885 #endif 1886 switch(num) { 1887 case TARGET_NR_exit: 1888 #ifdef HAVE_GPROF 1889 _mcleanup(); 1890 #endif 1891 gdb_exit(cpu_env, arg1); 1892 /* XXX: should free thread stack and CPU env */ 1893 _exit(arg1); 1894 ret = 0; /* avoid warning */ 1895 break; 1896 case TARGET_NR_read: 1897 page_unprotect_range(arg2, arg3); 1898 p = lock_user(arg2, arg3, 0); 1899 ret = get_errno(read(arg1, p, arg3)); 1900 unlock_user(p, arg2, ret); 1901 break; 1902 case TARGET_NR_write: 1903 p = lock_user(arg2, arg3, 1); 1904 ret = get_errno(write(arg1, p, arg3)); 1905 unlock_user(p, arg2, 0); 1906 break; 1907 case TARGET_NR_open: 1908 p = lock_user_string(arg1); 1909 ret = get_errno(open(path(p), 1910 target_to_host_bitmask(arg2, fcntl_flags_tbl), 1911 arg3)); 1912 unlock_user(p, arg1, 0); 1913 break; 1914 case TARGET_NR_close: 1915 ret = get_errno(close(arg1)); 1916 break; 1917 case TARGET_NR_brk: 1918 ret = do_brk(arg1); 1919 break; 1920 case TARGET_NR_fork: 1921 ret = get_errno(do_fork(cpu_env, SIGCHLD, 0)); 1922 break; 1923 case TARGET_NR_waitpid: 1924 { 1925 int status; 1926 ret = get_errno(waitpid(arg1, &status, arg3)); 1927 if (!is_error(ret) && arg2) 1928 tput32(arg2, status); 1929 } 1930 break; 1931 case TARGET_NR_creat: 1932 p = lock_user_string(arg1); 1933 ret = get_errno(creat(p, arg2)); 1934 unlock_user(p, arg1, 0); 1935 break; 1936 case TARGET_NR_link: 1937 { 1938 void * p2; 1939 p = lock_user_string(arg1); 1940 p2 = lock_user_string(arg2); 1941 ret = get_errno(link(p, p2)); 1942 unlock_user(p2, arg2, 0); 1943 unlock_user(p, arg1, 0); 1944 } 1945 break; 1946 case TARGET_NR_unlink: 1947 p = lock_user_string(arg1); 1948 ret = get_errno(unlink(p)); 1949 unlock_user(p, arg1, 0); 1950 break; 1951 case TARGET_NR_execve: 1952 { 1953 char **argp, **envp; 1954 int argc, envc; 1955 target_ulong gp; 1956 target_ulong guest_argp; 1957 target_ulong guest_envp; 1958 target_ulong addr; 1959 char **q; 1960 1961 argc = 0; 1962 guest_argp = arg2; 1963 for (gp = guest_argp; tgetl(gp); gp++) 1964 argc++; 1965 envc = 0; 1966 guest_envp = arg3; 1967 for (gp = guest_envp; tgetl(gp); gp++) 1968 envc++; 1969 1970 argp = alloca((argc + 1) * sizeof(void *)); 1971 envp = alloca((envc + 1) * sizeof(void *)); 1972 1973 for (gp = guest_argp, q = argp; ; 1974 gp += sizeof(target_ulong), q++) { 1975 addr = tgetl(gp); 1976 if (!addr) 1977 break; 1978 *q = lock_user_string(addr); 1979 } 1980 *q = NULL; 1981 1982 for (gp = guest_envp, q = envp; ; 1983 gp += sizeof(target_ulong), q++) { 1984 addr = tgetl(gp); 1985 if (!addr) 1986 break; 1987 *q = lock_user_string(addr); 1988 } 1989 *q = NULL; 1990 1991 p = lock_user_string(arg1); 1992 ret = get_errno(execve(p, argp, envp)); 1993 unlock_user(p, arg1, 0); 1994 1995 for (gp = guest_argp, q = argp; *q; 1996 gp += sizeof(target_ulong), q++) { 1997 addr = tgetl(gp); 1998 unlock_user(*q, addr, 0); 1999 } 2000 for (gp = guest_envp, q = envp; *q; 2001 gp += sizeof(target_ulong), q++) { 2002 addr = tgetl(gp); 2003 unlock_user(*q, addr, 0); 2004 } 2005 } 2006 break; 2007 case TARGET_NR_chdir: 2008 p = lock_user_string(arg1); 2009 ret = get_errno(chdir(p)); 2010 unlock_user(p, arg1, 0); 2011 break; 2012 #ifdef TARGET_NR_time 2013 case TARGET_NR_time: 2014 { 2015 time_t host_time; 2016 ret = get_errno(time(&host_time)); 2017 if (!is_error(ret) && arg1) 2018 tputl(arg1, host_time); 2019 } 2020 break; 2021 #endif 2022 case TARGET_NR_mknod: 2023 p = lock_user_string(arg1); 2024 ret = get_errno(mknod(p, arg2, arg3)); 2025 unlock_user(p, arg1, 0); 2026 break; 2027 case TARGET_NR_chmod: 2028 p = lock_user_string(arg1); 2029 ret = get_errno(chmod(p, arg2)); 2030 unlock_user(p, arg1, 0); 2031 break; 2032 #ifdef TARGET_NR_break 2033 case TARGET_NR_break: 2034 goto unimplemented; 2035 #endif 2036 #ifdef TARGET_NR_oldstat 2037 case TARGET_NR_oldstat: 2038 goto unimplemented; 2039 #endif 2040 case TARGET_NR_lseek: 2041 ret = get_errno(lseek(arg1, arg2, arg3)); 2042 break; 2043 case TARGET_NR_getpid: 2044 ret = get_errno(getpid()); 2045 break; 2046 case TARGET_NR_mount: 2047 /* need to look at the data field */ 2048 goto unimplemented; 2049 case TARGET_NR_umount: 2050 p = lock_user_string(arg1); 2051 ret = get_errno(umount(p)); 2052 unlock_user(p, arg1, 0); 2053 break; 2054 case TARGET_NR_stime: 2055 { 2056 time_t host_time; 2057 host_time = tgetl(arg1); 2058 ret = get_errno(stime(&host_time)); 2059 } 2060 break; 2061 case TARGET_NR_ptrace: 2062 goto unimplemented; 2063 case TARGET_NR_alarm: 2064 ret = alarm(arg1); 2065 break; 2066 #ifdef TARGET_NR_oldfstat 2067 case TARGET_NR_oldfstat: 2068 goto unimplemented; 2069 #endif 2070 case TARGET_NR_pause: 2071 ret = get_errno(pause()); 2072 break; 2073 case TARGET_NR_utime: 2074 { 2075 struct utimbuf tbuf, *host_tbuf; 2076 struct target_utimbuf *target_tbuf; 2077 if (arg2) { 2078 lock_user_struct(target_tbuf, arg2, 1); 2079 tbuf.actime = tswapl(target_tbuf->actime); 2080 tbuf.modtime = tswapl(target_tbuf->modtime); 2081 unlock_user_struct(target_tbuf, arg2, 0); 2082 host_tbuf = &tbuf; 2083 } else { 2084 host_tbuf = NULL; 2085 } 2086 p = lock_user_string(arg1); 2087 ret = get_errno(utime(p, host_tbuf)); 2088 unlock_user(p, arg1, 0); 2089 } 2090 break; 2091 case TARGET_NR_utimes: 2092 { 2093 struct timeval *tvp, tv[2]; 2094 if (arg2) { 2095 target_to_host_timeval(&tv[0], arg2); 2096 target_to_host_timeval(&tv[1], 2097 arg2 + sizeof (struct target_timeval)); 2098 tvp = tv; 2099 } else { 2100 tvp = NULL; 2101 } 2102 p = lock_user_string(arg1); 2103 ret = get_errno(utimes(p, tvp)); 2104 unlock_user(p, arg1, 0); 2105 } 2106 break; 2107 #ifdef TARGET_NR_stty 2108 case TARGET_NR_stty: 2109 goto unimplemented; 2110 #endif 2111 #ifdef TARGET_NR_gtty 2112 case TARGET_NR_gtty: 2113 goto unimplemented; 2114 #endif 2115 case TARGET_NR_access: 2116 p = lock_user_string(arg1); 2117 ret = get_errno(access(p, arg2)); 2118 unlock_user(p, arg1, 0); 2119 break; 2120 case TARGET_NR_nice: 2121 ret = get_errno(nice(arg1)); 2122 break; 2123 #ifdef TARGET_NR_ftime 2124 case TARGET_NR_ftime: 2125 goto unimplemented; 2126 #endif 2127 case TARGET_NR_sync: 2128 sync(); 2129 ret = 0; 2130 break; 2131 case TARGET_NR_kill: 2132 ret = get_errno(kill(arg1, arg2)); 2133 break; 2134 case TARGET_NR_rename: 2135 { 2136 void *p2; 2137 p = lock_user_string(arg1); 2138 p2 = lock_user_string(arg2); 2139 ret = get_errno(rename(p, p2)); 2140 unlock_user(p2, arg2, 0); 2141 unlock_user(p, arg1, 0); 2142 } 2143 break; 2144 case TARGET_NR_mkdir: 2145 p = lock_user_string(arg1); 2146 ret = get_errno(mkdir(p, arg2)); 2147 unlock_user(p, arg1, 0); 2148 break; 2149 case TARGET_NR_rmdir: 2150 p = lock_user_string(arg1); 2151 ret = get_errno(rmdir(p)); 2152 unlock_user(p, arg1, 0); 2153 break; 2154 case TARGET_NR_dup: 2155 ret = get_errno(dup(arg1)); 2156 break; 2157 case TARGET_NR_pipe: 2158 { 2159 int host_pipe[2]; 2160 ret = get_errno(pipe(host_pipe)); 2161 if (!is_error(ret)) { 2162 tput32(arg1, host_pipe[0]); 2163 tput32(arg1 + 4, host_pipe[1]); 2164 } 2165 } 2166 break; 2167 case TARGET_NR_times: 2168 { 2169 struct target_tms *tmsp; 2170 struct tms tms; 2171 ret = get_errno(times(&tms)); 2172 if (arg1) { 2173 tmsp = lock_user(arg1, sizeof(struct target_tms), 0); 2174 tmsp->tms_utime = tswapl(host_to_target_clock_t(tms.tms_utime)); 2175 tmsp->tms_stime = tswapl(host_to_target_clock_t(tms.tms_stime)); 2176 tmsp->tms_cutime = tswapl(host_to_target_clock_t(tms.tms_cutime)); 2177 tmsp->tms_cstime = tswapl(host_to_target_clock_t(tms.tms_cstime)); 2178 } 2179 if (!is_error(ret)) 2180 ret = host_to_target_clock_t(ret); 2181 } 2182 break; 2183 #ifdef TARGET_NR_prof 2184 case TARGET_NR_prof: 2185 goto unimplemented; 2186 #endif 2187 case TARGET_NR_signal: 2188 goto unimplemented; 2189 2190 case TARGET_NR_acct: 2191 p = lock_user_string(arg1); 2192 ret = get_errno(acct(path(p))); 2193 unlock_user(p, arg1, 0); 2194 break; 2195 case TARGET_NR_umount2: 2196 p = lock_user_string(arg1); 2197 ret = get_errno(umount2(p, arg2)); 2198 unlock_user(p, arg1, 0); 2199 break; 2200 #ifdef TARGET_NR_lock 2201 case TARGET_NR_lock: 2202 goto unimplemented; 2203 #endif 2204 case TARGET_NR_ioctl: 2205 ret = do_ioctl(arg1, arg2, arg3); 2206 break; 2207 case TARGET_NR_fcntl: 2208 ret = get_errno(do_fcntl(arg1, arg2, arg3)); 2209 break; 2210 #ifdef TARGET_NR_mpx 2211 case TARGET_NR_mpx: 2212 goto unimplemented; 2213 #endif 2214 case TARGET_NR_setpgid: 2215 ret = get_errno(setpgid(arg1, arg2)); 2216 break; 2217 #ifdef TARGET_NR_ulimit 2218 case TARGET_NR_ulimit: 2219 goto unimplemented; 2220 #endif 2221 #ifdef TARGET_NR_oldolduname 2222 case TARGET_NR_oldolduname: 2223 goto unimplemented; 2224 #endif 2225 case TARGET_NR_umask: 2226 ret = get_errno(umask(arg1)); 2227 break; 2228 case TARGET_NR_chroot: 2229 p = lock_user_string(arg1); 2230 ret = get_errno(chroot(p)); 2231 unlock_user(p, arg1, 0); 2232 break; 2233 case TARGET_NR_ustat: 2234 goto unimplemented; 2235 case TARGET_NR_dup2: 2236 ret = get_errno(dup2(arg1, arg2)); 2237 break; 2238 case TARGET_NR_getppid: 2239 ret = get_errno(getppid()); 2240 break; 2241 case TARGET_NR_getpgrp: 2242 ret = get_errno(getpgrp()); 2243 break; 2244 case TARGET_NR_setsid: 2245 ret = get_errno(setsid()); 2246 break; 2247 case TARGET_NR_sigaction: 2248 { 2249 #if !defined(TARGET_MIPS) 2250 struct target_old_sigaction *old_act; 2251 struct target_sigaction act, oact, *pact; 2252 if (arg2) { 2253 lock_user_struct(old_act, arg2, 1); 2254 act._sa_handler = old_act->_sa_handler; 2255 target_siginitset(&act.sa_mask, old_act->sa_mask); 2256 act.sa_flags = old_act->sa_flags; 2257 act.sa_restorer = old_act->sa_restorer; 2258 unlock_user_struct(old_act, arg2, 0); 2259 pact = &act; 2260 } else { 2261 pact = NULL; 2262 } 2263 ret = get_errno(do_sigaction(arg1, pact, &oact)); 2264 if (!is_error(ret) && arg3) { 2265 lock_user_struct(old_act, arg3, 0); 2266 old_act->_sa_handler = oact._sa_handler; 2267 old_act->sa_mask = oact.sa_mask.sig[0]; 2268 old_act->sa_flags = oact.sa_flags; 2269 old_act->sa_restorer = oact.sa_restorer; 2270 unlock_user_struct(old_act, arg3, 1); 2271 } 2272 #else 2273 struct target_sigaction act, oact, *pact, *old_act; 2274 2275 if (arg2) { 2276 lock_user_struct(old_act, arg2, 1); 2277 act._sa_handler = old_act->_sa_handler; 2278 target_siginitset(&act.sa_mask, old_act->sa_mask.sig[0]); 2279 act.sa_flags = old_act->sa_flags; 2280 unlock_user_struct(old_act, arg2, 0); 2281 pact = &act; 2282 } else { 2283 pact = NULL; 2284 } 2285 2286 ret = get_errno(do_sigaction(arg1, pact, &oact)); 2287 2288 if (!is_error(ret) && arg3) { 2289 lock_user_struct(old_act, arg3, 0); 2290 old_act->_sa_handler = oact._sa_handler; 2291 old_act->sa_flags = oact.sa_flags; 2292 old_act->sa_mask.sig[0] = oact.sa_mask.sig[0]; 2293 old_act->sa_mask.sig[1] = 0; 2294 old_act->sa_mask.sig[2] = 0; 2295 old_act->sa_mask.sig[3] = 0; 2296 unlock_user_struct(old_act, arg3, 1); 2297 } 2298 #endif 2299 } 2300 break; 2301 case TARGET_NR_rt_sigaction: 2302 { 2303 struct target_sigaction *act; 2304 struct target_sigaction *oact; 2305 2306 if (arg2) 2307 lock_user_struct(act, arg2, 1); 2308 else 2309 act = NULL; 2310 if (arg3) 2311 lock_user_struct(oact, arg3, 0); 2312 else 2313 oact = NULL; 2314 ret = get_errno(do_sigaction(arg1, act, oact)); 2315 if (arg2) 2316 unlock_user_struct(act, arg2, 0); 2317 if (arg3) 2318 unlock_user_struct(oact, arg3, 1); 2319 } 2320 break; 2321 case TARGET_NR_sgetmask: 2322 { 2323 sigset_t cur_set; 2324 target_ulong target_set; 2325 sigprocmask(0, NULL, &cur_set); 2326 host_to_target_old_sigset(&target_set, &cur_set); 2327 ret = target_set; 2328 } 2329 break; 2330 case TARGET_NR_ssetmask: 2331 { 2332 sigset_t set, oset, cur_set; 2333 target_ulong target_set = arg1; 2334 sigprocmask(0, NULL, &cur_set); 2335 target_to_host_old_sigset(&set, &target_set); 2336 sigorset(&set, &set, &cur_set); 2337 sigprocmask(SIG_SETMASK, &set, &oset); 2338 host_to_target_old_sigset(&target_set, &oset); 2339 ret = target_set; 2340 } 2341 break; 2342 case TARGET_NR_sigprocmask: 2343 { 2344 int how = arg1; 2345 sigset_t set, oldset, *set_ptr; 2346 2347 if (arg2) { 2348 switch(how) { 2349 case TARGET_SIG_BLOCK: 2350 how = SIG_BLOCK; 2351 break; 2352 case TARGET_SIG_UNBLOCK: 2353 how = SIG_UNBLOCK; 2354 break; 2355 case TARGET_SIG_SETMASK: 2356 how = SIG_SETMASK; 2357 break; 2358 default: 2359 ret = -EINVAL; 2360 goto fail; 2361 } 2362 p = lock_user(arg2, sizeof(target_sigset_t), 1); 2363 target_to_host_old_sigset(&set, p); 2364 unlock_user(p, arg2, 0); 2365 set_ptr = &set; 2366 } else { 2367 how = 0; 2368 set_ptr = NULL; 2369 } 2370 ret = get_errno(sigprocmask(arg1, set_ptr, &oldset)); 2371 if (!is_error(ret) && arg3) { 2372 p = lock_user(arg3, sizeof(target_sigset_t), 0); 2373 host_to_target_old_sigset(p, &oldset); 2374 unlock_user(p, arg3, sizeof(target_sigset_t)); 2375 } 2376 } 2377 break; 2378 case TARGET_NR_rt_sigprocmask: 2379 { 2380 int how = arg1; 2381 sigset_t set, oldset, *set_ptr; 2382 2383 if (arg2) { 2384 switch(how) { 2385 case TARGET_SIG_BLOCK: 2386 how = SIG_BLOCK; 2387 break; 2388 case TARGET_SIG_UNBLOCK: 2389 how = SIG_UNBLOCK; 2390 break; 2391 case TARGET_SIG_SETMASK: 2392 how = SIG_SETMASK; 2393 break; 2394 default: 2395 ret = -EINVAL; 2396 goto fail; 2397 } 2398 p = lock_user(arg2, sizeof(target_sigset_t), 1); 2399 target_to_host_sigset(&set, p); 2400 unlock_user(p, arg2, 0); 2401 set_ptr = &set; 2402 } else { 2403 how = 0; 2404 set_ptr = NULL; 2405 } 2406 ret = get_errno(sigprocmask(how, set_ptr, &oldset)); 2407 if (!is_error(ret) && arg3) { 2408 p = lock_user(arg3, sizeof(target_sigset_t), 0); 2409 host_to_target_sigset(p, &oldset); 2410 unlock_user(p, arg3, sizeof(target_sigset_t)); 2411 } 2412 } 2413 break; 2414 case TARGET_NR_sigpending: 2415 { 2416 sigset_t set; 2417 ret = get_errno(sigpending(&set)); 2418 if (!is_error(ret)) { 2419 p = lock_user(arg1, sizeof(target_sigset_t), 0); 2420 host_to_target_old_sigset(p, &set); 2421 unlock_user(p, arg1, sizeof(target_sigset_t)); 2422 } 2423 } 2424 break; 2425 case TARGET_NR_rt_sigpending: 2426 { 2427 sigset_t set; 2428 ret = get_errno(sigpending(&set)); 2429 if (!is_error(ret)) { 2430 p = lock_user(arg1, sizeof(target_sigset_t), 0); 2431 host_to_target_sigset(p, &set); 2432 unlock_user(p, arg1, sizeof(target_sigset_t)); 2433 } 2434 } 2435 break; 2436 case TARGET_NR_sigsuspend: 2437 { 2438 sigset_t set; 2439 p = lock_user(arg1, sizeof(target_sigset_t), 1); 2440 target_to_host_old_sigset(&set, p); 2441 unlock_user(p, arg1, 0); 2442 ret = get_errno(sigsuspend(&set)); 2443 } 2444 break; 2445 case TARGET_NR_rt_sigsuspend: 2446 { 2447 sigset_t set; 2448 p = lock_user(arg1, sizeof(target_sigset_t), 1); 2449 target_to_host_sigset(&set, p); 2450 unlock_user(p, arg1, 0); 2451 ret = get_errno(sigsuspend(&set)); 2452 } 2453 break; 2454 case TARGET_NR_rt_sigtimedwait: 2455 { 2456 sigset_t set; 2457 struct timespec uts, *puts; 2458 siginfo_t uinfo; 2459 2460 p = lock_user(arg1, sizeof(target_sigset_t), 1); 2461 target_to_host_sigset(&set, p); 2462 unlock_user(p, arg1, 0); 2463 if (arg3) { 2464 puts = &uts; 2465 target_to_host_timespec(puts, arg3); 2466 } else { 2467 puts = NULL; 2468 } 2469 ret = get_errno(sigtimedwait(&set, &uinfo, puts)); 2470 if (!is_error(ret) && arg2) { 2471 p = lock_user(arg2, sizeof(target_sigset_t), 0); 2472 host_to_target_siginfo(p, &uinfo); 2473 unlock_user(p, arg2, sizeof(target_sigset_t)); 2474 } 2475 } 2476 break; 2477 case TARGET_NR_rt_sigqueueinfo: 2478 { 2479 siginfo_t uinfo; 2480 p = lock_user(arg3, sizeof(target_sigset_t), 1); 2481 target_to_host_siginfo(&uinfo, p); 2482 unlock_user(p, arg1, 0); 2483 ret = get_errno(sys_rt_sigqueueinfo(arg1, arg2, &uinfo)); 2484 } 2485 break; 2486 case TARGET_NR_sigreturn: 2487 /* NOTE: ret is eax, so not transcoding must be done */ 2488 ret = do_sigreturn(cpu_env); 2489 break; 2490 case TARGET_NR_rt_sigreturn: 2491 /* NOTE: ret is eax, so not transcoding must be done */ 2492 ret = do_rt_sigreturn(cpu_env); 2493 break; 2494 case TARGET_NR_sethostname: 2495 p = lock_user_string(arg1); 2496 ret = get_errno(sethostname(p, arg2)); 2497 unlock_user(p, arg1, 0); 2498 break; 2499 case TARGET_NR_setrlimit: 2500 { 2501 /* XXX: convert resource ? */ 2502 int resource = arg1; 2503 struct target_rlimit *target_rlim; 2504 struct rlimit rlim; 2505 lock_user_struct(target_rlim, arg2, 1); 2506 rlim.rlim_cur = tswapl(target_rlim->rlim_cur); 2507 rlim.rlim_max = tswapl(target_rlim->rlim_max); 2508 unlock_user_struct(target_rlim, arg2, 0); 2509 ret = get_errno(setrlimit(resource, &rlim)); 2510 } 2511 break; 2512 case TARGET_NR_getrlimit: 2513 { 2514 /* XXX: convert resource ? */ 2515 int resource = arg1; 2516 struct target_rlimit *target_rlim; 2517 struct rlimit rlim; 2518 2519 ret = get_errno(getrlimit(resource, &rlim)); 2520 if (!is_error(ret)) { 2521 lock_user_struct(target_rlim, arg2, 0); 2522 rlim.rlim_cur = tswapl(target_rlim->rlim_cur); 2523 rlim.rlim_max = tswapl(target_rlim->rlim_max); 2524 unlock_user_struct(target_rlim, arg2, 1); 2525 } 2526 } 2527 break; 2528 case TARGET_NR_getrusage: 2529 { 2530 struct rusage rusage; 2531 ret = get_errno(getrusage(arg1, &rusage)); 2532 if (!is_error(ret)) { 2533 host_to_target_rusage(arg2, &rusage); 2534 } 2535 } 2536 break; 2537 case TARGET_NR_gettimeofday: 2538 { 2539 struct timeval tv; 2540 ret = get_errno(gettimeofday(&tv, NULL)); 2541 if (!is_error(ret)) { 2542 host_to_target_timeval(arg1, &tv); 2543 } 2544 } 2545 break; 2546 case TARGET_NR_settimeofday: 2547 { 2548 struct timeval tv; 2549 target_to_host_timeval(&tv, arg1); 2550 ret = get_errno(settimeofday(&tv, NULL)); 2551 } 2552 break; 2553 #ifdef TARGET_NR_select 2554 case TARGET_NR_select: 2555 { 2556 struct target_sel_arg_struct *sel; 2557 target_ulong inp, outp, exp, tvp; 2558 long nsel; 2559 2560 lock_user_struct(sel, arg1, 1); 2561 nsel = tswapl(sel->n); 2562 inp = tswapl(sel->inp); 2563 outp = tswapl(sel->outp); 2564 exp = tswapl(sel->exp); 2565 tvp = tswapl(sel->tvp); 2566 unlock_user_struct(sel, arg1, 0); 2567 ret = do_select(nsel, inp, outp, exp, tvp); 2568 } 2569 break; 2570 #endif 2571 case TARGET_NR_symlink: 2572 { 2573 void *p2; 2574 p = lock_user_string(arg1); 2575 p2 = lock_user_string(arg2); 2576 ret = get_errno(symlink(p, p2)); 2577 unlock_user(p2, arg2, 0); 2578 unlock_user(p, arg1, 0); 2579 } 2580 break; 2581 #ifdef TARGET_NR_oldlstat 2582 case TARGET_NR_oldlstat: 2583 goto unimplemented; 2584 #endif 2585 case TARGET_NR_readlink: 2586 { 2587 void *p2; 2588 p = lock_user_string(arg1); 2589 p2 = lock_user(arg2, arg3, 0); 2590 ret = get_errno(readlink(path(p), p2, arg3)); 2591 unlock_user(p2, arg2, ret); 2592 unlock_user(p, arg1, 0); 2593 } 2594 break; 2595 case TARGET_NR_uselib: 2596 goto unimplemented; 2597 case TARGET_NR_swapon: 2598 p = lock_user_string(arg1); 2599 ret = get_errno(swapon(p, arg2)); 2600 unlock_user(p, arg1, 0); 2601 break; 2602 case TARGET_NR_reboot: 2603 goto unimplemented; 2604 case TARGET_NR_readdir: 2605 goto unimplemented; 2606 case TARGET_NR_mmap: 2607 #if defined(TARGET_I386) || defined(TARGET_ARM) 2608 { 2609 target_ulong *v; 2610 target_ulong v1, v2, v3, v4, v5, v6; 2611 v = lock_user(arg1, 6 * sizeof(target_ulong), 1); 2612 v1 = tswapl(v[0]); 2613 v2 = tswapl(v[1]); 2614 v3 = tswapl(v[2]); 2615 v4 = tswapl(v[3]); 2616 v5 = tswapl(v[4]); 2617 v6 = tswapl(v[5]); 2618 unlock_user(v, arg1, 0); 2619 ret = get_errno(target_mmap(v1, v2, v3, 2620 target_to_host_bitmask(v4, mmap_flags_tbl), 2621 v5, v6)); 2622 } 2623 #else 2624 ret = get_errno(target_mmap(arg1, arg2, arg3, 2625 target_to_host_bitmask(arg4, mmap_flags_tbl), 2626 arg5, 2627 arg6)); 2628 #endif 2629 break; 2630 #ifdef TARGET_NR_mmap2 2631 case TARGET_NR_mmap2: 2632 #if defined(TARGET_SPARC) 2633 #define MMAP_SHIFT 12 2634 #else 2635 #define MMAP_SHIFT TARGET_PAGE_BITS 2636 #endif 2637 ret = get_errno(target_mmap(arg1, arg2, arg3, 2638 target_to_host_bitmask(arg4, mmap_flags_tbl), 2639 arg5, 2640 arg6 << MMAP_SHIFT)); 2641 break; 2642 #endif 2643 case TARGET_NR_munmap: 2644 ret = get_errno(target_munmap(arg1, arg2)); 2645 break; 2646 case TARGET_NR_mprotect: 2647 ret = get_errno(target_mprotect(arg1, arg2, arg3)); 2648 break; 2649 case TARGET_NR_mremap: 2650 ret = get_errno(target_mremap(arg1, arg2, arg3, arg4, arg5)); 2651 break; 2652 /* ??? msync/mlock/munlock are broken for softmmu. */ 2653 case TARGET_NR_msync: 2654 ret = get_errno(msync(g2h(arg1), arg2, arg3)); 2655 break; 2656 case TARGET_NR_mlock: 2657 ret = get_errno(mlock(g2h(arg1), arg2)); 2658 break; 2659 case TARGET_NR_munlock: 2660 ret = get_errno(munlock(g2h(arg1), arg2)); 2661 break; 2662 case TARGET_NR_mlockall: 2663 ret = get_errno(mlockall(arg1)); 2664 break; 2665 case TARGET_NR_munlockall: 2666 ret = get_errno(munlockall()); 2667 break; 2668 case TARGET_NR_truncate: 2669 p = lock_user_string(arg1); 2670 ret = get_errno(truncate(p, arg2)); 2671 unlock_user(p, arg1, 0); 2672 break; 2673 case TARGET_NR_ftruncate: 2674 ret = get_errno(ftruncate(arg1, arg2)); 2675 break; 2676 case TARGET_NR_fchmod: 2677 ret = get_errno(fchmod(arg1, arg2)); 2678 break; 2679 case TARGET_NR_getpriority: 2680 ret = get_errno(getpriority(arg1, arg2)); 2681 break; 2682 case TARGET_NR_setpriority: 2683 ret = get_errno(setpriority(arg1, arg2, arg3)); 2684 break; 2685 #ifdef TARGET_NR_profil 2686 case TARGET_NR_profil: 2687 goto unimplemented; 2688 #endif 2689 case TARGET_NR_statfs: 2690 p = lock_user_string(arg1); 2691 ret = get_errno(statfs(path(p), &stfs)); 2692 unlock_user(p, arg1, 0); 2693 convert_statfs: 2694 if (!is_error(ret)) { 2695 struct target_statfs *target_stfs; 2696 2697 lock_user_struct(target_stfs, arg2, 0); 2698 /* ??? put_user is probably wrong. */ 2699 put_user(stfs.f_type, &target_stfs->f_type); 2700 put_user(stfs.f_bsize, &target_stfs->f_bsize); 2701 put_user(stfs.f_blocks, &target_stfs->f_blocks); 2702 put_user(stfs.f_bfree, &target_stfs->f_bfree); 2703 put_user(stfs.f_bavail, &target_stfs->f_bavail); 2704 put_user(stfs.f_files, &target_stfs->f_files); 2705 put_user(stfs.f_ffree, &target_stfs->f_ffree); 2706 put_user(stfs.f_fsid.__val[0], &target_stfs->f_fsid); 2707 put_user(stfs.f_namelen, &target_stfs->f_namelen); 2708 unlock_user_struct(target_stfs, arg2, 1); 2709 } 2710 break; 2711 case TARGET_NR_fstatfs: 2712 ret = get_errno(fstatfs(arg1, &stfs)); 2713 goto convert_statfs; 2714 #ifdef TARGET_NR_statfs64 2715 case TARGET_NR_statfs64: 2716 p = lock_user_string(arg1); 2717 ret = get_errno(statfs(path(p), &stfs)); 2718 unlock_user(p, arg1, 0); 2719 convert_statfs64: 2720 if (!is_error(ret)) { 2721 struct target_statfs64 *target_stfs; 2722 2723 lock_user_struct(target_stfs, arg3, 0); 2724 /* ??? put_user is probably wrong. */ 2725 put_user(stfs.f_type, &target_stfs->f_type); 2726 put_user(stfs.f_bsize, &target_stfs->f_bsize); 2727 put_user(stfs.f_blocks, &target_stfs->f_blocks); 2728 put_user(stfs.f_bfree, &target_stfs->f_bfree); 2729 put_user(stfs.f_bavail, &target_stfs->f_bavail); 2730 put_user(stfs.f_files, &target_stfs->f_files); 2731 put_user(stfs.f_ffree, &target_stfs->f_ffree); 2732 put_user(stfs.f_fsid.__val[0], &target_stfs->f_fsid); 2733 put_user(stfs.f_namelen, &target_stfs->f_namelen); 2734 unlock_user_struct(target_stfs, arg3, 0); 2735 } 2736 break; 2737 case TARGET_NR_fstatfs64: 2738 ret = get_errno(fstatfs(arg1, &stfs)); 2739 goto convert_statfs64; 2740 #endif 2741 #ifdef TARGET_NR_ioperm 2742 case TARGET_NR_ioperm: 2743 goto unimplemented; 2744 #endif 2745 case TARGET_NR_socketcall: 2746 ret = do_socketcall(arg1, arg2); 2747 break; 2748 2749 #ifdef TARGET_NR_accept 2750 case TARGET_NR_accept: 2751 ret = do_socketcallwrapper(SOCKOP_accept, arg1, arg2, arg3, arg4, arg5, arg6); 2752 break; 2753 #endif 2754 #ifdef TARGET_NR_bind 2755 case TARGET_NR_bind: 2756 ret = do_bind(arg1, arg2, arg3); 2757 break; 2758 #endif 2759 #ifdef TARGET_NR_connect 2760 case TARGET_NR_connect: 2761 ret = do_connect(arg1, arg2, arg3); 2762 break; 2763 #endif 2764 #ifdef TARGET_NR_getpeername 2765 case TARGET_NR_getpeername: 2766 ret = do_socketcallwrapper(SOCKOP_getpeername, arg1, arg2, arg3, arg4, arg5, arg6); 2767 break; 2768 #endif 2769 #ifdef TARGET_NR_getsockname 2770 case TARGET_NR_getsockname: 2771 ret = do_socketcallwrapper(SOCKOP_getsockname, arg1, arg2, arg3, arg4, arg5, arg6); 2772 break; 2773 #endif 2774 #ifdef TARGET_NR_getsockopt 2775 case TARGET_NR_getsockopt: 2776 ret = do_getsockopt(arg1, arg2, arg3, arg4, arg5); 2777 break; 2778 #endif 2779 #ifdef TARGET_NR_listen 2780 case TARGET_NR_listen: 2781 ret = do_socketcallwrapper(SOCKOP_listen, arg1, arg2, arg3, arg4, arg5, arg6); 2782 break; 2783 #endif 2784 #ifdef TARGET_NR_recv 2785 case TARGET_NR_recv: 2786 ret = do_socketcallwrapper(SOCKOP_recv, arg1, arg2, arg3, arg4, arg5, arg6); 2787 break; 2788 #endif 2789 #ifdef TARGET_NR_recvfrom 2790 case TARGET_NR_recvfrom: 2791 ret = do_socketcallwrapper(SOCKOP_recvfrom, arg1, arg2, arg3, arg4, arg5, arg6); 2792 break; 2793 #endif 2794 #ifdef TARGET_NR_recvmsg 2795 case TARGET_NR_recvmsg: 2796 ret = do_sendrecvmsg(arg1, arg2, arg3, 0); 2797 break; 2798 #endif 2799 #ifdef TARGET_NR_send 2800 case TARGET_NR_send: 2801 ret = do_socketcallwrapper(SOCKOP_send, arg1, arg2, arg3, arg4, arg5, arg6); 2802 break; 2803 #endif 2804 #ifdef TARGET_NR_sendmsg 2805 case TARGET_NR_sendmsg: 2806 ret = do_sendrecvmsg(arg1, arg2, arg3, 1); 2807 break; 2808 #endif 2809 #ifdef TARGET_NR_sendto 2810 case TARGET_NR_sendto: 2811 ret = do_socketcallwrapper(SOCKOP_sendto, arg1, arg2, arg3, arg4, arg5, arg6); 2812 break; 2813 #endif 2814 #ifdef TARGET_NR_shutdown 2815 case TARGET_NR_shutdown: 2816 ret = do_socketcallwrapper(SOCKOP_shutdown, arg1, arg2, arg3, arg4, arg5, arg6); 2817 break; 2818 #endif 2819 #ifdef TARGET_NR_socket 2820 case TARGET_NR_socket: 2821 ret = do_socket(arg1, arg2, arg3); 2822 break; 2823 #endif 2824 #ifdef TARGET_NR_socketpair 2825 case TARGET_NR_socketpair: 2826 ret = do_socketcallwrapper(SOCKOP_socketpair, arg1, arg2, arg3, arg4, arg5, arg6); 2827 break; 2828 #endif 2829 #ifdef TARGET_NR_setsockopt 2830 case TARGET_NR_setsockopt: 2831 ret = do_setsockopt(arg1, arg2, arg3, arg4, (socklen_t) arg5); 2832 break; 2833 #endif 2834 2835 case TARGET_NR_syslog: 2836 goto unimplemented; 2837 case TARGET_NR_setitimer: 2838 { 2839 struct itimerval value, ovalue, *pvalue; 2840 2841 if (arg2) { 2842 pvalue = &value; 2843 target_to_host_timeval(&pvalue->it_interval, 2844 arg2); 2845 target_to_host_timeval(&pvalue->it_value, 2846 arg2 + sizeof(struct target_timeval)); 2847 } else { 2848 pvalue = NULL; 2849 } 2850 ret = get_errno(setitimer(arg1, pvalue, &ovalue)); 2851 if (!is_error(ret) && arg3) { 2852 host_to_target_timeval(arg3, 2853 &ovalue.it_interval); 2854 host_to_target_timeval(arg3 + sizeof(struct target_timeval), 2855 &ovalue.it_value); 2856 } 2857 } 2858 break; 2859 case TARGET_NR_getitimer: 2860 { 2861 struct itimerval value; 2862 2863 ret = get_errno(getitimer(arg1, &value)); 2864 if (!is_error(ret) && arg2) { 2865 host_to_target_timeval(arg2, 2866 &value.it_interval); 2867 host_to_target_timeval(arg2 + sizeof(struct target_timeval), 2868 &value.it_value); 2869 } 2870 } 2871 break; 2872 case TARGET_NR_stat: 2873 p = lock_user_string(arg1); 2874 ret = get_errno(stat(path(p), &st)); 2875 unlock_user(p, arg1, 0); 2876 goto do_stat; 2877 case TARGET_NR_lstat: 2878 p = lock_user_string(arg1); 2879 ret = get_errno(lstat(path(p), &st)); 2880 unlock_user(p, arg1, 0); 2881 goto do_stat; 2882 case TARGET_NR_fstat: 2883 { 2884 ret = get_errno(fstat(arg1, &st)); 2885 do_stat: 2886 if (!is_error(ret)) { 2887 struct target_stat *target_st; 2888 2889 lock_user_struct(target_st, arg2, 0); 2890 target_st->st_dev = tswap16(st.st_dev); 2891 target_st->st_ino = tswapl(st.st_ino); 2892 #if defined(TARGET_PPC) 2893 target_st->st_mode = tswapl(st.st_mode); /* XXX: check this */ 2894 target_st->st_uid = tswap32(st.st_uid); 2895 target_st->st_gid = tswap32(st.st_gid); 2896 #else 2897 target_st->st_mode = tswap16(st.st_mode); 2898 target_st->st_uid = tswap16(st.st_uid); 2899 target_st->st_gid = tswap16(st.st_gid); 2900 #endif 2901 target_st->st_nlink = tswap16(st.st_nlink); 2902 target_st->st_rdev = tswap16(st.st_rdev); 2903 target_st->st_size = tswapl(st.st_size); 2904 target_st->st_blksize = tswapl(st.st_blksize); 2905 target_st->st_blocks = tswapl(st.st_blocks); 2906 target_st->target_st_atime = tswapl(st.st_atime); 2907 target_st->target_st_mtime = tswapl(st.st_mtime); 2908 target_st->target_st_ctime = tswapl(st.st_ctime); 2909 unlock_user_struct(target_st, arg2, 1); 2910 } 2911 } 2912 break; 2913 #ifdef TARGET_NR_olduname 2914 case TARGET_NR_olduname: 2915 goto unimplemented; 2916 #endif 2917 #ifdef TARGET_NR_iopl 2918 case TARGET_NR_iopl: 2919 goto unimplemented; 2920 #endif 2921 case TARGET_NR_vhangup: 2922 ret = get_errno(vhangup()); 2923 break; 2924 #ifdef TARGET_NR_idle 2925 case TARGET_NR_idle: 2926 goto unimplemented; 2927 #endif 2928 #ifdef TARGET_NR_syscall 2929 case TARGET_NR_syscall: 2930 ret = do_syscall(cpu_env,arg1 & 0xffff,arg2,arg3,arg4,arg5,arg6,0); 2931 break; 2932 #endif 2933 case TARGET_NR_wait4: 2934 { 2935 int status; 2936 target_long status_ptr = arg2; 2937 struct rusage rusage, *rusage_ptr; 2938 target_ulong target_rusage = arg4; 2939 if (target_rusage) 2940 rusage_ptr = &rusage; 2941 else 2942 rusage_ptr = NULL; 2943 ret = get_errno(wait4(arg1, &status, arg3, rusage_ptr)); 2944 if (!is_error(ret)) { 2945 if (status_ptr) 2946 tputl(status_ptr, status); 2947 if (target_rusage) { 2948 host_to_target_rusage(target_rusage, &rusage); 2949 } 2950 } 2951 } 2952 break; 2953 case TARGET_NR_swapoff: 2954 p = lock_user_string(arg1); 2955 ret = get_errno(swapoff(p)); 2956 unlock_user(p, arg1, 0); 2957 break; 2958 case TARGET_NR_sysinfo: 2959 { 2960 struct target_sysinfo *target_value; 2961 struct sysinfo value; 2962 ret = get_errno(sysinfo(&value)); 2963 if (!is_error(ret) && arg1) 2964 { 2965 /* ??? __put_user is probably wrong. */ 2966 lock_user_struct(target_value, arg1, 0); 2967 __put_user(value.uptime, &target_value->uptime); 2968 __put_user(value.loads[0], &target_value->loads[0]); 2969 __put_user(value.loads[1], &target_value->loads[1]); 2970 __put_user(value.loads[2], &target_value->loads[2]); 2971 __put_user(value.totalram, &target_value->totalram); 2972 __put_user(value.freeram, &target_value->freeram); 2973 __put_user(value.sharedram, &target_value->sharedram); 2974 __put_user(value.bufferram, &target_value->bufferram); 2975 __put_user(value.totalswap, &target_value->totalswap); 2976 __put_user(value.freeswap, &target_value->freeswap); 2977 __put_user(value.procs, &target_value->procs); 2978 __put_user(value.totalhigh, &target_value->totalhigh); 2979 __put_user(value.freehigh, &target_value->freehigh); 2980 __put_user(value.mem_unit, &target_value->mem_unit); 2981 unlock_user_struct(target_value, arg1, 1); 2982 } 2983 } 2984 break; 2985 case TARGET_NR_ipc: 2986 ret = do_ipc(arg1, arg2, arg3, arg4, arg5, arg6); 2987 break; 2988 case TARGET_NR_fsync: 2989 ret = get_errno(fsync(arg1)); 2990 break; 2991 case TARGET_NR_clone: 2992 ret = get_errno(do_fork(cpu_env, arg1, arg2)); 2993 break; 2994 #ifdef __NR_exit_group 2995 /* new thread calls */ 2996 case TARGET_NR_exit_group: 2997 gdb_exit(cpu_env, arg1); 2998 ret = get_errno(exit_group(arg1)); 2999 break; 3000 #endif 3001 case TARGET_NR_setdomainname: 3002 p = lock_user_string(arg1); 3003 ret = get_errno(setdomainname(p, arg2)); 3004 unlock_user(p, arg1, 0); 3005 break; 3006 case TARGET_NR_uname: 3007 /* no need to transcode because we use the linux syscall */ 3008 { 3009 struct new_utsname * buf; 3010 3011 lock_user_struct(buf, arg1, 0); 3012 ret = get_errno(sys_uname(buf)); 3013 if (!is_error(ret)) { 3014 /* Overrite the native machine name with whatever is being 3015 emulated. */ 3016 strcpy (buf->machine, UNAME_MACHINE); 3017 /* Allow the user to override the reported release. */ 3018 if (qemu_uname_release && *qemu_uname_release) 3019 strcpy (buf->release, qemu_uname_release); 3020 } 3021 unlock_user_struct(buf, arg1, 1); 3022 } 3023 break; 3024 #ifdef TARGET_I386 3025 case TARGET_NR_modify_ldt: 3026 ret = get_errno(do_modify_ldt(cpu_env, arg1, arg2, arg3)); 3027 break; 3028 case TARGET_NR_vm86old: 3029 goto unimplemented; 3030 case TARGET_NR_vm86: 3031 ret = do_vm86(cpu_env, arg1, arg2); 3032 break; 3033 #endif 3034 case TARGET_NR_adjtimex: 3035 goto unimplemented; 3036 case TARGET_NR_create_module: 3037 case TARGET_NR_init_module: 3038 case TARGET_NR_delete_module: 3039 case TARGET_NR_get_kernel_syms: 3040 goto unimplemented; 3041 case TARGET_NR_quotactl: 3042 goto unimplemented; 3043 case TARGET_NR_getpgid: 3044 ret = get_errno(getpgid(arg1)); 3045 break; 3046 case TARGET_NR_fchdir: 3047 ret = get_errno(fchdir(arg1)); 3048 break; 3049 case TARGET_NR_bdflush: 3050 goto unimplemented; 3051 case TARGET_NR_sysfs: 3052 goto unimplemented; 3053 case TARGET_NR_personality: 3054 ret = get_errno(personality(arg1)); 3055 break; 3056 case TARGET_NR_afs_syscall: 3057 goto unimplemented; 3058 case TARGET_NR__llseek: 3059 { 3060 #if defined (__x86_64__) 3061 ret = get_errno(lseek(arg1, ((uint64_t )arg2 << 32) | arg3, arg5)); 3062 tput64(arg4, ret); 3063 #else 3064 int64_t res; 3065 ret = get_errno(_llseek(arg1, arg2, arg3, &res, arg5)); 3066 tput64(arg4, res); 3067 #endif 3068 } 3069 break; 3070 case TARGET_NR_getdents: 3071 #if TARGET_LONG_SIZE != 4 3072 goto unimplemented; 3073 #warning not supported 3074 #elif TARGET_LONG_SIZE == 4 && HOST_LONG_SIZE == 8 3075 { 3076 struct target_dirent *target_dirp; 3077 struct dirent *dirp; 3078 long count = arg3; 3079 3080 dirp = malloc(count); 3081 if (!dirp) 3082 return -ENOMEM; 3083 3084 ret = get_errno(sys_getdents(arg1, dirp, count)); 3085 if (!is_error(ret)) { 3086 struct dirent *de; 3087 struct target_dirent *tde; 3088 int len = ret; 3089 int reclen, treclen; 3090 int count1, tnamelen; 3091 3092 count1 = 0; 3093 de = dirp; 3094 target_dirp = lock_user(arg2, count, 0); 3095 tde = target_dirp; 3096 while (len > 0) { 3097 reclen = de->d_reclen; 3098 treclen = reclen - (2 * (sizeof(long) - sizeof(target_long))); 3099 tde->d_reclen = tswap16(treclen); 3100 tde->d_ino = tswapl(de->d_ino); 3101 tde->d_off = tswapl(de->d_off); 3102 tnamelen = treclen - (2 * sizeof(target_long) + 2); 3103 if (tnamelen > 256) 3104 tnamelen = 256; 3105 /* XXX: may not be correct */ 3106 strncpy(tde->d_name, de->d_name, tnamelen); 3107 de = (struct dirent *)((char *)de + reclen); 3108 len -= reclen; 3109 tde = (struct dirent *)((char *)tde + treclen); 3110 count1 += treclen; 3111 } 3112 ret = count1; 3113 } 3114 unlock_user(target_dirp, arg2, ret); 3115 free(dirp); 3116 } 3117 #else 3118 { 3119 struct dirent *dirp; 3120 long count = arg3; 3121 3122 dirp = lock_user(arg2, count, 0); 3123 ret = get_errno(sys_getdents(arg1, dirp, count)); 3124 if (!is_error(ret)) { 3125 struct dirent *de; 3126 int len = ret; 3127 int reclen; 3128 de = dirp; 3129 while (len > 0) { 3130 reclen = de->d_reclen; 3131 if (reclen > len) 3132 break; 3133 de->d_reclen = tswap16(reclen); 3134 tswapls(&de->d_ino); 3135 tswapls(&de->d_off); 3136 de = (struct dirent *)((char *)de + reclen); 3137 len -= reclen; 3138 } 3139 } 3140 unlock_user(dirp, arg2, ret); 3141 } 3142 #endif 3143 break; 3144 #ifdef TARGET_NR_getdents64 3145 case TARGET_NR_getdents64: 3146 { 3147 struct dirent64 *dirp; 3148 long count = arg3; 3149 dirp = lock_user(arg2, count, 0); 3150 ret = get_errno(sys_getdents64(arg1, dirp, count)); 3151 if (!is_error(ret)) { 3152 struct dirent64 *de; 3153 int len = ret; 3154 int reclen; 3155 de = dirp; 3156 while (len > 0) { 3157 reclen = de->d_reclen; 3158 if (reclen > len) 3159 break; 3160 de->d_reclen = tswap16(reclen); 3161 tswap64s(&de->d_ino); 3162 tswap64s(&de->d_off); 3163 de = (struct dirent64 *)((char *)de + reclen); 3164 len -= reclen; 3165 } 3166 } 3167 unlock_user(dirp, arg2, ret); 3168 } 3169 break; 3170 #endif /* TARGET_NR_getdents64 */ 3171 case TARGET_NR__newselect: 3172 ret = do_select(arg1, arg2, arg3, arg4, arg5); 3173 break; 3174 case TARGET_NR_poll: 3175 { 3176 struct target_pollfd *target_pfd; 3177 unsigned int nfds = arg2; 3178 int timeout = arg3; 3179 struct pollfd *pfd; 3180 unsigned int i; 3181 3182 target_pfd = lock_user(arg1, sizeof(struct target_pollfd) * nfds, 1); 3183 pfd = alloca(sizeof(struct pollfd) * nfds); 3184 for(i = 0; i < nfds; i++) { 3185 pfd[i].fd = tswap32(target_pfd[i].fd); 3186 pfd[i].events = tswap16(target_pfd[i].events); 3187 } 3188 ret = get_errno(poll(pfd, nfds, timeout)); 3189 if (!is_error(ret)) { 3190 for(i = 0; i < nfds; i++) { 3191 target_pfd[i].revents = tswap16(pfd[i].revents); 3192 } 3193 ret += nfds * (sizeof(struct target_pollfd) 3194 - sizeof(struct pollfd)); 3195 } 3196 unlock_user(target_pfd, arg1, ret); 3197 } 3198 break; 3199 case TARGET_NR_flock: 3200 /* NOTE: the flock constant seems to be the same for every 3201 Linux platform */ 3202 ret = get_errno(flock(arg1, arg2)); 3203 break; 3204 case TARGET_NR_readv: 3205 { 3206 int count = arg3; 3207 struct iovec *vec; 3208 3209 vec = alloca(count * sizeof(struct iovec)); 3210 lock_iovec(vec, arg2, count, 0); 3211 ret = get_errno(readv(arg1, vec, count)); 3212 unlock_iovec(vec, arg2, count, 1); 3213 } 3214 break; 3215 case TARGET_NR_writev: 3216 { 3217 int count = arg3; 3218 struct iovec *vec; 3219 3220 vec = alloca(count * sizeof(struct iovec)); 3221 lock_iovec(vec, arg2, count, 1); 3222 ret = get_errno(writev(arg1, vec, count)); 3223 unlock_iovec(vec, arg2, count, 0); 3224 } 3225 break; 3226 case TARGET_NR_getsid: 3227 ret = get_errno(getsid(arg1)); 3228 break; 3229 case TARGET_NR_fdatasync: 3230 ret = get_errno(fdatasync(arg1)); 3231 break; 3232 case TARGET_NR__sysctl: 3233 /* We don't implement this, but ENODIR is always a safe 3234 return value. */ 3235 return -ENOTDIR; 3236 case TARGET_NR_sched_setparam: 3237 { 3238 struct sched_param *target_schp; 3239 struct sched_param schp; 3240 3241 lock_user_struct(target_schp, arg2, 1); 3242 schp.sched_priority = tswap32(target_schp->sched_priority); 3243 unlock_user_struct(target_schp, arg2, 0); 3244 ret = get_errno(sched_setparam(arg1, &schp)); 3245 } 3246 break; 3247 case TARGET_NR_sched_getparam: 3248 { 3249 struct sched_param *target_schp; 3250 struct sched_param schp; 3251 ret = get_errno(sched_getparam(arg1, &schp)); 3252 if (!is_error(ret)) { 3253 lock_user_struct(target_schp, arg2, 0); 3254 target_schp->sched_priority = tswap32(schp.sched_priority); 3255 unlock_user_struct(target_schp, arg2, 1); 3256 } 3257 } 3258 break; 3259 case TARGET_NR_sched_setscheduler: 3260 { 3261 struct sched_param *target_schp; 3262 struct sched_param schp; 3263 lock_user_struct(target_schp, arg3, 1); 3264 schp.sched_priority = tswap32(target_schp->sched_priority); 3265 unlock_user_struct(target_schp, arg3, 0); 3266 ret = get_errno(sched_setscheduler(arg1, arg2, &schp)); 3267 } 3268 break; 3269 case TARGET_NR_sched_getscheduler: 3270 ret = get_errno(sched_getscheduler(arg1)); 3271 break; 3272 case TARGET_NR_sched_yield: 3273 ret = get_errno(sched_yield()); 3274 break; 3275 case TARGET_NR_sched_get_priority_max: 3276 ret = get_errno(sched_get_priority_max(arg1)); 3277 break; 3278 case TARGET_NR_sched_get_priority_min: 3279 ret = get_errno(sched_get_priority_min(arg1)); 3280 break; 3281 case TARGET_NR_sched_rr_get_interval: 3282 { 3283 struct timespec ts; 3284 ret = get_errno(sched_rr_get_interval(arg1, &ts)); 3285 if (!is_error(ret)) { 3286 host_to_target_timespec(arg2, &ts); 3287 } 3288 } 3289 break; 3290 case TARGET_NR_nanosleep: 3291 { 3292 struct timespec req, rem; 3293 target_to_host_timespec(&req, arg1); 3294 ret = get_errno(nanosleep(&req, &rem)); 3295 if (is_error(ret) && arg2) { 3296 host_to_target_timespec(arg2, &rem); 3297 } 3298 } 3299 break; 3300 case TARGET_NR_query_module: 3301 goto unimplemented; 3302 case TARGET_NR_nfsservctl: 3303 goto unimplemented; 3304 case TARGET_NR_prctl: 3305 goto unimplemented; 3306 #ifdef TARGET_NR_pread 3307 case TARGET_NR_pread: 3308 page_unprotect_range(arg2, arg3); 3309 p = lock_user(arg2, arg3, 0); 3310 ret = get_errno(pread(arg1, p, arg3, arg4)); 3311 unlock_user(p, arg2, ret); 3312 break; 3313 case TARGET_NR_pwrite: 3314 p = lock_user(arg2, arg3, 1); 3315 ret = get_errno(pwrite(arg1, p, arg3, arg4)); 3316 unlock_user(p, arg2, 0); 3317 break; 3318 #endif 3319 case TARGET_NR_getcwd: 3320 p = lock_user(arg1, arg2, 0); 3321 ret = get_errno(sys_getcwd1(p, arg2)); 3322 unlock_user(p, arg1, ret); 3323 break; 3324 case TARGET_NR_capget: 3325 goto unimplemented; 3326 case TARGET_NR_capset: 3327 goto unimplemented; 3328 case TARGET_NR_sigaltstack: 3329 goto unimplemented; 3330 case TARGET_NR_sendfile: 3331 goto unimplemented; 3332 #ifdef TARGET_NR_getpmsg 3333 case TARGET_NR_getpmsg: 3334 goto unimplemented; 3335 #endif 3336 #ifdef TARGET_NR_putpmsg 3337 case TARGET_NR_putpmsg: 3338 goto unimplemented; 3339 #endif 3340 #ifdef TARGET_NR_vfork 3341 case TARGET_NR_vfork: 3342 ret = get_errno(do_fork(cpu_env, CLONE_VFORK | CLONE_VM | SIGCHLD, 0)); 3343 break; 3344 #endif 3345 #ifdef TARGET_NR_ugetrlimit 3346 case TARGET_NR_ugetrlimit: 3347 { 3348 struct rlimit rlim; 3349 ret = get_errno(getrlimit(arg1, &rlim)); 3350 if (!is_error(ret)) { 3351 struct target_rlimit *target_rlim; 3352 lock_user_struct(target_rlim, arg2, 0); 3353 target_rlim->rlim_cur = tswapl(rlim.rlim_cur); 3354 target_rlim->rlim_max = tswapl(rlim.rlim_max); 3355 unlock_user_struct(target_rlim, arg2, 1); 3356 } 3357 break; 3358 } 3359 #endif 3360 #ifdef TARGET_NR_truncate64 3361 case TARGET_NR_truncate64: 3362 p = lock_user_string(arg1); 3363 ret = target_truncate64(cpu_env, p, arg2, arg3, arg4); 3364 unlock_user(p, arg1, 0); 3365 break; 3366 #endif 3367 #ifdef TARGET_NR_ftruncate64 3368 case TARGET_NR_ftruncate64: 3369 ret = target_ftruncate64(cpu_env, arg1, arg2, arg3, arg4); 3370 break; 3371 #endif 3372 #ifdef TARGET_NR_stat64 3373 case TARGET_NR_stat64: 3374 p = lock_user_string(arg1); 3375 ret = get_errno(stat(path(p), &st)); 3376 unlock_user(p, arg1, 0); 3377 goto do_stat64; 3378 #endif 3379 #ifdef TARGET_NR_lstat64 3380 case TARGET_NR_lstat64: 3381 p = lock_user_string(arg1); 3382 ret = get_errno(lstat(path(p), &st)); 3383 unlock_user(p, arg1, 0); 3384 goto do_stat64; 3385 #endif 3386 #ifdef TARGET_NR_fstat64 3387 case TARGET_NR_fstat64: 3388 { 3389 ret = get_errno(fstat(arg1, &st)); 3390 do_stat64: 3391 if (!is_error(ret)) { 3392 #ifdef TARGET_ARM 3393 if (((CPUARMState *)cpu_env)->eabi) { 3394 struct target_eabi_stat64 *target_st; 3395 lock_user_struct(target_st, arg2, 1); 3396 memset(target_st, 0, sizeof(struct target_eabi_stat64)); 3397 /* put_user is probably wrong. */ 3398 put_user(st.st_dev, &target_st->st_dev); 3399 put_user(st.st_ino, &target_st->st_ino); 3400 #ifdef TARGET_STAT64_HAS_BROKEN_ST_INO 3401 put_user(st.st_ino, &target_st->__st_ino); 3402 #endif 3403 put_user(st.st_mode, &target_st->st_mode); 3404 put_user(st.st_nlink, &target_st->st_nlink); 3405 put_user(st.st_uid, &target_st->st_uid); 3406 put_user(st.st_gid, &target_st->st_gid); 3407 put_user(st.st_rdev, &target_st->st_rdev); 3408 /* XXX: better use of kernel struct */ 3409 put_user(st.st_size, &target_st->st_size); 3410 put_user(st.st_blksize, &target_st->st_blksize); 3411 put_user(st.st_blocks, &target_st->st_blocks); 3412 put_user(st.st_atime, &target_st->target_st_atime); 3413 put_user(st.st_mtime, &target_st->target_st_mtime); 3414 put_user(st.st_ctime, &target_st->target_st_ctime); 3415 unlock_user_struct(target_st, arg2, 0); 3416 } else 3417 #endif 3418 { 3419 struct target_stat64 *target_st; 3420 lock_user_struct(target_st, arg2, 1); 3421 memset(target_st, 0, sizeof(struct target_stat64)); 3422 /* ??? put_user is probably wrong. */ 3423 put_user(st.st_dev, &target_st->st_dev); 3424 put_user(st.st_ino, &target_st->st_ino); 3425 #ifdef TARGET_STAT64_HAS_BROKEN_ST_INO 3426 put_user(st.st_ino, &target_st->__st_ino); 3427 #endif 3428 put_user(st.st_mode, &target_st->st_mode); 3429 put_user(st.st_nlink, &target_st->st_nlink); 3430 put_user(st.st_uid, &target_st->st_uid); 3431 put_user(st.st_gid, &target_st->st_gid); 3432 put_user(st.st_rdev, &target_st->st_rdev); 3433 /* XXX: better use of kernel struct */ 3434 put_user(st.st_size, &target_st->st_size); 3435 put_user(st.st_blksize, &target_st->st_blksize); 3436 put_user(st.st_blocks, &target_st->st_blocks); 3437 put_user(st.st_atime, &target_st->target_st_atime); 3438 put_user(st.st_mtime, &target_st->target_st_mtime); 3439 put_user(st.st_ctime, &target_st->target_st_ctime); 3440 unlock_user_struct(target_st, arg2, 0); 3441 } 3442 } 3443 } 3444 break; 3445 #endif 3446 #ifdef USE_UID16 3447 case TARGET_NR_lchown: 3448 p = lock_user_string(arg1); 3449 ret = get_errno(lchown(p, low2highuid(arg2), low2highgid(arg3))); 3450 unlock_user(p, arg1, 0); 3451 break; 3452 case TARGET_NR_getuid: 3453 ret = get_errno(high2lowuid(getuid())); 3454 break; 3455 case TARGET_NR_getgid: 3456 ret = get_errno(high2lowgid(getgid())); 3457 break; 3458 case TARGET_NR_geteuid: 3459 ret = get_errno(high2lowuid(geteuid())); 3460 break; 3461 case TARGET_NR_getegid: 3462 ret = get_errno(high2lowgid(getegid())); 3463 break; 3464 case TARGET_NR_setreuid: 3465 ret = get_errno(setreuid(low2highuid(arg1), low2highuid(arg2))); 3466 break; 3467 case TARGET_NR_setregid: 3468 ret = get_errno(setregid(low2highgid(arg1), low2highgid(arg2))); 3469 break; 3470 case TARGET_NR_getgroups: 3471 { 3472 int gidsetsize = arg1; 3473 uint16_t *target_grouplist; 3474 gid_t *grouplist; 3475 int i; 3476 3477 grouplist = alloca(gidsetsize * sizeof(gid_t)); 3478 ret = get_errno(getgroups(gidsetsize, grouplist)); 3479 if (!is_error(ret)) { 3480 target_grouplist = lock_user(arg2, gidsetsize * 2, 0); 3481 for(i = 0;i < gidsetsize; i++) 3482 target_grouplist[i] = tswap16(grouplist[i]); 3483 unlock_user(target_grouplist, arg2, gidsetsize * 2); 3484 } 3485 } 3486 break; 3487 case TARGET_NR_setgroups: 3488 { 3489 int gidsetsize = arg1; 3490 uint16_t *target_grouplist; 3491 gid_t *grouplist; 3492 int i; 3493 3494 grouplist = alloca(gidsetsize * sizeof(gid_t)); 3495 target_grouplist = lock_user(arg2, gidsetsize * 2, 1); 3496 for(i = 0;i < gidsetsize; i++) 3497 grouplist[i] = tswap16(target_grouplist[i]); 3498 unlock_user(target_grouplist, arg2, 0); 3499 ret = get_errno(setgroups(gidsetsize, grouplist)); 3500 } 3501 break; 3502 case TARGET_NR_fchown: 3503 ret = get_errno(fchown(arg1, low2highuid(arg2), low2highgid(arg3))); 3504 break; 3505 #ifdef TARGET_NR_setresuid 3506 case TARGET_NR_setresuid: 3507 ret = get_errno(setresuid(low2highuid(arg1), 3508 low2highuid(arg2), 3509 low2highuid(arg3))); 3510 break; 3511 #endif 3512 #ifdef TARGET_NR_getresuid 3513 case TARGET_NR_getresuid: 3514 { 3515 uid_t ruid, euid, suid; 3516 ret = get_errno(getresuid(&ruid, &euid, &suid)); 3517 if (!is_error(ret)) { 3518 tput16(arg1, tswap16(high2lowuid(ruid))); 3519 tput16(arg2, tswap16(high2lowuid(euid))); 3520 tput16(arg3, tswap16(high2lowuid(suid))); 3521 } 3522 } 3523 break; 3524 #endif 3525 #ifdef TARGET_NR_getresgid 3526 case TARGET_NR_setresgid: 3527 ret = get_errno(setresgid(low2highgid(arg1), 3528 low2highgid(arg2), 3529 low2highgid(arg3))); 3530 break; 3531 #endif 3532 #ifdef TARGET_NR_getresgid 3533 case TARGET_NR_getresgid: 3534 { 3535 gid_t rgid, egid, sgid; 3536 ret = get_errno(getresgid(&rgid, &egid, &sgid)); 3537 if (!is_error(ret)) { 3538 tput16(arg1, tswap16(high2lowgid(rgid))); 3539 tput16(arg2, tswap16(high2lowgid(egid))); 3540 tput16(arg3, tswap16(high2lowgid(sgid))); 3541 } 3542 } 3543 break; 3544 #endif 3545 case TARGET_NR_chown: 3546 p = lock_user_string(arg1); 3547 ret = get_errno(chown(p, low2highuid(arg2), low2highgid(arg3))); 3548 unlock_user(p, arg1, 0); 3549 break; 3550 case TARGET_NR_setuid: 3551 ret = get_errno(setuid(low2highuid(arg1))); 3552 break; 3553 case TARGET_NR_setgid: 3554 ret = get_errno(setgid(low2highgid(arg1))); 3555 break; 3556 case TARGET_NR_setfsuid: 3557 ret = get_errno(setfsuid(arg1)); 3558 break; 3559 case TARGET_NR_setfsgid: 3560 ret = get_errno(setfsgid(arg1)); 3561 break; 3562 #endif /* USE_UID16 */ 3563 3564 #ifdef TARGET_NR_lchown32 3565 case TARGET_NR_lchown32: 3566 p = lock_user_string(arg1); 3567 ret = get_errno(lchown(p, arg2, arg3)); 3568 unlock_user(p, arg1, 0); 3569 break; 3570 #endif 3571 #ifdef TARGET_NR_getuid32 3572 case TARGET_NR_getuid32: 3573 ret = get_errno(getuid()); 3574 break; 3575 #endif 3576 #ifdef TARGET_NR_getgid32 3577 case TARGET_NR_getgid32: 3578 ret = get_errno(getgid()); 3579 break; 3580 #endif 3581 #ifdef TARGET_NR_geteuid32 3582 case TARGET_NR_geteuid32: 3583 ret = get_errno(geteuid()); 3584 break; 3585 #endif 3586 #ifdef TARGET_NR_getegid32 3587 case TARGET_NR_getegid32: 3588 ret = get_errno(getegid()); 3589 break; 3590 #endif 3591 #ifdef TARGET_NR_setreuid32 3592 case TARGET_NR_setreuid32: 3593 ret = get_errno(setreuid(arg1, arg2)); 3594 break; 3595 #endif 3596 #ifdef TARGET_NR_setregid32 3597 case TARGET_NR_setregid32: 3598 ret = get_errno(setregid(arg1, arg2)); 3599 break; 3600 #endif 3601 #ifdef TARGET_NR_getgroups32 3602 case TARGET_NR_getgroups32: 3603 { 3604 int gidsetsize = arg1; 3605 uint32_t *target_grouplist; 3606 gid_t *grouplist; 3607 int i; 3608 3609 grouplist = alloca(gidsetsize * sizeof(gid_t)); 3610 ret = get_errno(getgroups(gidsetsize, grouplist)); 3611 if (!is_error(ret)) { 3612 target_grouplist = lock_user(arg2, gidsetsize * 4, 0); 3613 for(i = 0;i < gidsetsize; i++) 3614 target_grouplist[i] = tswap32(grouplist[i]); 3615 unlock_user(target_grouplist, arg2, gidsetsize * 4); 3616 } 3617 } 3618 break; 3619 #endif 3620 #ifdef TARGET_NR_setgroups32 3621 case TARGET_NR_setgroups32: 3622 { 3623 int gidsetsize = arg1; 3624 uint32_t *target_grouplist; 3625 gid_t *grouplist; 3626 int i; 3627 3628 grouplist = alloca(gidsetsize * sizeof(gid_t)); 3629 target_grouplist = lock_user(arg2, gidsetsize * 4, 1); 3630 for(i = 0;i < gidsetsize; i++) 3631 grouplist[i] = tswap32(target_grouplist[i]); 3632 unlock_user(target_grouplist, arg2, 0); 3633 ret = get_errno(setgroups(gidsetsize, grouplist)); 3634 } 3635 break; 3636 #endif 3637 #ifdef TARGET_NR_fchown32 3638 case TARGET_NR_fchown32: 3639 ret = get_errno(fchown(arg1, arg2, arg3)); 3640 break; 3641 #endif 3642 #ifdef TARGET_NR_setresuid32 3643 case TARGET_NR_setresuid32: 3644 ret = get_errno(setresuid(arg1, arg2, arg3)); 3645 break; 3646 #endif 3647 #ifdef TARGET_NR_getresuid32 3648 case TARGET_NR_getresuid32: 3649 { 3650 uid_t ruid, euid, suid; 3651 ret = get_errno(getresuid(&ruid, &euid, &suid)); 3652 if (!is_error(ret)) { 3653 tput32(arg1, tswap32(ruid)); 3654 tput32(arg2, tswap32(euid)); 3655 tput32(arg3, tswap32(suid)); 3656 } 3657 } 3658 break; 3659 #endif 3660 #ifdef TARGET_NR_setresgid32 3661 case TARGET_NR_setresgid32: 3662 ret = get_errno(setresgid(arg1, arg2, arg3)); 3663 break; 3664 #endif 3665 #ifdef TARGET_NR_getresgid32 3666 case TARGET_NR_getresgid32: 3667 { 3668 gid_t rgid, egid, sgid; 3669 ret = get_errno(getresgid(&rgid, &egid, &sgid)); 3670 if (!is_error(ret)) { 3671 tput32(arg1, tswap32(rgid)); 3672 tput32(arg2, tswap32(egid)); 3673 tput32(arg3, tswap32(sgid)); 3674 } 3675 } 3676 break; 3677 #endif 3678 #ifdef TARGET_NR_chown32 3679 case TARGET_NR_chown32: 3680 p = lock_user_string(arg1); 3681 ret = get_errno(chown(p, arg2, arg3)); 3682 unlock_user(p, arg1, 0); 3683 break; 3684 #endif 3685 #ifdef TARGET_NR_setuid32 3686 case TARGET_NR_setuid32: 3687 ret = get_errno(setuid(arg1)); 3688 break; 3689 #endif 3690 #ifdef TARGET_NR_setgid32 3691 case TARGET_NR_setgid32: 3692 ret = get_errno(setgid(arg1)); 3693 break; 3694 #endif 3695 #ifdef TARGET_NR_setfsuid32 3696 case TARGET_NR_setfsuid32: 3697 ret = get_errno(setfsuid(arg1)); 3698 break; 3699 #endif 3700 #ifdef TARGET_NR_setfsgid32 3701 case TARGET_NR_setfsgid32: 3702 ret = get_errno(setfsgid(arg1)); 3703 break; 3704 #endif 3705 3706 case TARGET_NR_pivot_root: 3707 goto unimplemented; 3708 #ifdef TARGET_NR_mincore 3709 case TARGET_NR_mincore: 3710 goto unimplemented; 3711 #endif 3712 #ifdef TARGET_NR_madvise 3713 case TARGET_NR_madvise: 3714 /* A straight passthrough may not be safe because qemu sometimes 3715 turns private flie-backed mappings into anonymous mappings. 3716 This will break MADV_DONTNEED. 3717 This is a hint, so ignoring and returning success is ok. */ 3718 ret = get_errno(0); 3719 break; 3720 #endif 3721 #if TARGET_LONG_BITS == 32 3722 case TARGET_NR_fcntl64: 3723 { 3724 struct flock64 fl; 3725 struct target_flock64 *target_fl; 3726 #ifdef TARGET_ARM 3727 struct target_eabi_flock64 *target_efl; 3728 #endif 3729 3730 switch(arg2) { 3731 case F_GETLK64: 3732 ret = get_errno(fcntl(arg1, arg2, &fl)); 3733 if (ret == 0) { 3734 #ifdef TARGET_ARM 3735 if (((CPUARMState *)cpu_env)->eabi) { 3736 lock_user_struct(target_efl, arg3, 0); 3737 target_efl->l_type = tswap16(fl.l_type); 3738 target_efl->l_whence = tswap16(fl.l_whence); 3739 target_efl->l_start = tswap64(fl.l_start); 3740 target_efl->l_len = tswap64(fl.l_len); 3741 target_efl->l_pid = tswapl(fl.l_pid); 3742 unlock_user_struct(target_efl, arg3, 1); 3743 } else 3744 #endif 3745 { 3746 lock_user_struct(target_fl, arg3, 0); 3747 target_fl->l_type = tswap16(fl.l_type); 3748 target_fl->l_whence = tswap16(fl.l_whence); 3749 target_fl->l_start = tswap64(fl.l_start); 3750 target_fl->l_len = tswap64(fl.l_len); 3751 target_fl->l_pid = tswapl(fl.l_pid); 3752 unlock_user_struct(target_fl, arg3, 1); 3753 } 3754 } 3755 break; 3756 3757 case F_SETLK64: 3758 case F_SETLKW64: 3759 #ifdef TARGET_ARM 3760 if (((CPUARMState *)cpu_env)->eabi) { 3761 lock_user_struct(target_efl, arg3, 1); 3762 fl.l_type = tswap16(target_efl->l_type); 3763 fl.l_whence = tswap16(target_efl->l_whence); 3764 fl.l_start = tswap64(target_efl->l_start); 3765 fl.l_len = tswap64(target_efl->l_len); 3766 fl.l_pid = tswapl(target_efl->l_pid); 3767 unlock_user_struct(target_efl, arg3, 0); 3768 } else 3769 #endif 3770 { 3771 lock_user_struct(target_fl, arg3, 1); 3772 fl.l_type = tswap16(target_fl->l_type); 3773 fl.l_whence = tswap16(target_fl->l_whence); 3774 fl.l_start = tswap64(target_fl->l_start); 3775 fl.l_len = tswap64(target_fl->l_len); 3776 fl.l_pid = tswapl(target_fl->l_pid); 3777 unlock_user_struct(target_fl, arg3, 0); 3778 } 3779 ret = get_errno(fcntl(arg1, arg2, &fl)); 3780 break; 3781 default: 3782 ret = get_errno(do_fcntl(arg1, arg2, arg3)); 3783 break; 3784 } 3785 break; 3786 } 3787 #endif 3788 #ifdef TARGET_NR_security 3789 case TARGET_NR_security: 3790 goto unimplemented; 3791 #endif 3792 #ifdef TARGET_NR_getpagesize 3793 case TARGET_NR_getpagesize: 3794 ret = TARGET_PAGE_SIZE; 3795 break; 3796 #endif 3797 case TARGET_NR_gettid: 3798 ret = get_errno(gettid()); 3799 break; 3800 case TARGET_NR_readahead: 3801 goto unimplemented; 3802 #ifdef TARGET_NR_setxattr 3803 case TARGET_NR_setxattr: 3804 case TARGET_NR_lsetxattr: 3805 case TARGET_NR_fsetxattr: 3806 case TARGET_NR_getxattr: 3807 case TARGET_NR_lgetxattr: 3808 case TARGET_NR_fgetxattr: 3809 case TARGET_NR_listxattr: 3810 case TARGET_NR_llistxattr: 3811 case TARGET_NR_flistxattr: 3812 case TARGET_NR_removexattr: 3813 case TARGET_NR_lremovexattr: 3814 case TARGET_NR_fremovexattr: 3815 goto unimplemented_nowarn; 3816 #endif 3817 #ifdef TARGET_NR_set_thread_area 3818 case TARGET_NR_set_thread_area: 3819 case TARGET_NR_get_thread_area: 3820 goto unimplemented_nowarn; 3821 #endif 3822 #ifdef TARGET_NR_getdomainname 3823 case TARGET_NR_getdomainname: 3824 goto unimplemented_nowarn; 3825 #endif 3826 default: 3827 unimplemented: 3828 gemu_log("qemu: Unsupported syscall: %d\n", num); 3829 #if defined(TARGET_NR_setxattr) || defined(TARGET_NR_set_thread_area) || defined(TARGET_NR_getdomainname) 3830 unimplemented_nowarn: 3831 #endif 3832 ret = -ENOSYS; 3833 break; 3834 } 3835 fail: 3836 #ifdef DEBUG 3837 gemu_log(" = %ld\n", ret); 3838 #endif 3839 return ret; 3840 } 3841 3842