1 /* 2 * Linux syscalls 3 * 4 * Copyright (c) 2003 Fabrice Bellard 5 * 6 * This program is free software; you can redistribute it and/or modify 7 * it under the terms of the GNU General Public License as published by 8 * the Free Software Foundation; either version 2 of the License, or 9 * (at your option) any later version. 10 * 11 * This program is distributed in the hope that it will be useful, 12 * but WITHOUT ANY WARRANTY; without even the implied warranty of 13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 * GNU General Public License for more details. 15 * 16 * You should have received a copy of the GNU General Public License 17 * along with this program; if not, write to the Free Software 18 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. 19 */ 20 #include <stdlib.h> 21 #include <stdio.h> 22 #include <stdarg.h> 23 #include <string.h> 24 #include <elf.h> 25 #include <endian.h> 26 #include <errno.h> 27 #include <unistd.h> 28 #include <fcntl.h> 29 #include <time.h> 30 #include <sys/types.h> 31 #include <sys/ipc.h> 32 #include <sys/msg.h> 33 #include <sys/wait.h> 34 #include <sys/time.h> 35 #include <sys/stat.h> 36 #include <sys/mount.h> 37 #include <sys/prctl.h> 38 #include <sys/resource.h> 39 #include <sys/mman.h> 40 #include <sys/swap.h> 41 #include <signal.h> 42 #include <sched.h> 43 #include <sys/socket.h> 44 #include <sys/uio.h> 45 #include <sys/poll.h> 46 #include <sys/times.h> 47 #include <sys/shm.h> 48 #include <sys/sem.h> 49 #include <sys/statfs.h> 50 #include <utime.h> 51 #include <sys/sysinfo.h> 52 //#include <sys/user.h> 53 #include <netinet/ip.h> 54 #include <netinet/tcp.h> 55 56 #define termios host_termios 57 #define winsize host_winsize 58 #define termio host_termio 59 #define sgttyb host_sgttyb /* same as target */ 60 #define tchars host_tchars /* same as target */ 61 #define ltchars host_ltchars /* same as target */ 62 63 #include <linux/termios.h> 64 #include <linux/unistd.h> 65 #include <linux/utsname.h> 66 #include <linux/cdrom.h> 67 #include <linux/hdreg.h> 68 #include <linux/soundcard.h> 69 #include <linux/dirent.h> 70 #include <linux/kd.h> 71 72 #include "qemu.h" 73 74 //#define DEBUG 75 76 #if defined(TARGET_I386) || defined(TARGET_ARM) || defined(TARGET_SPARC) \ 77 || defined(TARGET_M68K) || defined(TARGET_SH4) 78 /* 16 bit uid wrappers emulation */ 79 #define USE_UID16 80 #endif 81 82 //#include <linux/msdos_fs.h> 83 #define VFAT_IOCTL_READDIR_BOTH _IOR('r', 1, struct dirent [2]) 84 #define VFAT_IOCTL_READDIR_SHORT _IOR('r', 2, struct dirent [2]) 85 86 87 #undef _syscall0 88 #undef _syscall1 89 #undef _syscall2 90 #undef _syscall3 91 #undef _syscall4 92 #undef _syscall5 93 #undef _syscall6 94 95 #define _syscall0(type,name) \ 96 type name (void) \ 97 { \ 98 return syscall(__NR_##name); \ 99 } 100 101 #define _syscall1(type,name,type1,arg1) \ 102 type name (type1 arg1) \ 103 { \ 104 return syscall(__NR_##name, arg1); \ 105 } 106 107 #define _syscall2(type,name,type1,arg1,type2,arg2) \ 108 type name (type1 arg1,type2 arg2) \ 109 { \ 110 return syscall(__NR_##name, arg1, arg2); \ 111 } 112 113 #define _syscall3(type,name,type1,arg1,type2,arg2,type3,arg3) \ 114 type name (type1 arg1,type2 arg2,type3 arg3) \ 115 { \ 116 return syscall(__NR_##name, arg1, arg2, arg3); \ 117 } 118 119 #define _syscall4(type,name,type1,arg1,type2,arg2,type3,arg3,type4,arg4) \ 120 type name (type1 arg1,type2 arg2,type3 arg3,type4 arg4) \ 121 { \ 122 return syscall(__NR_##name, arg1, arg2, arg3, arg4); \ 123 } 124 125 #define _syscall5(type,name,type1,arg1,type2,arg2,type3,arg3,type4,arg4, \ 126 type5,arg5) \ 127 type name (type1 arg1,type2 arg2,type3 arg3,type4 arg4,type5 arg5) \ 128 { \ 129 return syscall(__NR_##name, arg1, arg2, arg3, arg4, arg5); \ 130 } 131 132 133 #define _syscall6(type,name,type1,arg1,type2,arg2,type3,arg3,type4,arg4, \ 134 type5,arg5,type6,arg6) \ 135 type name (type1 arg1,type2 arg2,type3 arg3,type4 arg4,type5 arg5,type6 arg6) \ 136 { \ 137 return syscall(__NR_##name, arg1, arg2, arg3, arg4, arg5, arg6); \ 138 } 139 140 141 #define __NR_sys_uname __NR_uname 142 #define __NR_sys_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 #else 2290 #error unsupported target CPU 2291 #endif 2292 new_env->opaque = ts; 2293 #ifdef __ia64__ 2294 ret = __clone2(clone_func, new_stack + NEW_STACK_SIZE, flags, new_env); 2295 #else 2296 ret = clone(clone_func, new_stack + NEW_STACK_SIZE, flags, new_env); 2297 #endif 2298 } else { 2299 /* if no CLONE_VM, we consider it is a fork */ 2300 if ((flags & ~CSIGNAL) != 0) 2301 return -EINVAL; 2302 ret = fork(); 2303 } 2304 return ret; 2305 } 2306 2307 static target_long do_fcntl(int fd, int cmd, target_ulong arg) 2308 { 2309 struct flock fl; 2310 struct target_flock *target_fl; 2311 struct flock64 fl64; 2312 struct target_flock64 *target_fl64; 2313 target_long ret; 2314 2315 switch(cmd) { 2316 case TARGET_F_GETLK: 2317 lock_user_struct(target_fl, arg, 1); 2318 fl.l_type = tswap16(target_fl->l_type); 2319 fl.l_whence = tswap16(target_fl->l_whence); 2320 fl.l_start = tswapl(target_fl->l_start); 2321 fl.l_len = tswapl(target_fl->l_len); 2322 fl.l_pid = tswapl(target_fl->l_pid); 2323 unlock_user_struct(target_fl, arg, 0); 2324 ret = fcntl(fd, cmd, &fl); 2325 if (ret == 0) { 2326 lock_user_struct(target_fl, arg, 0); 2327 target_fl->l_type = tswap16(fl.l_type); 2328 target_fl->l_whence = tswap16(fl.l_whence); 2329 target_fl->l_start = tswapl(fl.l_start); 2330 target_fl->l_len = tswapl(fl.l_len); 2331 target_fl->l_pid = tswapl(fl.l_pid); 2332 unlock_user_struct(target_fl, arg, 1); 2333 } 2334 break; 2335 2336 case TARGET_F_SETLK: 2337 case TARGET_F_SETLKW: 2338 lock_user_struct(target_fl, arg, 1); 2339 fl.l_type = tswap16(target_fl->l_type); 2340 fl.l_whence = tswap16(target_fl->l_whence); 2341 fl.l_start = tswapl(target_fl->l_start); 2342 fl.l_len = tswapl(target_fl->l_len); 2343 fl.l_pid = tswapl(target_fl->l_pid); 2344 unlock_user_struct(target_fl, arg, 0); 2345 ret = fcntl(fd, cmd, &fl); 2346 break; 2347 2348 case TARGET_F_GETLK64: 2349 lock_user_struct(target_fl64, arg, 1); 2350 fl64.l_type = tswap16(target_fl64->l_type) >> 1; 2351 fl64.l_whence = tswap16(target_fl64->l_whence); 2352 fl64.l_start = tswapl(target_fl64->l_start); 2353 fl64.l_len = tswapl(target_fl64->l_len); 2354 fl64.l_pid = tswap16(target_fl64->l_pid); 2355 unlock_user_struct(target_fl64, arg, 0); 2356 ret = fcntl(fd, cmd >> 1, &fl64); 2357 if (ret == 0) { 2358 lock_user_struct(target_fl64, arg, 0); 2359 target_fl64->l_type = tswap16(fl64.l_type) >> 1; 2360 target_fl64->l_whence = tswap16(fl64.l_whence); 2361 target_fl64->l_start = tswapl(fl64.l_start); 2362 target_fl64->l_len = tswapl(fl64.l_len); 2363 target_fl64->l_pid = tswapl(fl64.l_pid); 2364 unlock_user_struct(target_fl64, arg, 1); 2365 } 2366 break; 2367 case TARGET_F_SETLK64: 2368 case TARGET_F_SETLKW64: 2369 lock_user_struct(target_fl64, arg, 1); 2370 fl64.l_type = tswap16(target_fl64->l_type) >> 1; 2371 fl64.l_whence = tswap16(target_fl64->l_whence); 2372 fl64.l_start = tswapl(target_fl64->l_start); 2373 fl64.l_len = tswapl(target_fl64->l_len); 2374 fl64.l_pid = tswap16(target_fl64->l_pid); 2375 unlock_user_struct(target_fl64, arg, 0); 2376 ret = fcntl(fd, cmd >> 1, &fl64); 2377 break; 2378 2379 case F_GETFL: 2380 ret = fcntl(fd, cmd, arg); 2381 ret = host_to_target_bitmask(ret, fcntl_flags_tbl); 2382 break; 2383 2384 case F_SETFL: 2385 ret = fcntl(fd, cmd, target_to_host_bitmask(arg, fcntl_flags_tbl)); 2386 break; 2387 2388 default: 2389 ret = fcntl(fd, cmd, arg); 2390 break; 2391 } 2392 return ret; 2393 } 2394 2395 #ifdef USE_UID16 2396 2397 static inline int high2lowuid(int uid) 2398 { 2399 if (uid > 65535) 2400 return 65534; 2401 else 2402 return uid; 2403 } 2404 2405 static inline int high2lowgid(int gid) 2406 { 2407 if (gid > 65535) 2408 return 65534; 2409 else 2410 return gid; 2411 } 2412 2413 static inline int low2highuid(int uid) 2414 { 2415 if ((int16_t)uid == -1) 2416 return -1; 2417 else 2418 return uid; 2419 } 2420 2421 static inline int low2highgid(int gid) 2422 { 2423 if ((int16_t)gid == -1) 2424 return -1; 2425 else 2426 return gid; 2427 } 2428 2429 #endif /* USE_UID16 */ 2430 2431 void syscall_init(void) 2432 { 2433 IOCTLEntry *ie; 2434 const argtype *arg_type; 2435 int size; 2436 2437 #define STRUCT(name, list...) thunk_register_struct(STRUCT_ ## name, #name, struct_ ## name ## _def); 2438 #define STRUCT_SPECIAL(name) thunk_register_struct_direct(STRUCT_ ## name, #name, &struct_ ## name ## _def); 2439 #include "syscall_types.h" 2440 #undef STRUCT 2441 #undef STRUCT_SPECIAL 2442 2443 /* we patch the ioctl size if necessary. We rely on the fact that 2444 no ioctl has all the bits at '1' in the size field */ 2445 ie = ioctl_entries; 2446 while (ie->target_cmd != 0) { 2447 if (((ie->target_cmd >> TARGET_IOC_SIZESHIFT) & TARGET_IOC_SIZEMASK) == 2448 TARGET_IOC_SIZEMASK) { 2449 arg_type = ie->arg_type; 2450 if (arg_type[0] != TYPE_PTR) { 2451 fprintf(stderr, "cannot patch size for ioctl 0x%x\n", 2452 ie->target_cmd); 2453 exit(1); 2454 } 2455 arg_type++; 2456 size = thunk_type_size(arg_type, 0); 2457 ie->target_cmd = (ie->target_cmd & 2458 ~(TARGET_IOC_SIZEMASK << TARGET_IOC_SIZESHIFT)) | 2459 (size << TARGET_IOC_SIZESHIFT); 2460 } 2461 /* automatic consistency check if same arch */ 2462 #if defined(__i386__) && defined(TARGET_I386) 2463 if (ie->target_cmd != ie->host_cmd) { 2464 fprintf(stderr, "ERROR: ioctl: target=0x%x host=0x%x\n", 2465 ie->target_cmd, ie->host_cmd); 2466 } 2467 #endif 2468 ie++; 2469 } 2470 } 2471 2472 #if TARGET_LONG_BITS == 32 2473 static inline uint64_t target_offset64(uint32_t word0, uint32_t word1) 2474 { 2475 #ifdef TARGET_WORDS_BIG_ENDIAN 2476 return ((uint64_t)word0 << 32) | word1; 2477 #else 2478 return ((uint64_t)word1 << 32) | word0; 2479 #endif 2480 } 2481 #else /* TARGET_LONG_BITS == 32 */ 2482 static inline uint64_t target_offset64(uint64_t word0, uint64_t word1) 2483 { 2484 return word0; 2485 } 2486 #endif /* TARGET_LONG_BITS != 32 */ 2487 2488 #ifdef TARGET_NR_truncate64 2489 static inline target_long target_truncate64(void *cpu_env, const char *arg1, 2490 target_long arg2, 2491 target_long arg3, 2492 target_long arg4) 2493 { 2494 #ifdef TARGET_ARM 2495 if (((CPUARMState *)cpu_env)->eabi) 2496 { 2497 arg2 = arg3; 2498 arg3 = arg4; 2499 } 2500 #endif 2501 return get_errno(truncate64(arg1, target_offset64(arg2, arg3))); 2502 } 2503 #endif 2504 2505 #ifdef TARGET_NR_ftruncate64 2506 static inline target_long target_ftruncate64(void *cpu_env, target_long arg1, 2507 target_long arg2, 2508 target_long arg3, 2509 target_long arg4) 2510 { 2511 #ifdef TARGET_ARM 2512 if (((CPUARMState *)cpu_env)->eabi) 2513 { 2514 arg2 = arg3; 2515 arg3 = arg4; 2516 } 2517 #endif 2518 return get_errno(ftruncate64(arg1, target_offset64(arg2, arg3))); 2519 } 2520 #endif 2521 2522 static inline void target_to_host_timespec(struct timespec *host_ts, 2523 target_ulong target_addr) 2524 { 2525 struct target_timespec *target_ts; 2526 2527 lock_user_struct(target_ts, target_addr, 1); 2528 host_ts->tv_sec = tswapl(target_ts->tv_sec); 2529 host_ts->tv_nsec = tswapl(target_ts->tv_nsec); 2530 unlock_user_struct(target_ts, target_addr, 0); 2531 } 2532 2533 static inline void host_to_target_timespec(target_ulong target_addr, 2534 struct timespec *host_ts) 2535 { 2536 struct target_timespec *target_ts; 2537 2538 lock_user_struct(target_ts, target_addr, 0); 2539 target_ts->tv_sec = tswapl(host_ts->tv_sec); 2540 target_ts->tv_nsec = tswapl(host_ts->tv_nsec); 2541 unlock_user_struct(target_ts, target_addr, 1); 2542 } 2543 2544 target_long do_syscall(void *cpu_env, int num, target_long arg1, 2545 target_long arg2, target_long arg3, target_long arg4, 2546 target_long arg5, target_long arg6) 2547 { 2548 target_long ret; 2549 struct stat st; 2550 struct statfs stfs; 2551 void *p; 2552 2553 #ifdef DEBUG 2554 gemu_log("syscall %d", num); 2555 #endif 2556 switch(num) { 2557 case TARGET_NR_exit: 2558 #ifdef HAVE_GPROF 2559 _mcleanup(); 2560 #endif 2561 gdb_exit(cpu_env, arg1); 2562 /* XXX: should free thread stack and CPU env */ 2563 _exit(arg1); 2564 ret = 0; /* avoid warning */ 2565 break; 2566 case TARGET_NR_read: 2567 page_unprotect_range(arg2, arg3); 2568 p = lock_user(arg2, arg3, 0); 2569 ret = get_errno(read(arg1, p, arg3)); 2570 unlock_user(p, arg2, ret); 2571 break; 2572 case TARGET_NR_write: 2573 p = lock_user(arg2, arg3, 1); 2574 ret = get_errno(write(arg1, p, arg3)); 2575 unlock_user(p, arg2, 0); 2576 break; 2577 case TARGET_NR_open: 2578 p = lock_user_string(arg1); 2579 ret = get_errno(open(path(p), 2580 target_to_host_bitmask(arg2, fcntl_flags_tbl), 2581 arg3)); 2582 unlock_user(p, arg1, 0); 2583 break; 2584 #if defined(TARGET_NR_openat) && defined(__NR_openat) 2585 case TARGET_NR_openat: 2586 if (!arg2) { 2587 ret = -EFAULT; 2588 goto fail; 2589 } 2590 p = lock_user_string(arg2); 2591 if (!access_ok(VERIFY_READ, p, 1)) 2592 ret = -EFAULT; 2593 else 2594 ret = get_errno(sys_openat(arg1, 2595 path(p), 2596 target_to_host_bitmask(arg3, fcntl_flags_tbl), 2597 arg4)); 2598 if (p) 2599 unlock_user(p, arg2, 0); 2600 break; 2601 #endif 2602 case TARGET_NR_close: 2603 ret = get_errno(close(arg1)); 2604 break; 2605 case TARGET_NR_brk: 2606 ret = do_brk(arg1); 2607 break; 2608 case TARGET_NR_fork: 2609 ret = get_errno(do_fork(cpu_env, SIGCHLD, 0)); 2610 break; 2611 #ifdef TARGET_NR_waitpid 2612 case TARGET_NR_waitpid: 2613 { 2614 int status; 2615 ret = get_errno(waitpid(arg1, &status, arg3)); 2616 if (!is_error(ret) && arg2) 2617 tput32(arg2, status); 2618 } 2619 break; 2620 #endif 2621 #ifdef TARGET_NR_creat /* not on alpha */ 2622 case TARGET_NR_creat: 2623 p = lock_user_string(arg1); 2624 ret = get_errno(creat(p, arg2)); 2625 unlock_user(p, arg1, 0); 2626 break; 2627 #endif 2628 case TARGET_NR_link: 2629 { 2630 void * p2; 2631 p = lock_user_string(arg1); 2632 p2 = lock_user_string(arg2); 2633 ret = get_errno(link(p, p2)); 2634 unlock_user(p2, arg2, 0); 2635 unlock_user(p, arg1, 0); 2636 } 2637 break; 2638 #if defined(TARGET_NR_linkat) && defined(__NR_linkat) 2639 case TARGET_NR_linkat: 2640 if (!arg2 || !arg4) { 2641 ret = -EFAULT; 2642 goto fail; 2643 } 2644 { 2645 void * p2 = NULL; 2646 p = lock_user_string(arg2); 2647 p2 = lock_user_string(arg4); 2648 if (!access_ok(VERIFY_READ, p, 1) 2649 || !access_ok(VERIFY_READ, p2, 1)) 2650 ret = -EFAULT; 2651 else 2652 ret = get_errno(sys_linkat(arg1, p, arg3, p2, arg5)); 2653 if (p2) 2654 unlock_user(p, arg2, 0); 2655 if (p) 2656 unlock_user(p2, arg4, 0); 2657 } 2658 break; 2659 #endif 2660 case TARGET_NR_unlink: 2661 p = lock_user_string(arg1); 2662 ret = get_errno(unlink(p)); 2663 unlock_user(p, arg1, 0); 2664 break; 2665 #if defined(TARGET_NR_unlinkat) && defined(__NR_unlinkat) 2666 case TARGET_NR_unlinkat: 2667 if (!arg2) { 2668 ret = -EFAULT; 2669 goto fail; 2670 } 2671 p = lock_user_string(arg2); 2672 if (!access_ok(VERIFY_READ, p, 1)) 2673 ret = -EFAULT; 2674 else 2675 ret = get_errno(sys_unlinkat(arg1, p, arg3)); 2676 if (p) 2677 unlock_user(p, arg2, 0); 2678 break; 2679 #endif 2680 case TARGET_NR_execve: 2681 { 2682 char **argp, **envp; 2683 int argc, envc; 2684 target_ulong gp; 2685 target_ulong guest_argp; 2686 target_ulong guest_envp; 2687 target_ulong addr; 2688 char **q; 2689 2690 argc = 0; 2691 guest_argp = arg2; 2692 for (gp = guest_argp; tgetl(gp); gp++) 2693 argc++; 2694 envc = 0; 2695 guest_envp = arg3; 2696 for (gp = guest_envp; tgetl(gp); gp++) 2697 envc++; 2698 2699 argp = alloca((argc + 1) * sizeof(void *)); 2700 envp = alloca((envc + 1) * sizeof(void *)); 2701 2702 for (gp = guest_argp, q = argp; ; 2703 gp += sizeof(target_ulong), q++) { 2704 addr = tgetl(gp); 2705 if (!addr) 2706 break; 2707 *q = lock_user_string(addr); 2708 } 2709 *q = NULL; 2710 2711 for (gp = guest_envp, q = envp; ; 2712 gp += sizeof(target_ulong), q++) { 2713 addr = tgetl(gp); 2714 if (!addr) 2715 break; 2716 *q = lock_user_string(addr); 2717 } 2718 *q = NULL; 2719 2720 p = lock_user_string(arg1); 2721 ret = get_errno(execve(p, argp, envp)); 2722 unlock_user(p, arg1, 0); 2723 2724 for (gp = guest_argp, q = argp; *q; 2725 gp += sizeof(target_ulong), q++) { 2726 addr = tgetl(gp); 2727 unlock_user(*q, addr, 0); 2728 } 2729 for (gp = guest_envp, q = envp; *q; 2730 gp += sizeof(target_ulong), q++) { 2731 addr = tgetl(gp); 2732 unlock_user(*q, addr, 0); 2733 } 2734 } 2735 break; 2736 case TARGET_NR_chdir: 2737 p = lock_user_string(arg1); 2738 ret = get_errno(chdir(p)); 2739 unlock_user(p, arg1, 0); 2740 break; 2741 #ifdef TARGET_NR_time 2742 case TARGET_NR_time: 2743 { 2744 time_t host_time; 2745 ret = get_errno(time(&host_time)); 2746 if (!is_error(ret) && arg1) 2747 tputl(arg1, host_time); 2748 } 2749 break; 2750 #endif 2751 case TARGET_NR_mknod: 2752 p = lock_user_string(arg1); 2753 ret = get_errno(mknod(p, arg2, arg3)); 2754 unlock_user(p, arg1, 0); 2755 break; 2756 #if defined(TARGET_NR_mknodat) && defined(__NR_mknodat) 2757 case TARGET_NR_mknodat: 2758 if (!arg2) { 2759 ret = -EFAULT; 2760 goto fail; 2761 } 2762 p = lock_user_string(arg2); 2763 if (!access_ok(VERIFY_READ, p, 1)) 2764 ret = -EFAULT; 2765 else 2766 ret = get_errno(sys_mknodat(arg1, p, arg3, arg4)); 2767 if (p) 2768 unlock_user(p, arg2, 0); 2769 break; 2770 #endif 2771 case TARGET_NR_chmod: 2772 p = lock_user_string(arg1); 2773 ret = get_errno(chmod(p, arg2)); 2774 unlock_user(p, arg1, 0); 2775 break; 2776 #ifdef TARGET_NR_break 2777 case TARGET_NR_break: 2778 goto unimplemented; 2779 #endif 2780 #ifdef TARGET_NR_oldstat 2781 case TARGET_NR_oldstat: 2782 goto unimplemented; 2783 #endif 2784 case TARGET_NR_lseek: 2785 ret = get_errno(lseek(arg1, arg2, arg3)); 2786 break; 2787 #ifdef TARGET_NR_getxpid 2788 case TARGET_NR_getxpid: 2789 #else 2790 case TARGET_NR_getpid: 2791 #endif 2792 ret = get_errno(getpid()); 2793 break; 2794 case TARGET_NR_mount: 2795 { 2796 /* need to look at the data field */ 2797 void *p2, *p3; 2798 p = lock_user_string(arg1); 2799 p2 = lock_user_string(arg2); 2800 p3 = lock_user_string(arg3); 2801 ret = get_errno(mount(p, p2, p3, (unsigned long)arg4, (const void *)arg5)); 2802 unlock_user(p, arg1, 0); 2803 unlock_user(p2, arg2, 0); 2804 unlock_user(p3, arg3, 0); 2805 break; 2806 } 2807 #ifdef TARGET_NR_umount 2808 case TARGET_NR_umount: 2809 p = lock_user_string(arg1); 2810 ret = get_errno(umount(p)); 2811 unlock_user(p, arg1, 0); 2812 break; 2813 #endif 2814 #ifdef TARGET_NR_stime /* not on alpha */ 2815 case TARGET_NR_stime: 2816 { 2817 time_t host_time; 2818 host_time = tgetl(arg1); 2819 ret = get_errno(stime(&host_time)); 2820 } 2821 break; 2822 #endif 2823 case TARGET_NR_ptrace: 2824 goto unimplemented; 2825 #ifdef TARGET_NR_alarm /* not on alpha */ 2826 case TARGET_NR_alarm: 2827 ret = alarm(arg1); 2828 break; 2829 #endif 2830 #ifdef TARGET_NR_oldfstat 2831 case TARGET_NR_oldfstat: 2832 goto unimplemented; 2833 #endif 2834 #ifdef TARGET_NR_pause /* not on alpha */ 2835 case TARGET_NR_pause: 2836 ret = get_errno(pause()); 2837 break; 2838 #endif 2839 #ifdef TARGET_NR_utime 2840 case TARGET_NR_utime: 2841 { 2842 struct utimbuf tbuf, *host_tbuf; 2843 struct target_utimbuf *target_tbuf; 2844 if (arg2) { 2845 lock_user_struct(target_tbuf, arg2, 1); 2846 tbuf.actime = tswapl(target_tbuf->actime); 2847 tbuf.modtime = tswapl(target_tbuf->modtime); 2848 unlock_user_struct(target_tbuf, arg2, 0); 2849 host_tbuf = &tbuf; 2850 } else { 2851 host_tbuf = NULL; 2852 } 2853 p = lock_user_string(arg1); 2854 ret = get_errno(utime(p, host_tbuf)); 2855 unlock_user(p, arg1, 0); 2856 } 2857 break; 2858 #endif 2859 case TARGET_NR_utimes: 2860 { 2861 struct timeval *tvp, tv[2]; 2862 if (arg2) { 2863 target_to_host_timeval(&tv[0], arg2); 2864 target_to_host_timeval(&tv[1], 2865 arg2 + sizeof (struct target_timeval)); 2866 tvp = tv; 2867 } else { 2868 tvp = NULL; 2869 } 2870 p = lock_user_string(arg1); 2871 ret = get_errno(utimes(p, tvp)); 2872 unlock_user(p, arg1, 0); 2873 } 2874 break; 2875 #ifdef TARGET_NR_stty 2876 case TARGET_NR_stty: 2877 goto unimplemented; 2878 #endif 2879 #ifdef TARGET_NR_gtty 2880 case TARGET_NR_gtty: 2881 goto unimplemented; 2882 #endif 2883 case TARGET_NR_access: 2884 p = lock_user_string(arg1); 2885 ret = get_errno(access(p, arg2)); 2886 unlock_user(p, arg1, 0); 2887 break; 2888 #if defined(TARGET_NR_faccessat) && defined(__NR_faccessat) 2889 case TARGET_NR_faccessat: 2890 if (!arg2) { 2891 ret = -EFAULT; 2892 goto fail; 2893 } 2894 p = lock_user_string(arg2); 2895 if (!access_ok(VERIFY_READ, p, 1)) 2896 ret = -EFAULT; 2897 else 2898 ret = get_errno(sys_faccessat(arg1, p, arg3, arg4)); 2899 if (p) 2900 unlock_user(p, arg2, 0); 2901 break; 2902 #endif 2903 #ifdef TARGET_NR_nice /* not on alpha */ 2904 case TARGET_NR_nice: 2905 ret = get_errno(nice(arg1)); 2906 break; 2907 #endif 2908 #ifdef TARGET_NR_ftime 2909 case TARGET_NR_ftime: 2910 goto unimplemented; 2911 #endif 2912 case TARGET_NR_sync: 2913 sync(); 2914 ret = 0; 2915 break; 2916 case TARGET_NR_kill: 2917 ret = get_errno(kill(arg1, arg2)); 2918 break; 2919 case TARGET_NR_rename: 2920 { 2921 void *p2; 2922 p = lock_user_string(arg1); 2923 p2 = lock_user_string(arg2); 2924 ret = get_errno(rename(p, p2)); 2925 unlock_user(p2, arg2, 0); 2926 unlock_user(p, arg1, 0); 2927 } 2928 break; 2929 #if defined(TARGET_NR_renameat) && defined(__NR_renameat) 2930 case TARGET_NR_renameat: 2931 if (!arg2 || !arg4) { 2932 ret = -EFAULT; 2933 goto fail; 2934 } 2935 { 2936 void *p2 = NULL; 2937 p = lock_user_string(arg2); 2938 p2 = lock_user_string(arg4); 2939 if (!access_ok(VERIFY_READ, p, 1) 2940 || !access_ok(VERIFY_READ, p2, 1)) 2941 ret = -EFAULT; 2942 else 2943 ret = get_errno(sys_renameat(arg1, p, arg3, p2)); 2944 if (p2) 2945 unlock_user(p2, arg4, 0); 2946 if (p) 2947 unlock_user(p, arg2, 0); 2948 } 2949 break; 2950 #endif 2951 case TARGET_NR_mkdir: 2952 p = lock_user_string(arg1); 2953 ret = get_errno(mkdir(p, arg2)); 2954 unlock_user(p, arg1, 0); 2955 break; 2956 #if defined(TARGET_NR_mkdirat) && defined(__NR_mkdirat) 2957 case TARGET_NR_mkdirat: 2958 if (!arg2) { 2959 ret = -EFAULT; 2960 goto fail; 2961 } 2962 p = lock_user_string(arg2); 2963 if (!access_ok(VERIFY_READ, p, 1)) 2964 ret = -EFAULT; 2965 else 2966 ret = get_errno(sys_mkdirat(arg1, p, arg3)); 2967 if (p) 2968 unlock_user(p, arg2, 0); 2969 break; 2970 #endif 2971 case TARGET_NR_rmdir: 2972 p = lock_user_string(arg1); 2973 ret = get_errno(rmdir(p)); 2974 unlock_user(p, arg1, 0); 2975 break; 2976 case TARGET_NR_dup: 2977 ret = get_errno(dup(arg1)); 2978 break; 2979 case TARGET_NR_pipe: 2980 { 2981 int host_pipe[2]; 2982 ret = get_errno(pipe(host_pipe)); 2983 if (!is_error(ret)) { 2984 #if defined(TARGET_MIPS) 2985 CPUMIPSState *env = (CPUMIPSState*)cpu_env; 2986 env->gpr[3][env->current_tc] = host_pipe[1]; 2987 ret = host_pipe[0]; 2988 #else 2989 tput32(arg1, host_pipe[0]); 2990 tput32(arg1 + 4, host_pipe[1]); 2991 #endif 2992 } 2993 } 2994 break; 2995 case TARGET_NR_times: 2996 { 2997 struct target_tms *tmsp; 2998 struct tms tms; 2999 ret = get_errno(times(&tms)); 3000 if (arg1) { 3001 tmsp = lock_user(arg1, sizeof(struct target_tms), 0); 3002 tmsp->tms_utime = tswapl(host_to_target_clock_t(tms.tms_utime)); 3003 tmsp->tms_stime = tswapl(host_to_target_clock_t(tms.tms_stime)); 3004 tmsp->tms_cutime = tswapl(host_to_target_clock_t(tms.tms_cutime)); 3005 tmsp->tms_cstime = tswapl(host_to_target_clock_t(tms.tms_cstime)); 3006 } 3007 if (!is_error(ret)) 3008 ret = host_to_target_clock_t(ret); 3009 } 3010 break; 3011 #ifdef TARGET_NR_prof 3012 case TARGET_NR_prof: 3013 goto unimplemented; 3014 #endif 3015 #ifdef TARGET_NR_signal 3016 case TARGET_NR_signal: 3017 goto unimplemented; 3018 #endif 3019 case TARGET_NR_acct: 3020 p = lock_user_string(arg1); 3021 ret = get_errno(acct(path(p))); 3022 unlock_user(p, arg1, 0); 3023 break; 3024 #ifdef TARGET_NR_umount2 /* not on alpha */ 3025 case TARGET_NR_umount2: 3026 p = lock_user_string(arg1); 3027 ret = get_errno(umount2(p, arg2)); 3028 unlock_user(p, arg1, 0); 3029 break; 3030 #endif 3031 #ifdef TARGET_NR_lock 3032 case TARGET_NR_lock: 3033 goto unimplemented; 3034 #endif 3035 case TARGET_NR_ioctl: 3036 ret = do_ioctl(arg1, arg2, arg3); 3037 break; 3038 case TARGET_NR_fcntl: 3039 ret = get_errno(do_fcntl(arg1, arg2, arg3)); 3040 break; 3041 #ifdef TARGET_NR_mpx 3042 case TARGET_NR_mpx: 3043 goto unimplemented; 3044 #endif 3045 case TARGET_NR_setpgid: 3046 ret = get_errno(setpgid(arg1, arg2)); 3047 break; 3048 #ifdef TARGET_NR_ulimit 3049 case TARGET_NR_ulimit: 3050 goto unimplemented; 3051 #endif 3052 #ifdef TARGET_NR_oldolduname 3053 case TARGET_NR_oldolduname: 3054 goto unimplemented; 3055 #endif 3056 case TARGET_NR_umask: 3057 ret = get_errno(umask(arg1)); 3058 break; 3059 case TARGET_NR_chroot: 3060 p = lock_user_string(arg1); 3061 ret = get_errno(chroot(p)); 3062 unlock_user(p, arg1, 0); 3063 break; 3064 case TARGET_NR_ustat: 3065 goto unimplemented; 3066 case TARGET_NR_dup2: 3067 ret = get_errno(dup2(arg1, arg2)); 3068 break; 3069 #ifdef TARGET_NR_getppid /* not on alpha */ 3070 case TARGET_NR_getppid: 3071 ret = get_errno(getppid()); 3072 break; 3073 #endif 3074 case TARGET_NR_getpgrp: 3075 ret = get_errno(getpgrp()); 3076 break; 3077 case TARGET_NR_setsid: 3078 ret = get_errno(setsid()); 3079 break; 3080 #ifdef TARGET_NR_sigaction 3081 case TARGET_NR_sigaction: 3082 { 3083 #if !defined(TARGET_MIPS) 3084 struct target_old_sigaction *old_act; 3085 struct target_sigaction act, oact, *pact; 3086 if (arg2) { 3087 lock_user_struct(old_act, arg2, 1); 3088 act._sa_handler = old_act->_sa_handler; 3089 target_siginitset(&act.sa_mask, old_act->sa_mask); 3090 act.sa_flags = old_act->sa_flags; 3091 act.sa_restorer = old_act->sa_restorer; 3092 unlock_user_struct(old_act, arg2, 0); 3093 pact = &act; 3094 } else { 3095 pact = NULL; 3096 } 3097 ret = get_errno(do_sigaction(arg1, pact, &oact)); 3098 if (!is_error(ret) && arg3) { 3099 lock_user_struct(old_act, arg3, 0); 3100 old_act->_sa_handler = oact._sa_handler; 3101 old_act->sa_mask = oact.sa_mask.sig[0]; 3102 old_act->sa_flags = oact.sa_flags; 3103 old_act->sa_restorer = oact.sa_restorer; 3104 unlock_user_struct(old_act, arg3, 1); 3105 } 3106 #else 3107 struct target_sigaction act, oact, *pact, *old_act; 3108 3109 if (arg2) { 3110 lock_user_struct(old_act, arg2, 1); 3111 act._sa_handler = old_act->_sa_handler; 3112 target_siginitset(&act.sa_mask, old_act->sa_mask.sig[0]); 3113 act.sa_flags = old_act->sa_flags; 3114 unlock_user_struct(old_act, arg2, 0); 3115 pact = &act; 3116 } else { 3117 pact = NULL; 3118 } 3119 3120 ret = get_errno(do_sigaction(arg1, pact, &oact)); 3121 3122 if (!is_error(ret) && arg3) { 3123 lock_user_struct(old_act, arg3, 0); 3124 old_act->_sa_handler = oact._sa_handler; 3125 old_act->sa_flags = oact.sa_flags; 3126 old_act->sa_mask.sig[0] = oact.sa_mask.sig[0]; 3127 old_act->sa_mask.sig[1] = 0; 3128 old_act->sa_mask.sig[2] = 0; 3129 old_act->sa_mask.sig[3] = 0; 3130 unlock_user_struct(old_act, arg3, 1); 3131 } 3132 #endif 3133 } 3134 break; 3135 #endif 3136 case TARGET_NR_rt_sigaction: 3137 { 3138 struct target_sigaction *act; 3139 struct target_sigaction *oact; 3140 3141 if (arg2) 3142 lock_user_struct(act, arg2, 1); 3143 else 3144 act = NULL; 3145 if (arg3) 3146 lock_user_struct(oact, arg3, 0); 3147 else 3148 oact = NULL; 3149 ret = get_errno(do_sigaction(arg1, act, oact)); 3150 if (arg2) 3151 unlock_user_struct(act, arg2, 0); 3152 if (arg3) 3153 unlock_user_struct(oact, arg3, 1); 3154 } 3155 break; 3156 #ifdef TARGET_NR_sgetmask /* not on alpha */ 3157 case TARGET_NR_sgetmask: 3158 { 3159 sigset_t cur_set; 3160 target_ulong target_set; 3161 sigprocmask(0, NULL, &cur_set); 3162 host_to_target_old_sigset(&target_set, &cur_set); 3163 ret = target_set; 3164 } 3165 break; 3166 #endif 3167 #ifdef TARGET_NR_ssetmask /* not on alpha */ 3168 case TARGET_NR_ssetmask: 3169 { 3170 sigset_t set, oset, cur_set; 3171 target_ulong target_set = arg1; 3172 sigprocmask(0, NULL, &cur_set); 3173 target_to_host_old_sigset(&set, &target_set); 3174 sigorset(&set, &set, &cur_set); 3175 sigprocmask(SIG_SETMASK, &set, &oset); 3176 host_to_target_old_sigset(&target_set, &oset); 3177 ret = target_set; 3178 } 3179 break; 3180 #endif 3181 #ifdef TARGET_NR_sigprocmask 3182 case TARGET_NR_sigprocmask: 3183 { 3184 int how = arg1; 3185 sigset_t set, oldset, *set_ptr; 3186 3187 if (arg2) { 3188 switch(how) { 3189 case TARGET_SIG_BLOCK: 3190 how = SIG_BLOCK; 3191 break; 3192 case TARGET_SIG_UNBLOCK: 3193 how = SIG_UNBLOCK; 3194 break; 3195 case TARGET_SIG_SETMASK: 3196 how = SIG_SETMASK; 3197 break; 3198 default: 3199 ret = -EINVAL; 3200 goto fail; 3201 } 3202 p = lock_user(arg2, sizeof(target_sigset_t), 1); 3203 target_to_host_old_sigset(&set, p); 3204 unlock_user(p, arg2, 0); 3205 set_ptr = &set; 3206 } else { 3207 how = 0; 3208 set_ptr = NULL; 3209 } 3210 ret = get_errno(sigprocmask(arg1, set_ptr, &oldset)); 3211 if (!is_error(ret) && arg3) { 3212 p = lock_user(arg3, sizeof(target_sigset_t), 0); 3213 host_to_target_old_sigset(p, &oldset); 3214 unlock_user(p, arg3, sizeof(target_sigset_t)); 3215 } 3216 } 3217 break; 3218 #endif 3219 case TARGET_NR_rt_sigprocmask: 3220 { 3221 int how = arg1; 3222 sigset_t set, oldset, *set_ptr; 3223 3224 if (arg2) { 3225 switch(how) { 3226 case TARGET_SIG_BLOCK: 3227 how = SIG_BLOCK; 3228 break; 3229 case TARGET_SIG_UNBLOCK: 3230 how = SIG_UNBLOCK; 3231 break; 3232 case TARGET_SIG_SETMASK: 3233 how = SIG_SETMASK; 3234 break; 3235 default: 3236 ret = -EINVAL; 3237 goto fail; 3238 } 3239 p = lock_user(arg2, sizeof(target_sigset_t), 1); 3240 target_to_host_sigset(&set, p); 3241 unlock_user(p, arg2, 0); 3242 set_ptr = &set; 3243 } else { 3244 how = 0; 3245 set_ptr = NULL; 3246 } 3247 ret = get_errno(sigprocmask(how, set_ptr, &oldset)); 3248 if (!is_error(ret) && arg3) { 3249 p = lock_user(arg3, sizeof(target_sigset_t), 0); 3250 host_to_target_sigset(p, &oldset); 3251 unlock_user(p, arg3, sizeof(target_sigset_t)); 3252 } 3253 } 3254 break; 3255 #ifdef TARGET_NR_sigpending 3256 case TARGET_NR_sigpending: 3257 { 3258 sigset_t set; 3259 ret = get_errno(sigpending(&set)); 3260 if (!is_error(ret)) { 3261 p = lock_user(arg1, sizeof(target_sigset_t), 0); 3262 host_to_target_old_sigset(p, &set); 3263 unlock_user(p, arg1, sizeof(target_sigset_t)); 3264 } 3265 } 3266 break; 3267 #endif 3268 case TARGET_NR_rt_sigpending: 3269 { 3270 sigset_t set; 3271 ret = get_errno(sigpending(&set)); 3272 if (!is_error(ret)) { 3273 p = lock_user(arg1, sizeof(target_sigset_t), 0); 3274 host_to_target_sigset(p, &set); 3275 unlock_user(p, arg1, sizeof(target_sigset_t)); 3276 } 3277 } 3278 break; 3279 #ifdef TARGET_NR_sigsuspend 3280 case TARGET_NR_sigsuspend: 3281 { 3282 sigset_t set; 3283 p = lock_user(arg1, sizeof(target_sigset_t), 1); 3284 target_to_host_old_sigset(&set, p); 3285 unlock_user(p, arg1, 0); 3286 ret = get_errno(sigsuspend(&set)); 3287 } 3288 break; 3289 #endif 3290 case TARGET_NR_rt_sigsuspend: 3291 { 3292 sigset_t set; 3293 p = lock_user(arg1, sizeof(target_sigset_t), 1); 3294 target_to_host_sigset(&set, p); 3295 unlock_user(p, arg1, 0); 3296 ret = get_errno(sigsuspend(&set)); 3297 } 3298 break; 3299 case TARGET_NR_rt_sigtimedwait: 3300 { 3301 sigset_t set; 3302 struct timespec uts, *puts; 3303 siginfo_t uinfo; 3304 3305 p = lock_user(arg1, sizeof(target_sigset_t), 1); 3306 target_to_host_sigset(&set, p); 3307 unlock_user(p, arg1, 0); 3308 if (arg3) { 3309 puts = &uts; 3310 target_to_host_timespec(puts, arg3); 3311 } else { 3312 puts = NULL; 3313 } 3314 ret = get_errno(sigtimedwait(&set, &uinfo, puts)); 3315 if (!is_error(ret) && arg2) { 3316 p = lock_user(arg2, sizeof(target_sigset_t), 0); 3317 host_to_target_siginfo(p, &uinfo); 3318 unlock_user(p, arg2, sizeof(target_sigset_t)); 3319 } 3320 } 3321 break; 3322 case TARGET_NR_rt_sigqueueinfo: 3323 { 3324 siginfo_t uinfo; 3325 p = lock_user(arg3, sizeof(target_sigset_t), 1); 3326 target_to_host_siginfo(&uinfo, p); 3327 unlock_user(p, arg1, 0); 3328 ret = get_errno(sys_rt_sigqueueinfo(arg1, arg2, &uinfo)); 3329 } 3330 break; 3331 #ifdef TARGET_NR_sigreturn 3332 case TARGET_NR_sigreturn: 3333 /* NOTE: ret is eax, so not transcoding must be done */ 3334 ret = do_sigreturn(cpu_env); 3335 break; 3336 #endif 3337 case TARGET_NR_rt_sigreturn: 3338 /* NOTE: ret is eax, so not transcoding must be done */ 3339 ret = do_rt_sigreturn(cpu_env); 3340 break; 3341 case TARGET_NR_sethostname: 3342 p = lock_user_string(arg1); 3343 ret = get_errno(sethostname(p, arg2)); 3344 unlock_user(p, arg1, 0); 3345 break; 3346 case TARGET_NR_setrlimit: 3347 { 3348 /* XXX: convert resource ? */ 3349 int resource = arg1; 3350 struct target_rlimit *target_rlim; 3351 struct rlimit rlim; 3352 lock_user_struct(target_rlim, arg2, 1); 3353 rlim.rlim_cur = tswapl(target_rlim->rlim_cur); 3354 rlim.rlim_max = tswapl(target_rlim->rlim_max); 3355 unlock_user_struct(target_rlim, arg2, 0); 3356 ret = get_errno(setrlimit(resource, &rlim)); 3357 } 3358 break; 3359 case TARGET_NR_getrlimit: 3360 { 3361 /* XXX: convert resource ? */ 3362 int resource = arg1; 3363 struct target_rlimit *target_rlim; 3364 struct rlimit rlim; 3365 3366 ret = get_errno(getrlimit(resource, &rlim)); 3367 if (!is_error(ret)) { 3368 lock_user_struct(target_rlim, arg2, 0); 3369 rlim.rlim_cur = tswapl(target_rlim->rlim_cur); 3370 rlim.rlim_max = tswapl(target_rlim->rlim_max); 3371 unlock_user_struct(target_rlim, arg2, 1); 3372 } 3373 } 3374 break; 3375 case TARGET_NR_getrusage: 3376 { 3377 struct rusage rusage; 3378 ret = get_errno(getrusage(arg1, &rusage)); 3379 if (!is_error(ret)) { 3380 host_to_target_rusage(arg2, &rusage); 3381 } 3382 } 3383 break; 3384 case TARGET_NR_gettimeofday: 3385 { 3386 struct timeval tv; 3387 ret = get_errno(gettimeofday(&tv, NULL)); 3388 if (!is_error(ret)) { 3389 host_to_target_timeval(arg1, &tv); 3390 } 3391 } 3392 break; 3393 case TARGET_NR_settimeofday: 3394 { 3395 struct timeval tv; 3396 target_to_host_timeval(&tv, arg1); 3397 ret = get_errno(settimeofday(&tv, NULL)); 3398 } 3399 break; 3400 #ifdef TARGET_NR_select 3401 case TARGET_NR_select: 3402 { 3403 struct target_sel_arg_struct *sel; 3404 target_ulong inp, outp, exp, tvp; 3405 long nsel; 3406 3407 lock_user_struct(sel, arg1, 1); 3408 nsel = tswapl(sel->n); 3409 inp = tswapl(sel->inp); 3410 outp = tswapl(sel->outp); 3411 exp = tswapl(sel->exp); 3412 tvp = tswapl(sel->tvp); 3413 unlock_user_struct(sel, arg1, 0); 3414 ret = do_select(nsel, inp, outp, exp, tvp); 3415 } 3416 break; 3417 #endif 3418 case TARGET_NR_symlink: 3419 { 3420 void *p2; 3421 p = lock_user_string(arg1); 3422 p2 = lock_user_string(arg2); 3423 ret = get_errno(symlink(p, p2)); 3424 unlock_user(p2, arg2, 0); 3425 unlock_user(p, arg1, 0); 3426 } 3427 break; 3428 #if defined(TARGET_NR_symlinkat) && defined(__NR_symlinkat) 3429 case TARGET_NR_symlinkat: 3430 if (!arg1 || !arg3) { 3431 ret = -EFAULT; 3432 goto fail; 3433 } 3434 { 3435 void *p2 = NULL; 3436 p = lock_user_string(arg1); 3437 p2 = lock_user_string(arg3); 3438 if (!access_ok(VERIFY_READ, p, 1) 3439 || !access_ok(VERIFY_READ, p2, 1)) 3440 ret = -EFAULT; 3441 else 3442 ret = get_errno(sys_symlinkat(p, arg2, p2)); 3443 if (p2) 3444 unlock_user(p2, arg3, 0); 3445 if (p) 3446 unlock_user(p, arg1, 0); 3447 } 3448 break; 3449 #endif 3450 #ifdef TARGET_NR_oldlstat 3451 case TARGET_NR_oldlstat: 3452 goto unimplemented; 3453 #endif 3454 case TARGET_NR_readlink: 3455 { 3456 void *p2; 3457 p = lock_user_string(arg1); 3458 p2 = lock_user(arg2, arg3, 0); 3459 ret = get_errno(readlink(path(p), p2, arg3)); 3460 unlock_user(p2, arg2, ret); 3461 unlock_user(p, arg1, 0); 3462 } 3463 break; 3464 #if defined(TARGET_NR_readlinkat) && defined(__NR_readlinkat) 3465 case TARGET_NR_readlinkat: 3466 if (!arg2 || !arg3) { 3467 ret = -EFAULT; 3468 goto fail; 3469 } 3470 { 3471 void *p2 = NULL; 3472 p = lock_user_string(arg2); 3473 p2 = lock_user(arg3, arg4, 0); 3474 if (!access_ok(VERIFY_READ, p, 1) 3475 || !access_ok(VERIFY_READ, p2, 1)) 3476 ret = -EFAULT; 3477 else 3478 ret = get_errno(sys_readlinkat(arg1, path(p), p2, arg4)); 3479 if (p2) 3480 unlock_user(p2, arg3, ret); 3481 if (p) 3482 unlock_user(p, arg2, 0); 3483 } 3484 break; 3485 #endif 3486 #ifdef TARGET_NR_uselib 3487 case TARGET_NR_uselib: 3488 goto unimplemented; 3489 #endif 3490 #ifdef TARGET_NR_swapon 3491 case TARGET_NR_swapon: 3492 p = lock_user_string(arg1); 3493 ret = get_errno(swapon(p, arg2)); 3494 unlock_user(p, arg1, 0); 3495 break; 3496 #endif 3497 case TARGET_NR_reboot: 3498 goto unimplemented; 3499 #ifdef TARGET_NR_readdir 3500 case TARGET_NR_readdir: 3501 goto unimplemented; 3502 #endif 3503 #ifdef TARGET_NR_mmap 3504 case TARGET_NR_mmap: 3505 #if defined(TARGET_I386) || defined(TARGET_ARM) || defined(TARGET_M68K) 3506 { 3507 target_ulong *v; 3508 target_ulong v1, v2, v3, v4, v5, v6; 3509 v = lock_user(arg1, 6 * sizeof(target_ulong), 1); 3510 v1 = tswapl(v[0]); 3511 v2 = tswapl(v[1]); 3512 v3 = tswapl(v[2]); 3513 v4 = tswapl(v[3]); 3514 v5 = tswapl(v[4]); 3515 v6 = tswapl(v[5]); 3516 unlock_user(v, arg1, 0); 3517 ret = get_errno(target_mmap(v1, v2, v3, 3518 target_to_host_bitmask(v4, mmap_flags_tbl), 3519 v5, v6)); 3520 } 3521 #else 3522 ret = get_errno(target_mmap(arg1, arg2, arg3, 3523 target_to_host_bitmask(arg4, mmap_flags_tbl), 3524 arg5, 3525 arg6)); 3526 #endif 3527 break; 3528 #endif 3529 #ifdef TARGET_NR_mmap2 3530 case TARGET_NR_mmap2: 3531 #if defined(TARGET_SPARC) || defined(TARGET_MIPS) 3532 #define MMAP_SHIFT 12 3533 #else 3534 #define MMAP_SHIFT TARGET_PAGE_BITS 3535 #endif 3536 ret = get_errno(target_mmap(arg1, arg2, arg3, 3537 target_to_host_bitmask(arg4, mmap_flags_tbl), 3538 arg5, 3539 arg6 << MMAP_SHIFT)); 3540 break; 3541 #endif 3542 case TARGET_NR_munmap: 3543 ret = get_errno(target_munmap(arg1, arg2)); 3544 break; 3545 case TARGET_NR_mprotect: 3546 ret = get_errno(target_mprotect(arg1, arg2, arg3)); 3547 break; 3548 #ifdef TARGET_NR_mremap 3549 case TARGET_NR_mremap: 3550 ret = get_errno(target_mremap(arg1, arg2, arg3, arg4, arg5)); 3551 break; 3552 #endif 3553 /* ??? msync/mlock/munlock are broken for softmmu. */ 3554 #ifdef TARGET_NR_msync 3555 case TARGET_NR_msync: 3556 ret = get_errno(msync(g2h(arg1), arg2, arg3)); 3557 break; 3558 #endif 3559 #ifdef TARGET_NR_mlock 3560 case TARGET_NR_mlock: 3561 ret = get_errno(mlock(g2h(arg1), arg2)); 3562 break; 3563 #endif 3564 #ifdef TARGET_NR_munlock 3565 case TARGET_NR_munlock: 3566 ret = get_errno(munlock(g2h(arg1), arg2)); 3567 break; 3568 #endif 3569 #ifdef TARGET_NR_mlockall 3570 case TARGET_NR_mlockall: 3571 ret = get_errno(mlockall(arg1)); 3572 break; 3573 #endif 3574 #ifdef TARGET_NR_munlockall 3575 case TARGET_NR_munlockall: 3576 ret = get_errno(munlockall()); 3577 break; 3578 #endif 3579 case TARGET_NR_truncate: 3580 p = lock_user_string(arg1); 3581 ret = get_errno(truncate(p, arg2)); 3582 unlock_user(p, arg1, 0); 3583 break; 3584 case TARGET_NR_ftruncate: 3585 ret = get_errno(ftruncate(arg1, arg2)); 3586 break; 3587 case TARGET_NR_fchmod: 3588 ret = get_errno(fchmod(arg1, arg2)); 3589 break; 3590 #if defined(TARGET_NR_fchmodat) && defined(__NR_fchmodat) 3591 case TARGET_NR_fchmodat: 3592 if (!arg2) { 3593 ret = -EFAULT; 3594 goto fail; 3595 } 3596 p = lock_user_string(arg2); 3597 if (!access_ok(VERIFY_READ, p, 1)) 3598 ret = -EFAULT; 3599 else 3600 ret = get_errno(sys_fchmodat(arg1, p, arg3, arg4)); 3601 if (p) 3602 unlock_user(p, arg2, 0); 3603 break; 3604 #endif 3605 case TARGET_NR_getpriority: 3606 ret = get_errno(getpriority(arg1, arg2)); 3607 break; 3608 case TARGET_NR_setpriority: 3609 ret = get_errno(setpriority(arg1, arg2, arg3)); 3610 break; 3611 #ifdef TARGET_NR_profil 3612 case TARGET_NR_profil: 3613 goto unimplemented; 3614 #endif 3615 case TARGET_NR_statfs: 3616 p = lock_user_string(arg1); 3617 ret = get_errno(statfs(path(p), &stfs)); 3618 unlock_user(p, arg1, 0); 3619 convert_statfs: 3620 if (!is_error(ret)) { 3621 struct target_statfs *target_stfs; 3622 3623 lock_user_struct(target_stfs, arg2, 0); 3624 /* ??? put_user is probably wrong. */ 3625 put_user(stfs.f_type, &target_stfs->f_type); 3626 put_user(stfs.f_bsize, &target_stfs->f_bsize); 3627 put_user(stfs.f_blocks, &target_stfs->f_blocks); 3628 put_user(stfs.f_bfree, &target_stfs->f_bfree); 3629 put_user(stfs.f_bavail, &target_stfs->f_bavail); 3630 put_user(stfs.f_files, &target_stfs->f_files); 3631 put_user(stfs.f_ffree, &target_stfs->f_ffree); 3632 put_user(stfs.f_fsid.__val[0], &target_stfs->f_fsid.val[0]); 3633 put_user(stfs.f_fsid.__val[1], &target_stfs->f_fsid.val[1]); 3634 put_user(stfs.f_namelen, &target_stfs->f_namelen); 3635 unlock_user_struct(target_stfs, arg2, 1); 3636 } 3637 break; 3638 case TARGET_NR_fstatfs: 3639 ret = get_errno(fstatfs(arg1, &stfs)); 3640 goto convert_statfs; 3641 #ifdef TARGET_NR_statfs64 3642 case TARGET_NR_statfs64: 3643 p = lock_user_string(arg1); 3644 ret = get_errno(statfs(path(p), &stfs)); 3645 unlock_user(p, arg1, 0); 3646 convert_statfs64: 3647 if (!is_error(ret)) { 3648 struct target_statfs64 *target_stfs; 3649 3650 lock_user_struct(target_stfs, arg3, 0); 3651 /* ??? put_user is probably wrong. */ 3652 put_user(stfs.f_type, &target_stfs->f_type); 3653 put_user(stfs.f_bsize, &target_stfs->f_bsize); 3654 put_user(stfs.f_blocks, &target_stfs->f_blocks); 3655 put_user(stfs.f_bfree, &target_stfs->f_bfree); 3656 put_user(stfs.f_bavail, &target_stfs->f_bavail); 3657 put_user(stfs.f_files, &target_stfs->f_files); 3658 put_user(stfs.f_ffree, &target_stfs->f_ffree); 3659 put_user(stfs.f_fsid.__val[0], &target_stfs->f_fsid.val[0]); 3660 put_user(stfs.f_fsid.__val[1], &target_stfs->f_fsid.val[1]); 3661 put_user(stfs.f_namelen, &target_stfs->f_namelen); 3662 unlock_user_struct(target_stfs, arg3, 0); 3663 } 3664 break; 3665 case TARGET_NR_fstatfs64: 3666 ret = get_errno(fstatfs(arg1, &stfs)); 3667 goto convert_statfs64; 3668 #endif 3669 #ifdef TARGET_NR_ioperm 3670 case TARGET_NR_ioperm: 3671 goto unimplemented; 3672 #endif 3673 #ifdef TARGET_NR_socketcall 3674 case TARGET_NR_socketcall: 3675 ret = do_socketcall(arg1, arg2); 3676 break; 3677 #endif 3678 #ifdef TARGET_NR_accept 3679 case TARGET_NR_accept: 3680 ret = do_accept(arg1, arg2, arg3); 3681 break; 3682 #endif 3683 #ifdef TARGET_NR_bind 3684 case TARGET_NR_bind: 3685 ret = do_bind(arg1, arg2, arg3); 3686 break; 3687 #endif 3688 #ifdef TARGET_NR_connect 3689 case TARGET_NR_connect: 3690 ret = do_connect(arg1, arg2, arg3); 3691 break; 3692 #endif 3693 #ifdef TARGET_NR_getpeername 3694 case TARGET_NR_getpeername: 3695 ret = do_getpeername(arg1, arg2, arg3); 3696 break; 3697 #endif 3698 #ifdef TARGET_NR_getsockname 3699 case TARGET_NR_getsockname: 3700 ret = do_getsockname(arg1, arg2, arg3); 3701 break; 3702 #endif 3703 #ifdef TARGET_NR_getsockopt 3704 case TARGET_NR_getsockopt: 3705 ret = do_getsockopt(arg1, arg2, arg3, arg4, arg5); 3706 break; 3707 #endif 3708 #ifdef TARGET_NR_listen 3709 case TARGET_NR_listen: 3710 ret = get_errno(listen(arg1, arg2)); 3711 break; 3712 #endif 3713 #ifdef TARGET_NR_recv 3714 case TARGET_NR_recv: 3715 ret = do_recvfrom(arg1, arg2, arg3, arg4, 0, 0); 3716 break; 3717 #endif 3718 #ifdef TARGET_NR_recvfrom 3719 case TARGET_NR_recvfrom: 3720 ret = do_recvfrom(arg1, arg2, arg3, arg4, arg5, arg6); 3721 break; 3722 #endif 3723 #ifdef TARGET_NR_recvmsg 3724 case TARGET_NR_recvmsg: 3725 ret = do_sendrecvmsg(arg1, arg2, arg3, 0); 3726 break; 3727 #endif 3728 #ifdef TARGET_NR_send 3729 case TARGET_NR_send: 3730 ret = do_sendto(arg1, arg2, arg3, arg4, 0, 0); 3731 break; 3732 #endif 3733 #ifdef TARGET_NR_sendmsg 3734 case TARGET_NR_sendmsg: 3735 ret = do_sendrecvmsg(arg1, arg2, arg3, 1); 3736 break; 3737 #endif 3738 #ifdef TARGET_NR_sendto 3739 case TARGET_NR_sendto: 3740 ret = do_sendto(arg1, arg2, arg3, arg4, arg5, arg6); 3741 break; 3742 #endif 3743 #ifdef TARGET_NR_shutdown 3744 case TARGET_NR_shutdown: 3745 ret = get_errno(shutdown(arg1, arg2)); 3746 break; 3747 #endif 3748 #ifdef TARGET_NR_socket 3749 case TARGET_NR_socket: 3750 ret = do_socket(arg1, arg2, arg3); 3751 break; 3752 #endif 3753 #ifdef TARGET_NR_socketpair 3754 case TARGET_NR_socketpair: 3755 ret = do_socketpair(arg1, arg2, arg3, arg4); 3756 break; 3757 #endif 3758 #ifdef TARGET_NR_setsockopt 3759 case TARGET_NR_setsockopt: 3760 ret = do_setsockopt(arg1, arg2, arg3, arg4, (socklen_t) arg5); 3761 break; 3762 #endif 3763 3764 case TARGET_NR_syslog: 3765 p = lock_user_string(arg2); 3766 ret = get_errno(sys_syslog((int)arg1, p, (int)arg3)); 3767 unlock_user(p, arg2, 0); 3768 break; 3769 3770 case TARGET_NR_setitimer: 3771 { 3772 struct itimerval value, ovalue, *pvalue; 3773 3774 if (arg2) { 3775 pvalue = &value; 3776 target_to_host_timeval(&pvalue->it_interval, 3777 arg2); 3778 target_to_host_timeval(&pvalue->it_value, 3779 arg2 + sizeof(struct target_timeval)); 3780 } else { 3781 pvalue = NULL; 3782 } 3783 ret = get_errno(setitimer(arg1, pvalue, &ovalue)); 3784 if (!is_error(ret) && arg3) { 3785 host_to_target_timeval(arg3, 3786 &ovalue.it_interval); 3787 host_to_target_timeval(arg3 + sizeof(struct target_timeval), 3788 &ovalue.it_value); 3789 } 3790 } 3791 break; 3792 case TARGET_NR_getitimer: 3793 { 3794 struct itimerval value; 3795 3796 ret = get_errno(getitimer(arg1, &value)); 3797 if (!is_error(ret) && arg2) { 3798 host_to_target_timeval(arg2, 3799 &value.it_interval); 3800 host_to_target_timeval(arg2 + sizeof(struct target_timeval), 3801 &value.it_value); 3802 } 3803 } 3804 break; 3805 case TARGET_NR_stat: 3806 p = lock_user_string(arg1); 3807 ret = get_errno(stat(path(p), &st)); 3808 unlock_user(p, arg1, 0); 3809 goto do_stat; 3810 case TARGET_NR_lstat: 3811 p = lock_user_string(arg1); 3812 ret = get_errno(lstat(path(p), &st)); 3813 unlock_user(p, arg1, 0); 3814 goto do_stat; 3815 case TARGET_NR_fstat: 3816 { 3817 ret = get_errno(fstat(arg1, &st)); 3818 do_stat: 3819 if (!is_error(ret)) { 3820 struct target_stat *target_st; 3821 3822 lock_user_struct(target_st, arg2, 0); 3823 #if defined(TARGET_MIPS) || defined(TARGET_SPARC64) 3824 target_st->st_dev = tswap32(st.st_dev); 3825 #else 3826 target_st->st_dev = tswap16(st.st_dev); 3827 #endif 3828 target_st->st_ino = tswapl(st.st_ino); 3829 #if defined(TARGET_PPC) || defined(TARGET_MIPS) 3830 target_st->st_mode = tswapl(st.st_mode); /* XXX: check this */ 3831 target_st->st_uid = tswap32(st.st_uid); 3832 target_st->st_gid = tswap32(st.st_gid); 3833 #elif defined(TARGET_SPARC64) 3834 target_st->st_mode = tswap32(st.st_mode); 3835 target_st->st_uid = tswap32(st.st_uid); 3836 target_st->st_gid = tswap32(st.st_gid); 3837 #else 3838 target_st->st_mode = tswap16(st.st_mode); 3839 target_st->st_uid = tswap16(st.st_uid); 3840 target_st->st_gid = tswap16(st.st_gid); 3841 #endif 3842 #if defined(TARGET_MIPS) 3843 /* If this is the same on PPC, then just merge w/ the above ifdef */ 3844 target_st->st_nlink = tswapl(st.st_nlink); 3845 target_st->st_rdev = tswapl(st.st_rdev); 3846 #elif defined(TARGET_SPARC64) 3847 target_st->st_nlink = tswap32(st.st_nlink); 3848 target_st->st_rdev = tswap32(st.st_rdev); 3849 #else 3850 target_st->st_nlink = tswap16(st.st_nlink); 3851 target_st->st_rdev = tswap16(st.st_rdev); 3852 #endif 3853 target_st->st_size = tswapl(st.st_size); 3854 target_st->st_blksize = tswapl(st.st_blksize); 3855 target_st->st_blocks = tswapl(st.st_blocks); 3856 target_st->target_st_atime = tswapl(st.st_atime); 3857 target_st->target_st_mtime = tswapl(st.st_mtime); 3858 target_st->target_st_ctime = tswapl(st.st_ctime); 3859 unlock_user_struct(target_st, arg2, 1); 3860 } 3861 } 3862 break; 3863 #ifdef TARGET_NR_olduname 3864 case TARGET_NR_olduname: 3865 goto unimplemented; 3866 #endif 3867 #ifdef TARGET_NR_iopl 3868 case TARGET_NR_iopl: 3869 goto unimplemented; 3870 #endif 3871 case TARGET_NR_vhangup: 3872 ret = get_errno(vhangup()); 3873 break; 3874 #ifdef TARGET_NR_idle 3875 case TARGET_NR_idle: 3876 goto unimplemented; 3877 #endif 3878 #ifdef TARGET_NR_syscall 3879 case TARGET_NR_syscall: 3880 ret = do_syscall(cpu_env,arg1 & 0xffff,arg2,arg3,arg4,arg5,arg6,0); 3881 break; 3882 #endif 3883 case TARGET_NR_wait4: 3884 { 3885 int status; 3886 target_long status_ptr = arg2; 3887 struct rusage rusage, *rusage_ptr; 3888 target_ulong target_rusage = arg4; 3889 if (target_rusage) 3890 rusage_ptr = &rusage; 3891 else 3892 rusage_ptr = NULL; 3893 ret = get_errno(wait4(arg1, &status, arg3, rusage_ptr)); 3894 if (!is_error(ret)) { 3895 if (status_ptr) 3896 tputl(status_ptr, status); 3897 if (target_rusage) { 3898 host_to_target_rusage(target_rusage, &rusage); 3899 } 3900 } 3901 } 3902 break; 3903 #ifdef TARGET_NR_swapoff 3904 case TARGET_NR_swapoff: 3905 p = lock_user_string(arg1); 3906 ret = get_errno(swapoff(p)); 3907 unlock_user(p, arg1, 0); 3908 break; 3909 #endif 3910 case TARGET_NR_sysinfo: 3911 { 3912 struct target_sysinfo *target_value; 3913 struct sysinfo value; 3914 ret = get_errno(sysinfo(&value)); 3915 if (!is_error(ret) && arg1) 3916 { 3917 /* ??? __put_user is probably wrong. */ 3918 lock_user_struct(target_value, arg1, 0); 3919 __put_user(value.uptime, &target_value->uptime); 3920 __put_user(value.loads[0], &target_value->loads[0]); 3921 __put_user(value.loads[1], &target_value->loads[1]); 3922 __put_user(value.loads[2], &target_value->loads[2]); 3923 __put_user(value.totalram, &target_value->totalram); 3924 __put_user(value.freeram, &target_value->freeram); 3925 __put_user(value.sharedram, &target_value->sharedram); 3926 __put_user(value.bufferram, &target_value->bufferram); 3927 __put_user(value.totalswap, &target_value->totalswap); 3928 __put_user(value.freeswap, &target_value->freeswap); 3929 __put_user(value.procs, &target_value->procs); 3930 __put_user(value.totalhigh, &target_value->totalhigh); 3931 __put_user(value.freehigh, &target_value->freehigh); 3932 __put_user(value.mem_unit, &target_value->mem_unit); 3933 unlock_user_struct(target_value, arg1, 1); 3934 } 3935 } 3936 break; 3937 #ifdef TARGET_NR_ipc 3938 case TARGET_NR_ipc: 3939 ret = do_ipc(arg1, arg2, arg3, arg4, arg5, arg6); 3940 break; 3941 #endif 3942 case TARGET_NR_fsync: 3943 ret = get_errno(fsync(arg1)); 3944 break; 3945 case TARGET_NR_clone: 3946 ret = get_errno(do_fork(cpu_env, arg1, arg2)); 3947 break; 3948 #ifdef __NR_exit_group 3949 /* new thread calls */ 3950 case TARGET_NR_exit_group: 3951 gdb_exit(cpu_env, arg1); 3952 ret = get_errno(exit_group(arg1)); 3953 break; 3954 #endif 3955 case TARGET_NR_setdomainname: 3956 p = lock_user_string(arg1); 3957 ret = get_errno(setdomainname(p, arg2)); 3958 unlock_user(p, arg1, 0); 3959 break; 3960 case TARGET_NR_uname: 3961 /* no need to transcode because we use the linux syscall */ 3962 { 3963 struct new_utsname * buf; 3964 3965 lock_user_struct(buf, arg1, 0); 3966 ret = get_errno(sys_uname(buf)); 3967 if (!is_error(ret)) { 3968 /* Overrite the native machine name with whatever is being 3969 emulated. */ 3970 strcpy (buf->machine, UNAME_MACHINE); 3971 /* Allow the user to override the reported release. */ 3972 if (qemu_uname_release && *qemu_uname_release) 3973 strcpy (buf->release, qemu_uname_release); 3974 } 3975 unlock_user_struct(buf, arg1, 1); 3976 } 3977 break; 3978 #ifdef TARGET_I386 3979 case TARGET_NR_modify_ldt: 3980 ret = get_errno(do_modify_ldt(cpu_env, arg1, arg2, arg3)); 3981 break; 3982 #if !defined(TARGET_X86_64) 3983 case TARGET_NR_vm86old: 3984 goto unimplemented; 3985 case TARGET_NR_vm86: 3986 ret = do_vm86(cpu_env, arg1, arg2); 3987 break; 3988 #endif 3989 #endif 3990 case TARGET_NR_adjtimex: 3991 goto unimplemented; 3992 #ifdef TARGET_NR_create_module 3993 case TARGET_NR_create_module: 3994 #endif 3995 case TARGET_NR_init_module: 3996 case TARGET_NR_delete_module: 3997 #ifdef TARGET_NR_get_kernel_syms 3998 case TARGET_NR_get_kernel_syms: 3999 #endif 4000 goto unimplemented; 4001 case TARGET_NR_quotactl: 4002 goto unimplemented; 4003 case TARGET_NR_getpgid: 4004 ret = get_errno(getpgid(arg1)); 4005 break; 4006 case TARGET_NR_fchdir: 4007 ret = get_errno(fchdir(arg1)); 4008 break; 4009 #ifdef TARGET_NR_bdflush /* not on x86_64 */ 4010 case TARGET_NR_bdflush: 4011 goto unimplemented; 4012 #endif 4013 #ifdef TARGET_NR_sysfs 4014 case TARGET_NR_sysfs: 4015 goto unimplemented; 4016 #endif 4017 case TARGET_NR_personality: 4018 ret = get_errno(personality(arg1)); 4019 break; 4020 #ifdef TARGET_NR_afs_syscall 4021 case TARGET_NR_afs_syscall: 4022 goto unimplemented; 4023 #endif 4024 #ifdef TARGET_NR__llseek /* Not on alpha */ 4025 case TARGET_NR__llseek: 4026 { 4027 #if defined (__x86_64__) 4028 ret = get_errno(lseek(arg1, ((uint64_t )arg2 << 32) | arg3, arg5)); 4029 tput64(arg4, ret); 4030 #else 4031 int64_t res; 4032 ret = get_errno(_llseek(arg1, arg2, arg3, &res, arg5)); 4033 tput64(arg4, res); 4034 #endif 4035 } 4036 break; 4037 #endif 4038 case TARGET_NR_getdents: 4039 #if TARGET_LONG_SIZE != 4 4040 goto unimplemented; 4041 #warning not supported 4042 #elif TARGET_LONG_SIZE == 4 && HOST_LONG_SIZE == 8 4043 { 4044 struct target_dirent *target_dirp; 4045 struct dirent *dirp; 4046 target_long count = arg3; 4047 4048 dirp = malloc(count); 4049 if (!dirp) 4050 return -ENOMEM; 4051 4052 ret = get_errno(sys_getdents(arg1, dirp, count)); 4053 if (!is_error(ret)) { 4054 struct dirent *de; 4055 struct target_dirent *tde; 4056 int len = ret; 4057 int reclen, treclen; 4058 int count1, tnamelen; 4059 4060 count1 = 0; 4061 de = dirp; 4062 target_dirp = lock_user(arg2, count, 0); 4063 tde = target_dirp; 4064 while (len > 0) { 4065 reclen = de->d_reclen; 4066 treclen = reclen - (2 * (sizeof(long) - sizeof(target_long))); 4067 tde->d_reclen = tswap16(treclen); 4068 tde->d_ino = tswapl(de->d_ino); 4069 tde->d_off = tswapl(de->d_off); 4070 tnamelen = treclen - (2 * sizeof(target_long) + 2); 4071 if (tnamelen > 256) 4072 tnamelen = 256; 4073 /* XXX: may not be correct */ 4074 strncpy(tde->d_name, de->d_name, tnamelen); 4075 de = (struct dirent *)((char *)de + reclen); 4076 len -= reclen; 4077 tde = (struct target_dirent *)((char *)tde + treclen); 4078 count1 += treclen; 4079 } 4080 ret = count1; 4081 } 4082 unlock_user(target_dirp, arg2, ret); 4083 free(dirp); 4084 } 4085 #else 4086 { 4087 struct dirent *dirp; 4088 target_long count = arg3; 4089 4090 dirp = lock_user(arg2, count, 0); 4091 ret = get_errno(sys_getdents(arg1, dirp, count)); 4092 if (!is_error(ret)) { 4093 struct dirent *de; 4094 int len = ret; 4095 int reclen; 4096 de = dirp; 4097 while (len > 0) { 4098 reclen = de->d_reclen; 4099 if (reclen > len) 4100 break; 4101 de->d_reclen = tswap16(reclen); 4102 tswapls(&de->d_ino); 4103 tswapls(&de->d_off); 4104 de = (struct dirent *)((char *)de + reclen); 4105 len -= reclen; 4106 } 4107 } 4108 unlock_user(dirp, arg2, ret); 4109 } 4110 #endif 4111 break; 4112 #if defined(TARGET_NR_getdents64) && defined(__NR_getdents64) 4113 case TARGET_NR_getdents64: 4114 { 4115 struct dirent64 *dirp; 4116 target_long count = arg3; 4117 dirp = lock_user(arg2, count, 0); 4118 ret = get_errno(sys_getdents64(arg1, dirp, count)); 4119 if (!is_error(ret)) { 4120 struct dirent64 *de; 4121 int len = ret; 4122 int reclen; 4123 de = dirp; 4124 while (len > 0) { 4125 reclen = de->d_reclen; 4126 if (reclen > len) 4127 break; 4128 de->d_reclen = tswap16(reclen); 4129 tswap64s(&de->d_ino); 4130 tswap64s(&de->d_off); 4131 de = (struct dirent64 *)((char *)de + reclen); 4132 len -= reclen; 4133 } 4134 } 4135 unlock_user(dirp, arg2, ret); 4136 } 4137 break; 4138 #endif /* TARGET_NR_getdents64 */ 4139 #ifdef TARGET_NR__newselect 4140 case TARGET_NR__newselect: 4141 ret = do_select(arg1, arg2, arg3, arg4, arg5); 4142 break; 4143 #endif 4144 #ifdef TARGET_NR_poll 4145 case TARGET_NR_poll: 4146 { 4147 struct target_pollfd *target_pfd; 4148 unsigned int nfds = arg2; 4149 int timeout = arg3; 4150 struct pollfd *pfd; 4151 unsigned int i; 4152 4153 target_pfd = lock_user(arg1, sizeof(struct target_pollfd) * nfds, 1); 4154 pfd = alloca(sizeof(struct pollfd) * nfds); 4155 for(i = 0; i < nfds; i++) { 4156 pfd[i].fd = tswap32(target_pfd[i].fd); 4157 pfd[i].events = tswap16(target_pfd[i].events); 4158 } 4159 ret = get_errno(poll(pfd, nfds, timeout)); 4160 if (!is_error(ret)) { 4161 for(i = 0; i < nfds; i++) { 4162 target_pfd[i].revents = tswap16(pfd[i].revents); 4163 } 4164 ret += nfds * (sizeof(struct target_pollfd) 4165 - sizeof(struct pollfd)); 4166 } 4167 unlock_user(target_pfd, arg1, ret); 4168 } 4169 break; 4170 #endif 4171 case TARGET_NR_flock: 4172 /* NOTE: the flock constant seems to be the same for every 4173 Linux platform */ 4174 ret = get_errno(flock(arg1, arg2)); 4175 break; 4176 case TARGET_NR_readv: 4177 { 4178 int count = arg3; 4179 struct iovec *vec; 4180 4181 vec = alloca(count * sizeof(struct iovec)); 4182 lock_iovec(vec, arg2, count, 0); 4183 ret = get_errno(readv(arg1, vec, count)); 4184 unlock_iovec(vec, arg2, count, 1); 4185 } 4186 break; 4187 case TARGET_NR_writev: 4188 { 4189 int count = arg3; 4190 struct iovec *vec; 4191 4192 vec = alloca(count * sizeof(struct iovec)); 4193 lock_iovec(vec, arg2, count, 1); 4194 ret = get_errno(writev(arg1, vec, count)); 4195 unlock_iovec(vec, arg2, count, 0); 4196 } 4197 break; 4198 case TARGET_NR_getsid: 4199 ret = get_errno(getsid(arg1)); 4200 break; 4201 #if defined(TARGET_NR_fdatasync) /* Not on alpha (osf_datasync ?) */ 4202 case TARGET_NR_fdatasync: 4203 ret = get_errno(fdatasync(arg1)); 4204 break; 4205 #endif 4206 case TARGET_NR__sysctl: 4207 /* We don't implement this, but ENODIR is always a safe 4208 return value. */ 4209 return -ENOTDIR; 4210 case TARGET_NR_sched_setparam: 4211 { 4212 struct sched_param *target_schp; 4213 struct sched_param schp; 4214 4215 lock_user_struct(target_schp, arg2, 1); 4216 schp.sched_priority = tswap32(target_schp->sched_priority); 4217 unlock_user_struct(target_schp, arg2, 0); 4218 ret = get_errno(sched_setparam(arg1, &schp)); 4219 } 4220 break; 4221 case TARGET_NR_sched_getparam: 4222 { 4223 struct sched_param *target_schp; 4224 struct sched_param schp; 4225 ret = get_errno(sched_getparam(arg1, &schp)); 4226 if (!is_error(ret)) { 4227 lock_user_struct(target_schp, arg2, 0); 4228 target_schp->sched_priority = tswap32(schp.sched_priority); 4229 unlock_user_struct(target_schp, arg2, 1); 4230 } 4231 } 4232 break; 4233 case TARGET_NR_sched_setscheduler: 4234 { 4235 struct sched_param *target_schp; 4236 struct sched_param schp; 4237 lock_user_struct(target_schp, arg3, 1); 4238 schp.sched_priority = tswap32(target_schp->sched_priority); 4239 unlock_user_struct(target_schp, arg3, 0); 4240 ret = get_errno(sched_setscheduler(arg1, arg2, &schp)); 4241 } 4242 break; 4243 case TARGET_NR_sched_getscheduler: 4244 ret = get_errno(sched_getscheduler(arg1)); 4245 break; 4246 case TARGET_NR_sched_yield: 4247 ret = get_errno(sched_yield()); 4248 break; 4249 case TARGET_NR_sched_get_priority_max: 4250 ret = get_errno(sched_get_priority_max(arg1)); 4251 break; 4252 case TARGET_NR_sched_get_priority_min: 4253 ret = get_errno(sched_get_priority_min(arg1)); 4254 break; 4255 case TARGET_NR_sched_rr_get_interval: 4256 { 4257 struct timespec ts; 4258 ret = get_errno(sched_rr_get_interval(arg1, &ts)); 4259 if (!is_error(ret)) { 4260 host_to_target_timespec(arg2, &ts); 4261 } 4262 } 4263 break; 4264 case TARGET_NR_nanosleep: 4265 { 4266 struct timespec req, rem; 4267 target_to_host_timespec(&req, arg1); 4268 ret = get_errno(nanosleep(&req, &rem)); 4269 if (is_error(ret) && arg2) { 4270 host_to_target_timespec(arg2, &rem); 4271 } 4272 } 4273 break; 4274 #ifdef TARGET_NR_query_module 4275 case TARGET_NR_query_module: 4276 goto unimplemented; 4277 #endif 4278 #ifdef TARGET_NR_nfsservctl 4279 case TARGET_NR_nfsservctl: 4280 goto unimplemented; 4281 #endif 4282 case TARGET_NR_prctl: 4283 switch (arg1) 4284 { 4285 case PR_GET_PDEATHSIG: 4286 { 4287 int deathsig; 4288 ret = get_errno(prctl(arg1, &deathsig, arg3, arg4, arg5)); 4289 if (!is_error(ret) && arg2) 4290 tput32(arg2, deathsig); 4291 } 4292 break; 4293 default: 4294 ret = get_errno(prctl(arg1, arg2, arg3, arg4, arg5)); 4295 break; 4296 } 4297 break; 4298 #ifdef TARGET_NR_pread 4299 case TARGET_NR_pread: 4300 page_unprotect_range(arg2, arg3); 4301 p = lock_user(arg2, arg3, 0); 4302 ret = get_errno(pread(arg1, p, arg3, arg4)); 4303 unlock_user(p, arg2, ret); 4304 break; 4305 case TARGET_NR_pwrite: 4306 p = lock_user(arg2, arg3, 1); 4307 ret = get_errno(pwrite(arg1, p, arg3, arg4)); 4308 unlock_user(p, arg2, 0); 4309 break; 4310 #endif 4311 case TARGET_NR_getcwd: 4312 p = lock_user(arg1, arg2, 0); 4313 ret = get_errno(sys_getcwd1(p, arg2)); 4314 unlock_user(p, arg1, ret); 4315 break; 4316 case TARGET_NR_capget: 4317 goto unimplemented; 4318 case TARGET_NR_capset: 4319 goto unimplemented; 4320 case TARGET_NR_sigaltstack: 4321 goto unimplemented; 4322 case TARGET_NR_sendfile: 4323 goto unimplemented; 4324 #ifdef TARGET_NR_getpmsg 4325 case TARGET_NR_getpmsg: 4326 goto unimplemented; 4327 #endif 4328 #ifdef TARGET_NR_putpmsg 4329 case TARGET_NR_putpmsg: 4330 goto unimplemented; 4331 #endif 4332 #ifdef TARGET_NR_vfork 4333 case TARGET_NR_vfork: 4334 ret = get_errno(do_fork(cpu_env, CLONE_VFORK | CLONE_VM | SIGCHLD, 0)); 4335 break; 4336 #endif 4337 #ifdef TARGET_NR_ugetrlimit 4338 case TARGET_NR_ugetrlimit: 4339 { 4340 struct rlimit rlim; 4341 ret = get_errno(getrlimit(arg1, &rlim)); 4342 if (!is_error(ret)) { 4343 struct target_rlimit *target_rlim; 4344 lock_user_struct(target_rlim, arg2, 0); 4345 target_rlim->rlim_cur = tswapl(rlim.rlim_cur); 4346 target_rlim->rlim_max = tswapl(rlim.rlim_max); 4347 unlock_user_struct(target_rlim, arg2, 1); 4348 } 4349 break; 4350 } 4351 #endif 4352 #ifdef TARGET_NR_truncate64 4353 case TARGET_NR_truncate64: 4354 p = lock_user_string(arg1); 4355 ret = target_truncate64(cpu_env, p, arg2, arg3, arg4); 4356 unlock_user(p, arg1, 0); 4357 break; 4358 #endif 4359 #ifdef TARGET_NR_ftruncate64 4360 case TARGET_NR_ftruncate64: 4361 ret = target_ftruncate64(cpu_env, arg1, arg2, arg3, arg4); 4362 break; 4363 #endif 4364 #ifdef TARGET_NR_stat64 4365 case TARGET_NR_stat64: 4366 p = lock_user_string(arg1); 4367 ret = get_errno(stat(path(p), &st)); 4368 unlock_user(p, arg1, 0); 4369 goto do_stat64; 4370 #endif 4371 #ifdef TARGET_NR_lstat64 4372 case TARGET_NR_lstat64: 4373 p = lock_user_string(arg1); 4374 ret = get_errno(lstat(path(p), &st)); 4375 unlock_user(p, arg1, 0); 4376 goto do_stat64; 4377 #endif 4378 #ifdef TARGET_NR_fstat64 4379 case TARGET_NR_fstat64: 4380 { 4381 ret = get_errno(fstat(arg1, &st)); 4382 do_stat64: 4383 if (!is_error(ret)) { 4384 #ifdef TARGET_ARM 4385 if (((CPUARMState *)cpu_env)->eabi) { 4386 struct target_eabi_stat64 *target_st; 4387 lock_user_struct(target_st, arg2, 1); 4388 memset(target_st, 0, sizeof(struct target_eabi_stat64)); 4389 /* put_user is probably wrong. */ 4390 put_user(st.st_dev, &target_st->st_dev); 4391 put_user(st.st_ino, &target_st->st_ino); 4392 #ifdef TARGET_STAT64_HAS_BROKEN_ST_INO 4393 put_user(st.st_ino, &target_st->__st_ino); 4394 #endif 4395 put_user(st.st_mode, &target_st->st_mode); 4396 put_user(st.st_nlink, &target_st->st_nlink); 4397 put_user(st.st_uid, &target_st->st_uid); 4398 put_user(st.st_gid, &target_st->st_gid); 4399 put_user(st.st_rdev, &target_st->st_rdev); 4400 /* XXX: better use of kernel struct */ 4401 put_user(st.st_size, &target_st->st_size); 4402 put_user(st.st_blksize, &target_st->st_blksize); 4403 put_user(st.st_blocks, &target_st->st_blocks); 4404 put_user(st.st_atime, &target_st->target_st_atime); 4405 put_user(st.st_mtime, &target_st->target_st_mtime); 4406 put_user(st.st_ctime, &target_st->target_st_ctime); 4407 unlock_user_struct(target_st, arg2, 0); 4408 } else 4409 #endif 4410 { 4411 struct target_stat64 *target_st; 4412 lock_user_struct(target_st, arg2, 1); 4413 memset(target_st, 0, sizeof(struct target_stat64)); 4414 /* ??? put_user is probably wrong. */ 4415 put_user(st.st_dev, &target_st->st_dev); 4416 put_user(st.st_ino, &target_st->st_ino); 4417 #ifdef TARGET_STAT64_HAS_BROKEN_ST_INO 4418 put_user(st.st_ino, &target_st->__st_ino); 4419 #endif 4420 put_user(st.st_mode, &target_st->st_mode); 4421 put_user(st.st_nlink, &target_st->st_nlink); 4422 put_user(st.st_uid, &target_st->st_uid); 4423 put_user(st.st_gid, &target_st->st_gid); 4424 put_user(st.st_rdev, &target_st->st_rdev); 4425 /* XXX: better use of kernel struct */ 4426 put_user(st.st_size, &target_st->st_size); 4427 put_user(st.st_blksize, &target_st->st_blksize); 4428 put_user(st.st_blocks, &target_st->st_blocks); 4429 put_user(st.st_atime, &target_st->target_st_atime); 4430 put_user(st.st_mtime, &target_st->target_st_mtime); 4431 put_user(st.st_ctime, &target_st->target_st_ctime); 4432 unlock_user_struct(target_st, arg2, 0); 4433 } 4434 } 4435 } 4436 break; 4437 #endif 4438 #ifdef USE_UID16 4439 case TARGET_NR_lchown: 4440 p = lock_user_string(arg1); 4441 ret = get_errno(lchown(p, low2highuid(arg2), low2highgid(arg3))); 4442 unlock_user(p, arg1, 0); 4443 break; 4444 case TARGET_NR_getuid: 4445 ret = get_errno(high2lowuid(getuid())); 4446 break; 4447 case TARGET_NR_getgid: 4448 ret = get_errno(high2lowgid(getgid())); 4449 break; 4450 case TARGET_NR_geteuid: 4451 ret = get_errno(high2lowuid(geteuid())); 4452 break; 4453 case TARGET_NR_getegid: 4454 ret = get_errno(high2lowgid(getegid())); 4455 break; 4456 case TARGET_NR_setreuid: 4457 ret = get_errno(setreuid(low2highuid(arg1), low2highuid(arg2))); 4458 break; 4459 case TARGET_NR_setregid: 4460 ret = get_errno(setregid(low2highgid(arg1), low2highgid(arg2))); 4461 break; 4462 case TARGET_NR_getgroups: 4463 { 4464 int gidsetsize = arg1; 4465 uint16_t *target_grouplist; 4466 gid_t *grouplist; 4467 int i; 4468 4469 grouplist = alloca(gidsetsize * sizeof(gid_t)); 4470 ret = get_errno(getgroups(gidsetsize, grouplist)); 4471 if (!is_error(ret)) { 4472 target_grouplist = lock_user(arg2, gidsetsize * 2, 0); 4473 for(i = 0;i < gidsetsize; i++) 4474 target_grouplist[i] = tswap16(grouplist[i]); 4475 unlock_user(target_grouplist, arg2, gidsetsize * 2); 4476 } 4477 } 4478 break; 4479 case TARGET_NR_setgroups: 4480 { 4481 int gidsetsize = arg1; 4482 uint16_t *target_grouplist; 4483 gid_t *grouplist; 4484 int i; 4485 4486 grouplist = alloca(gidsetsize * sizeof(gid_t)); 4487 target_grouplist = lock_user(arg2, gidsetsize * 2, 1); 4488 for(i = 0;i < gidsetsize; i++) 4489 grouplist[i] = tswap16(target_grouplist[i]); 4490 unlock_user(target_grouplist, arg2, 0); 4491 ret = get_errno(setgroups(gidsetsize, grouplist)); 4492 } 4493 break; 4494 case TARGET_NR_fchown: 4495 ret = get_errno(fchown(arg1, low2highuid(arg2), low2highgid(arg3))); 4496 break; 4497 #if defined(TARGET_NR_fchownat) && defined(__NR_fchownat) 4498 case TARGET_NR_fchownat: 4499 if (!arg2) { 4500 ret = -EFAULT; 4501 goto fail; 4502 } 4503 p = lock_user_string(arg2); 4504 if (!access_ok(VERIFY_READ, p, 1)) 4505 ret = -EFAULT; 4506 else 4507 ret = get_errno(sys_fchownat(arg1, p, low2highuid(arg3), low2highgid(arg4), arg5)); 4508 if (p) 4509 unlock_user(p, arg2, 0); 4510 break; 4511 #endif 4512 #ifdef TARGET_NR_setresuid 4513 case TARGET_NR_setresuid: 4514 ret = get_errno(setresuid(low2highuid(arg1), 4515 low2highuid(arg2), 4516 low2highuid(arg3))); 4517 break; 4518 #endif 4519 #ifdef TARGET_NR_getresuid 4520 case TARGET_NR_getresuid: 4521 { 4522 uid_t ruid, euid, suid; 4523 ret = get_errno(getresuid(&ruid, &euid, &suid)); 4524 if (!is_error(ret)) { 4525 tput16(arg1, tswap16(high2lowuid(ruid))); 4526 tput16(arg2, tswap16(high2lowuid(euid))); 4527 tput16(arg3, tswap16(high2lowuid(suid))); 4528 } 4529 } 4530 break; 4531 #endif 4532 #ifdef TARGET_NR_getresgid 4533 case TARGET_NR_setresgid: 4534 ret = get_errno(setresgid(low2highgid(arg1), 4535 low2highgid(arg2), 4536 low2highgid(arg3))); 4537 break; 4538 #endif 4539 #ifdef TARGET_NR_getresgid 4540 case TARGET_NR_getresgid: 4541 { 4542 gid_t rgid, egid, sgid; 4543 ret = get_errno(getresgid(&rgid, &egid, &sgid)); 4544 if (!is_error(ret)) { 4545 tput16(arg1, tswap16(high2lowgid(rgid))); 4546 tput16(arg2, tswap16(high2lowgid(egid))); 4547 tput16(arg3, tswap16(high2lowgid(sgid))); 4548 } 4549 } 4550 break; 4551 #endif 4552 case TARGET_NR_chown: 4553 p = lock_user_string(arg1); 4554 ret = get_errno(chown(p, low2highuid(arg2), low2highgid(arg3))); 4555 unlock_user(p, arg1, 0); 4556 break; 4557 case TARGET_NR_setuid: 4558 ret = get_errno(setuid(low2highuid(arg1))); 4559 break; 4560 case TARGET_NR_setgid: 4561 ret = get_errno(setgid(low2highgid(arg1))); 4562 break; 4563 case TARGET_NR_setfsuid: 4564 ret = get_errno(setfsuid(arg1)); 4565 break; 4566 case TARGET_NR_setfsgid: 4567 ret = get_errno(setfsgid(arg1)); 4568 break; 4569 #endif /* USE_UID16 */ 4570 4571 #ifdef TARGET_NR_lchown32 4572 case TARGET_NR_lchown32: 4573 p = lock_user_string(arg1); 4574 ret = get_errno(lchown(p, arg2, arg3)); 4575 unlock_user(p, arg1, 0); 4576 break; 4577 #endif 4578 #ifdef TARGET_NR_getuid32 4579 case TARGET_NR_getuid32: 4580 ret = get_errno(getuid()); 4581 break; 4582 #endif 4583 #ifdef TARGET_NR_getgid32 4584 case TARGET_NR_getgid32: 4585 ret = get_errno(getgid()); 4586 break; 4587 #endif 4588 #ifdef TARGET_NR_geteuid32 4589 case TARGET_NR_geteuid32: 4590 ret = get_errno(geteuid()); 4591 break; 4592 #endif 4593 #ifdef TARGET_NR_getegid32 4594 case TARGET_NR_getegid32: 4595 ret = get_errno(getegid()); 4596 break; 4597 #endif 4598 #ifdef TARGET_NR_setreuid32 4599 case TARGET_NR_setreuid32: 4600 ret = get_errno(setreuid(arg1, arg2)); 4601 break; 4602 #endif 4603 #ifdef TARGET_NR_setregid32 4604 case TARGET_NR_setregid32: 4605 ret = get_errno(setregid(arg1, arg2)); 4606 break; 4607 #endif 4608 #ifdef TARGET_NR_getgroups32 4609 case TARGET_NR_getgroups32: 4610 { 4611 int gidsetsize = arg1; 4612 uint32_t *target_grouplist; 4613 gid_t *grouplist; 4614 int i; 4615 4616 grouplist = alloca(gidsetsize * sizeof(gid_t)); 4617 ret = get_errno(getgroups(gidsetsize, grouplist)); 4618 if (!is_error(ret)) { 4619 target_grouplist = lock_user(arg2, gidsetsize * 4, 0); 4620 for(i = 0;i < gidsetsize; i++) 4621 target_grouplist[i] = tswap32(grouplist[i]); 4622 unlock_user(target_grouplist, arg2, gidsetsize * 4); 4623 } 4624 } 4625 break; 4626 #endif 4627 #ifdef TARGET_NR_setgroups32 4628 case TARGET_NR_setgroups32: 4629 { 4630 int gidsetsize = arg1; 4631 uint32_t *target_grouplist; 4632 gid_t *grouplist; 4633 int i; 4634 4635 grouplist = alloca(gidsetsize * sizeof(gid_t)); 4636 target_grouplist = lock_user(arg2, gidsetsize * 4, 1); 4637 for(i = 0;i < gidsetsize; i++) 4638 grouplist[i] = tswap32(target_grouplist[i]); 4639 unlock_user(target_grouplist, arg2, 0); 4640 ret = get_errno(setgroups(gidsetsize, grouplist)); 4641 } 4642 break; 4643 #endif 4644 #ifdef TARGET_NR_fchown32 4645 case TARGET_NR_fchown32: 4646 ret = get_errno(fchown(arg1, arg2, arg3)); 4647 break; 4648 #endif 4649 #ifdef TARGET_NR_setresuid32 4650 case TARGET_NR_setresuid32: 4651 ret = get_errno(setresuid(arg1, arg2, arg3)); 4652 break; 4653 #endif 4654 #ifdef TARGET_NR_getresuid32 4655 case TARGET_NR_getresuid32: 4656 { 4657 uid_t ruid, euid, suid; 4658 ret = get_errno(getresuid(&ruid, &euid, &suid)); 4659 if (!is_error(ret)) { 4660 tput32(arg1, tswap32(ruid)); 4661 tput32(arg2, tswap32(euid)); 4662 tput32(arg3, tswap32(suid)); 4663 } 4664 } 4665 break; 4666 #endif 4667 #ifdef TARGET_NR_setresgid32 4668 case TARGET_NR_setresgid32: 4669 ret = get_errno(setresgid(arg1, arg2, arg3)); 4670 break; 4671 #endif 4672 #ifdef TARGET_NR_getresgid32 4673 case TARGET_NR_getresgid32: 4674 { 4675 gid_t rgid, egid, sgid; 4676 ret = get_errno(getresgid(&rgid, &egid, &sgid)); 4677 if (!is_error(ret)) { 4678 tput32(arg1, tswap32(rgid)); 4679 tput32(arg2, tswap32(egid)); 4680 tput32(arg3, tswap32(sgid)); 4681 } 4682 } 4683 break; 4684 #endif 4685 #ifdef TARGET_NR_chown32 4686 case TARGET_NR_chown32: 4687 p = lock_user_string(arg1); 4688 ret = get_errno(chown(p, arg2, arg3)); 4689 unlock_user(p, arg1, 0); 4690 break; 4691 #endif 4692 #ifdef TARGET_NR_setuid32 4693 case TARGET_NR_setuid32: 4694 ret = get_errno(setuid(arg1)); 4695 break; 4696 #endif 4697 #ifdef TARGET_NR_setgid32 4698 case TARGET_NR_setgid32: 4699 ret = get_errno(setgid(arg1)); 4700 break; 4701 #endif 4702 #ifdef TARGET_NR_setfsuid32 4703 case TARGET_NR_setfsuid32: 4704 ret = get_errno(setfsuid(arg1)); 4705 break; 4706 #endif 4707 #ifdef TARGET_NR_setfsgid32 4708 case TARGET_NR_setfsgid32: 4709 ret = get_errno(setfsgid(arg1)); 4710 break; 4711 #endif 4712 4713 case TARGET_NR_pivot_root: 4714 goto unimplemented; 4715 #ifdef TARGET_NR_mincore 4716 case TARGET_NR_mincore: 4717 goto unimplemented; 4718 #endif 4719 #ifdef TARGET_NR_madvise 4720 case TARGET_NR_madvise: 4721 /* A straight passthrough may not be safe because qemu sometimes 4722 turns private flie-backed mappings into anonymous mappings. 4723 This will break MADV_DONTNEED. 4724 This is a hint, so ignoring and returning success is ok. */ 4725 ret = get_errno(0); 4726 break; 4727 #endif 4728 #if TARGET_LONG_BITS == 32 4729 case TARGET_NR_fcntl64: 4730 { 4731 int cmd; 4732 struct flock64 fl; 4733 struct target_flock64 *target_fl; 4734 #ifdef TARGET_ARM 4735 struct target_eabi_flock64 *target_efl; 4736 #endif 4737 4738 switch(arg2){ 4739 case TARGET_F_GETLK64: 4740 cmd = F_GETLK64; 4741 break; 4742 case TARGET_F_SETLK64: 4743 cmd = F_SETLK64; 4744 break; 4745 case TARGET_F_SETLKW64: 4746 cmd = F_SETLK64; 4747 break; 4748 default: 4749 cmd = arg2; 4750 break; 4751 } 4752 4753 switch(arg2) { 4754 case TARGET_F_GETLK64: 4755 #ifdef TARGET_ARM 4756 if (((CPUARMState *)cpu_env)->eabi) { 4757 lock_user_struct(target_efl, arg3, 1); 4758 fl.l_type = tswap16(target_efl->l_type); 4759 fl.l_whence = tswap16(target_efl->l_whence); 4760 fl.l_start = tswap64(target_efl->l_start); 4761 fl.l_len = tswap64(target_efl->l_len); 4762 fl.l_pid = tswapl(target_efl->l_pid); 4763 unlock_user_struct(target_efl, arg3, 0); 4764 } else 4765 #endif 4766 { 4767 lock_user_struct(target_fl, arg3, 1); 4768 fl.l_type = tswap16(target_fl->l_type); 4769 fl.l_whence = tswap16(target_fl->l_whence); 4770 fl.l_start = tswap64(target_fl->l_start); 4771 fl.l_len = tswap64(target_fl->l_len); 4772 fl.l_pid = tswapl(target_fl->l_pid); 4773 unlock_user_struct(target_fl, arg3, 0); 4774 } 4775 ret = get_errno(fcntl(arg1, cmd, &fl)); 4776 if (ret == 0) { 4777 #ifdef TARGET_ARM 4778 if (((CPUARMState *)cpu_env)->eabi) { 4779 lock_user_struct(target_efl, arg3, 0); 4780 target_efl->l_type = tswap16(fl.l_type); 4781 target_efl->l_whence = tswap16(fl.l_whence); 4782 target_efl->l_start = tswap64(fl.l_start); 4783 target_efl->l_len = tswap64(fl.l_len); 4784 target_efl->l_pid = tswapl(fl.l_pid); 4785 unlock_user_struct(target_efl, arg3, 1); 4786 } else 4787 #endif 4788 { 4789 lock_user_struct(target_fl, arg3, 0); 4790 target_fl->l_type = tswap16(fl.l_type); 4791 target_fl->l_whence = tswap16(fl.l_whence); 4792 target_fl->l_start = tswap64(fl.l_start); 4793 target_fl->l_len = tswap64(fl.l_len); 4794 target_fl->l_pid = tswapl(fl.l_pid); 4795 unlock_user_struct(target_fl, arg3, 1); 4796 } 4797 } 4798 break; 4799 4800 case TARGET_F_SETLK64: 4801 case TARGET_F_SETLKW64: 4802 #ifdef TARGET_ARM 4803 if (((CPUARMState *)cpu_env)->eabi) { 4804 lock_user_struct(target_efl, arg3, 1); 4805 fl.l_type = tswap16(target_efl->l_type); 4806 fl.l_whence = tswap16(target_efl->l_whence); 4807 fl.l_start = tswap64(target_efl->l_start); 4808 fl.l_len = tswap64(target_efl->l_len); 4809 fl.l_pid = tswapl(target_efl->l_pid); 4810 unlock_user_struct(target_efl, arg3, 0); 4811 } else 4812 #endif 4813 { 4814 lock_user_struct(target_fl, arg3, 1); 4815 fl.l_type = tswap16(target_fl->l_type); 4816 fl.l_whence = tswap16(target_fl->l_whence); 4817 fl.l_start = tswap64(target_fl->l_start); 4818 fl.l_len = tswap64(target_fl->l_len); 4819 fl.l_pid = tswapl(target_fl->l_pid); 4820 unlock_user_struct(target_fl, arg3, 0); 4821 } 4822 ret = get_errno(fcntl(arg1, cmd, &fl)); 4823 break; 4824 default: 4825 ret = get_errno(do_fcntl(arg1, cmd, arg3)); 4826 break; 4827 } 4828 break; 4829 } 4830 #endif 4831 #ifdef TARGET_NR_cacheflush 4832 case TARGET_NR_cacheflush: 4833 /* self-modifying code is handled automatically, so nothing needed */ 4834 ret = 0; 4835 break; 4836 #endif 4837 #ifdef TARGET_NR_security 4838 case TARGET_NR_security: 4839 goto unimplemented; 4840 #endif 4841 #ifdef TARGET_NR_getpagesize 4842 case TARGET_NR_getpagesize: 4843 ret = TARGET_PAGE_SIZE; 4844 break; 4845 #endif 4846 case TARGET_NR_gettid: 4847 ret = get_errno(gettid()); 4848 break; 4849 #ifdef TARGET_NR_readahead 4850 case TARGET_NR_readahead: 4851 goto unimplemented; 4852 #endif 4853 #ifdef TARGET_NR_setxattr 4854 case TARGET_NR_setxattr: 4855 case TARGET_NR_lsetxattr: 4856 case TARGET_NR_fsetxattr: 4857 case TARGET_NR_getxattr: 4858 case TARGET_NR_lgetxattr: 4859 case TARGET_NR_fgetxattr: 4860 case TARGET_NR_listxattr: 4861 case TARGET_NR_llistxattr: 4862 case TARGET_NR_flistxattr: 4863 case TARGET_NR_removexattr: 4864 case TARGET_NR_lremovexattr: 4865 case TARGET_NR_fremovexattr: 4866 goto unimplemented_nowarn; 4867 #endif 4868 #ifdef TARGET_NR_set_thread_area 4869 case TARGET_NR_set_thread_area: 4870 #ifdef TARGET_MIPS 4871 ((CPUMIPSState *) cpu_env)->tls_value = arg1; 4872 ret = 0; 4873 break; 4874 #else 4875 goto unimplemented_nowarn; 4876 #endif 4877 #endif 4878 #ifdef TARGET_NR_get_thread_area 4879 case TARGET_NR_get_thread_area: 4880 goto unimplemented_nowarn; 4881 #endif 4882 #ifdef TARGET_NR_getdomainname 4883 case TARGET_NR_getdomainname: 4884 goto unimplemented_nowarn; 4885 #endif 4886 4887 #ifdef TARGET_NR_clock_gettime 4888 case TARGET_NR_clock_gettime: 4889 { 4890 struct timespec ts; 4891 ret = get_errno(clock_gettime(arg1, &ts)); 4892 if (!is_error(ret)) { 4893 host_to_target_timespec(arg2, &ts); 4894 } 4895 break; 4896 } 4897 #endif 4898 #ifdef TARGET_NR_clock_getres 4899 case TARGET_NR_clock_getres: 4900 { 4901 struct timespec ts; 4902 ret = get_errno(clock_getres(arg1, &ts)); 4903 if (!is_error(ret)) { 4904 host_to_target_timespec(arg2, &ts); 4905 } 4906 break; 4907 } 4908 #endif 4909 4910 #if defined(TARGET_NR_set_tid_address) && defined(__NR_set_tid_address) 4911 case TARGET_NR_set_tid_address: 4912 ret = get_errno(set_tid_address((int *) arg1)); 4913 break; 4914 #endif 4915 4916 #if defined(TARGET_NR_tkill) && defined(__NR_tkill) 4917 case TARGET_NR_tkill: 4918 ret = get_errno(sys_tkill((int)arg1, (int)arg2)); 4919 break; 4920 #endif 4921 4922 #if defined(TARGET_NR_tgkill) && defined(__NR_tgkill) 4923 case TARGET_NR_tgkill: 4924 ret = get_errno(sys_tgkill((int)arg1, (int)arg2, (int)arg3)); 4925 break; 4926 #endif 4927 4928 #ifdef TARGET_NR_set_robust_list 4929 case TARGET_NR_set_robust_list: 4930 goto unimplemented_nowarn; 4931 #endif 4932 4933 #if defined(TARGET_NR_utimensat) && defined(__NR_utimensat) 4934 case TARGET_NR_utimensat: 4935 { 4936 struct timespec ts[2]; 4937 target_to_host_timespec(ts, arg3); 4938 target_to_host_timespec(ts+1, arg3+sizeof(struct target_timespec)); 4939 if (!arg2) 4940 ret = get_errno(sys_utimensat(arg1, NULL, ts, arg4)); 4941 else { 4942 p = lock_user_string(arg2); 4943 if (!access_ok(VERIFY_READ, p, 1)) 4944 ret = -EFAULT; 4945 else 4946 ret = get_errno(sys_utimensat(arg1, path(p), ts, arg4)); 4947 if (p) 4948 unlock_user(p, arg2, 0); 4949 } 4950 } 4951 break; 4952 #endif 4953 4954 default: 4955 unimplemented: 4956 gemu_log("qemu: Unsupported syscall: %d\n", num); 4957 #if defined(TARGET_NR_setxattr) || defined(TARGET_NR_get_thread_area) || defined(TARGET_NR_getdomainname) || defined(TARGET_NR_set_robust_list) 4958 unimplemented_nowarn: 4959 #endif 4960 ret = -ENOSYS; 4961 break; 4962 } 4963 fail: 4964 #ifdef DEBUG 4965 gemu_log(" = %ld\n", ret); 4966 #endif 4967 return ret; 4968 } 4969