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