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