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