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