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