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