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