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