📄 syscall.c
字号:
newsp = env->aregs[7]; new_env->aregs[7] = newsp; new_env->dregs[0] = 0; /* ??? is this sufficient? */#elif defined(TARGET_MIPS) printf ("HELPME: %s:%d\n", __FILE__, __LINE__);#elif defined(TARGET_PPC) if (!newsp) newsp = env->gpr[1]; new_env->gpr[1] = newsp; { int i; for (i = 7; i < 32; i++) new_env->gpr[i] = 0; }#elif defined(TARGET_SH4) if (!newsp) newsp = env->gregs[15]; new_env->gregs[15] = newsp; /* XXXXX */#else#error unsupported target CPU#endif new_env->opaque = ts;#ifdef __ia64__ ret = __clone2(clone_func, new_stack + NEW_STACK_SIZE, flags, new_env);#else ret = clone(clone_func, new_stack + NEW_STACK_SIZE, flags, new_env);#endif } else { /* if no CLONE_VM, we consider it is a fork */ if ((flags & ~CSIGNAL) != 0) return -EINVAL; ret = fork(); } return ret;}static long do_fcntl(int fd, int cmd, target_ulong arg){ struct flock fl; struct target_flock *target_fl; struct flock64 fl64; struct target_flock64 *target_fl64; long ret; switch(cmd) { case TARGET_F_GETLK: ret = fcntl(fd, cmd, &fl); if (ret == 0) { lock_user_struct(target_fl, arg, 0); target_fl->l_type = tswap16(fl.l_type); target_fl->l_whence = tswap16(fl.l_whence); target_fl->l_start = tswapl(fl.l_start); target_fl->l_len = tswapl(fl.l_len); target_fl->l_pid = tswapl(fl.l_pid); unlock_user_struct(target_fl, arg, 1); } break; case TARGET_F_SETLK: case TARGET_F_SETLKW: lock_user_struct(target_fl, arg, 1); fl.l_type = tswap16(target_fl->l_type); fl.l_whence = tswap16(target_fl->l_whence); fl.l_start = tswapl(target_fl->l_start); fl.l_len = tswapl(target_fl->l_len); fl.l_pid = tswapl(target_fl->l_pid); unlock_user_struct(target_fl, arg, 0); ret = fcntl(fd, cmd, &fl); break; case TARGET_F_GETLK64: ret = fcntl(fd, cmd >> 1, &fl64); if (ret == 0) { lock_user_struct(target_fl64, arg, 0); target_fl64->l_type = tswap16(fl64.l_type) >> 1; target_fl64->l_whence = tswap16(fl64.l_whence); target_fl64->l_start = tswapl(fl64.l_start); target_fl64->l_len = tswapl(fl64.l_len); target_fl64->l_pid = tswapl(fl64.l_pid); unlock_user_struct(target_fl64, arg, 1); } break; case TARGET_F_SETLK64: case TARGET_F_SETLKW64: lock_user_struct(target_fl64, arg, 1); fl64.l_type = tswap16(target_fl64->l_type) >> 1; fl64.l_whence = tswap16(target_fl64->l_whence); fl64.l_start = tswapl(target_fl64->l_start); fl64.l_len = tswapl(target_fl64->l_len); fl64.l_pid = tswap16(target_fl64->l_pid); unlock_user_struct(target_fl64, arg, 0); ret = fcntl(fd, cmd >> 1, &fl64); break; case F_GETFL: ret = fcntl(fd, cmd, arg); ret = host_to_target_bitmask(ret, fcntl_flags_tbl); break; case F_SETFL: ret = fcntl(fd, cmd, target_to_host_bitmask(arg, fcntl_flags_tbl)); break; default: ret = fcntl(fd, cmd, arg); break; } return ret;}#ifdef USE_UID16static inline int high2lowuid(int uid){ if (uid > 65535) return 65534; else return uid;}static inline int high2lowgid(int gid){ if (gid > 65535) return 65534; else return gid;}static inline int low2highuid(int uid){ if ((int16_t)uid == -1) return -1; else return uid;}static inline int low2highgid(int gid){ if ((int16_t)gid == -1) return -1; else return gid;}#endif /* USE_UID16 */void syscall_init(void){ IOCTLEntry *ie; const argtype *arg_type; int size;#define STRUCT(name, list...) thunk_register_struct(STRUCT_ ## name, #name, struct_ ## name ## _def); #define STRUCT_SPECIAL(name) thunk_register_struct_direct(STRUCT_ ## name, #name, &struct_ ## name ## _def); #include "syscall_types.h"#undef STRUCT#undef STRUCT_SPECIAL /* we patch the ioctl size if necessary. We rely on the fact that no ioctl has all the bits at '1' in the size field */ ie = ioctl_entries; while (ie->target_cmd != 0) { if (((ie->target_cmd >> TARGET_IOC_SIZESHIFT) & TARGET_IOC_SIZEMASK) == TARGET_IOC_SIZEMASK) { arg_type = ie->arg_type; if (arg_type[0] != TYPE_PTR) { fprintf(stderr, "cannot patch size for ioctl 0x%x\n", ie->target_cmd); exit(1); } arg_type++; size = thunk_type_size(arg_type, 0); ie->target_cmd = (ie->target_cmd & ~(TARGET_IOC_SIZEMASK << TARGET_IOC_SIZESHIFT)) | (size << TARGET_IOC_SIZESHIFT); } /* automatic consistency check if same arch */#if defined(__i386__) && defined(TARGET_I386) if (ie->target_cmd != ie->host_cmd) { fprintf(stderr, "ERROR: ioctl: target=0x%x host=0x%x\n", ie->target_cmd, ie->host_cmd); }#endif ie++; }}static inline uint64_t target_offset64(uint32_t word0, uint32_t word1){#ifdef TARGET_WORDS_BIG_ENDIAN return ((uint64_t)word0 << 32) | word1;#else return ((uint64_t)word1 << 32) | word0;#endif}#ifdef TARGET_NR_truncate64static inline long target_truncate64(void *cpu_env, const char *arg1, long arg2, long arg3, long arg4){#ifdef TARGET_ARM if (((CPUARMState *)cpu_env)->eabi) { arg2 = arg3; arg3 = arg4; }#endif return get_errno(truncate64(arg1, target_offset64(arg2, arg3)));}#endif#ifdef TARGET_NR_ftruncate64static inline long target_ftruncate64(void *cpu_env, long arg1, long arg2, long arg3, long arg4){#ifdef TARGET_ARM if (((CPUARMState *)cpu_env)->eabi) { arg2 = arg3; arg3 = arg4; }#endif return get_errno(ftruncate64(arg1, target_offset64(arg2, arg3)));}#endifstatic inline void target_to_host_timespec(struct timespec *host_ts, target_ulong target_addr){ struct target_timespec *target_ts; lock_user_struct(target_ts, target_addr, 1); host_ts->tv_sec = tswapl(target_ts->tv_sec); host_ts->tv_nsec = tswapl(target_ts->tv_nsec); unlock_user_struct(target_ts, target_addr, 0);}static inline void host_to_target_timespec(target_ulong target_addr, struct timespec *host_ts){ struct target_timespec *target_ts; lock_user_struct(target_ts, target_addr, 0); target_ts->tv_sec = tswapl(host_ts->tv_sec); target_ts->tv_nsec = tswapl(host_ts->tv_nsec); unlock_user_struct(target_ts, target_addr, 1);}long do_syscall(void *cpu_env, int num, long arg1, long arg2, long arg3, long arg4, long arg5, long arg6){ long ret; struct stat st; struct statfs stfs; void *p; #ifdef DEBUG gemu_log("syscall %d", num);#endif switch(num) { case TARGET_NR_exit:#ifdef HAVE_GPROF _mcleanup();#endif gdb_exit(cpu_env, arg1); /* XXX: should free thread stack and CPU env */ _exit(arg1); ret = 0; /* avoid warning */ break; case TARGET_NR_read: page_unprotect_range(arg2, arg3); p = lock_user(arg2, arg3, 0); ret = get_errno(read(arg1, p, arg3)); unlock_user(p, arg2, ret); break; case TARGET_NR_write: p = lock_user(arg2, arg3, 1); ret = get_errno(write(arg1, p, arg3)); unlock_user(p, arg2, 0); break; case TARGET_NR_open: p = lock_user_string(arg1); ret = get_errno(open(path(p), target_to_host_bitmask(arg2, fcntl_flags_tbl), arg3)); unlock_user(p, arg1, 0); break; case TARGET_NR_close: ret = get_errno(close(arg1)); break; case TARGET_NR_brk: ret = do_brk(arg1); break; case TARGET_NR_fork: ret = get_errno(do_fork(cpu_env, SIGCHLD, 0)); break; case TARGET_NR_waitpid: { int status; ret = get_errno(waitpid(arg1, &status, arg3)); if (!is_error(ret) && arg2) tput32(arg2, status); } break; case TARGET_NR_creat: p = lock_user_string(arg1); ret = get_errno(creat(p, arg2)); unlock_user(p, arg1, 0); break; case TARGET_NR_link: { void * p2; p = lock_user_string(arg1); p2 = lock_user_string(arg2); ret = get_errno(link(p, p2)); unlock_user(p2, arg2, 0); unlock_user(p, arg1, 0); } break; case TARGET_NR_unlink: p = lock_user_string(arg1); ret = get_errno(unlink(p)); unlock_user(p, arg1, 0); break; case TARGET_NR_execve: { char **argp, **envp; int argc, envc; target_ulong gp; target_ulong guest_argp; target_ulong guest_envp; target_ulong addr; char **q; argc = 0; guest_argp = arg2; for (gp = guest_argp; tgetl(gp); gp++) argc++; envc = 0; guest_envp = arg3; for (gp = guest_envp; tgetl(gp); gp++) envc++; argp = alloca((argc + 1) * sizeof(void *)); envp = alloca((envc + 1) * sizeof(void *)); for (gp = guest_argp, q = argp; ; gp += sizeof(target_ulong), q++) { addr = tgetl(gp); if (!addr) break; *q = lock_user_string(addr); } *q = NULL; for (gp = guest_envp, q = envp; ; gp += sizeof(target_ulong), q++) { addr = tgetl(gp); if (!addr) break; *q = lock_user_string(addr); } *q = NULL; p = lock_user_string(arg1); ret = get_errno(execve(p, argp, envp)); unlock_user(p, arg1, 0); for (gp = guest_argp, q = argp; *q; gp += sizeof(target_ulong), q++) { addr = tgetl(gp); unlock_user(*q, addr, 0); } for (gp = guest_envp, q = envp; *q; gp += sizeof(target_ulong), q++) { addr = tgetl(gp); unlock_user(*q, addr, 0); } } break; case TARGET_NR_chdir: p = lock_user_string(arg1); ret = get_errno(chdir(p)); unlock_user(p, arg1, 0); break;#ifdef TARGET_NR_time case TARGET_NR_time: { time_t host_time; ret = get_errno(time(&host_time)); if (!is_error(ret) && arg1) tputl(arg1, host_time); } break;#endif case TARGET_NR_mknod: p = lock_user_string(arg1); ret = get_errno(mknod(p, arg2, arg3)); unlock_user(p, arg1, 0); break; case TARGET_NR_chmod: p = lock_user_string(arg1); ret = get_errno(chmod(p, arg2)); unlock_user(p, arg1, 0); break;#ifdef TARGET_NR_break case TARGET_NR_break: goto unimplemented;#endif#ifdef TARGET_NR_oldstat case TARGET_NR_oldstat: goto unimplemented;#endif case TARGET_NR_lseek: ret = get_errno(lseek(arg1, arg2, arg3)); break; case TARGET_NR_getpid: ret = get_errno(getpid()); break; case TARGET_NR_mount: /* need to look at the data field */ goto unimplemented; case TARGET_NR_umount: p = lock_user_string(arg1); ret = get_errno(umount(p)); unlock_user(p, arg1, 0); break; case TARGET_NR_stime: { time_t host_time; host_tim
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -