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