⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 syscall.c

📁 qemu性能直逼VMware的仿真器QEMU 的模擬速度約為實機的 25%;約為 Bochs 的 60 倍。Plex86、User-Mode-Linux、VMware 和 Virtual PC 則比
💻 C
📖 第 1 页 / 共 5 页
字号:
            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 + -