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