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