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