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

📄 syscall.c

📁 qemu性能直逼VMware的仿真器QEMU 的模擬速度約為實機的 25%;約為 Bochs 的 60 倍。Plex86、User-Mode-Linux、VMware 和 Virtual PC 則比
💻 C
📖 第 1 页 / 共 5 页
字号:
    }    arg_type = ie->arg_type;#if defined(DEBUG)    gemu_log("ioctl: cmd=0x%04lx (%s)\n", cmd, ie->name);#endif    switch(arg_type[0]) {    case TYPE_NULL:        /* no argument */        ret = get_errno(ioctl(fd, ie->host_cmd));        break;    case TYPE_PTRVOID:    case TYPE_INT:        /* int argment */        ret = get_errno(ioctl(fd, ie->host_cmd, arg));        break;    case TYPE_PTR:        arg_type++;        target_size = thunk_type_size(arg_type, 0);        switch(ie->access) {        case IOC_R:            ret = get_errno(ioctl(fd, ie->host_cmd, buf_temp));            if (!is_error(ret)) {                argptr = lock_user(arg, target_size, 0);                thunk_convert(argptr, buf_temp, arg_type, THUNK_TARGET);                unlock_user(argptr, arg, target_size);            }            break;        case IOC_W:            argptr = lock_user(arg, target_size, 1);            thunk_convert(buf_temp, argptr, arg_type, THUNK_HOST);            unlock_user(argptr, arg, 0);            ret = get_errno(ioctl(fd, ie->host_cmd, buf_temp));            break;        default:        case IOC_RW:            argptr = lock_user(arg, target_size, 1);            thunk_convert(buf_temp, argptr, arg_type, THUNK_HOST);            unlock_user(argptr, arg, 0);            ret = get_errno(ioctl(fd, ie->host_cmd, buf_temp));            if (!is_error(ret)) {                argptr = lock_user(arg, target_size, 0);                thunk_convert(argptr, buf_temp, arg_type, THUNK_TARGET);                unlock_user(argptr, arg, target_size);            }            break;        }        break;    default:        gemu_log("Unsupported ioctl type: cmd=0x%04lx type=%d\n", cmd, arg_type[0]);        ret = -ENOSYS;        break;    }    return ret;}bitmask_transtbl iflag_tbl[] = {        { TARGET_IGNBRK, TARGET_IGNBRK, IGNBRK, IGNBRK },        { TARGET_BRKINT, TARGET_BRKINT, BRKINT, BRKINT },        { TARGET_IGNPAR, TARGET_IGNPAR, IGNPAR, IGNPAR },        { TARGET_PARMRK, TARGET_PARMRK, PARMRK, PARMRK },        { TARGET_INPCK, TARGET_INPCK, INPCK, INPCK },        { TARGET_ISTRIP, TARGET_ISTRIP, ISTRIP, ISTRIP },        { TARGET_INLCR, TARGET_INLCR, INLCR, INLCR },        { TARGET_IGNCR, TARGET_IGNCR, IGNCR, IGNCR },        { TARGET_ICRNL, TARGET_ICRNL, ICRNL, ICRNL },        { TARGET_IUCLC, TARGET_IUCLC, IUCLC, IUCLC },        { TARGET_IXON, TARGET_IXON, IXON, IXON },        { TARGET_IXANY, TARGET_IXANY, IXANY, IXANY },        { TARGET_IXOFF, TARGET_IXOFF, IXOFF, IXOFF },        { TARGET_IMAXBEL, TARGET_IMAXBEL, IMAXBEL, IMAXBEL },        { 0, 0, 0, 0 }};bitmask_transtbl oflag_tbl[] = {	{ TARGET_OPOST, TARGET_OPOST, OPOST, OPOST },	{ TARGET_OLCUC, TARGET_OLCUC, OLCUC, OLCUC },	{ TARGET_ONLCR, TARGET_ONLCR, ONLCR, ONLCR },	{ TARGET_OCRNL, TARGET_OCRNL, OCRNL, OCRNL },	{ TARGET_ONOCR, TARGET_ONOCR, ONOCR, ONOCR },	{ TARGET_ONLRET, TARGET_ONLRET, ONLRET, ONLRET },	{ TARGET_OFILL, TARGET_OFILL, OFILL, OFILL },	{ TARGET_OFDEL, TARGET_OFDEL, OFDEL, OFDEL },	{ TARGET_NLDLY, TARGET_NL0, NLDLY, NL0 },	{ TARGET_NLDLY, TARGET_NL1, NLDLY, NL1 },	{ TARGET_CRDLY, TARGET_CR0, CRDLY, CR0 },	{ TARGET_CRDLY, TARGET_CR1, CRDLY, CR1 },	{ TARGET_CRDLY, TARGET_CR2, CRDLY, CR2 },	{ TARGET_CRDLY, TARGET_CR3, CRDLY, CR3 },	{ TARGET_TABDLY, TARGET_TAB0, TABDLY, TAB0 },	{ TARGET_TABDLY, TARGET_TAB1, TABDLY, TAB1 },	{ TARGET_TABDLY, TARGET_TAB2, TABDLY, TAB2 },	{ TARGET_TABDLY, TARGET_TAB3, TABDLY, TAB3 },	{ TARGET_BSDLY, TARGET_BS0, BSDLY, BS0 },	{ TARGET_BSDLY, TARGET_BS1, BSDLY, BS1 },	{ TARGET_VTDLY, TARGET_VT0, VTDLY, VT0 },	{ TARGET_VTDLY, TARGET_VT1, VTDLY, VT1 },	{ TARGET_FFDLY, TARGET_FF0, FFDLY, FF0 },	{ TARGET_FFDLY, TARGET_FF1, FFDLY, FF1 },	{ 0, 0, 0, 0 }};bitmask_transtbl cflag_tbl[] = {	{ TARGET_CBAUD, TARGET_B0, CBAUD, B0 },	{ TARGET_CBAUD, TARGET_B50, CBAUD, B50 },	{ TARGET_CBAUD, TARGET_B75, CBAUD, B75 },	{ TARGET_CBAUD, TARGET_B110, CBAUD, B110 },	{ TARGET_CBAUD, TARGET_B134, CBAUD, B134 },	{ TARGET_CBAUD, TARGET_B150, CBAUD, B150 },	{ TARGET_CBAUD, TARGET_B200, CBAUD, B200 },	{ TARGET_CBAUD, TARGET_B300, CBAUD, B300 },	{ TARGET_CBAUD, TARGET_B600, CBAUD, B600 },	{ TARGET_CBAUD, TARGET_B1200, CBAUD, B1200 },	{ TARGET_CBAUD, TARGET_B1800, CBAUD, B1800 },	{ TARGET_CBAUD, TARGET_B2400, CBAUD, B2400 },	{ TARGET_CBAUD, TARGET_B4800, CBAUD, B4800 },	{ TARGET_CBAUD, TARGET_B9600, CBAUD, B9600 },	{ TARGET_CBAUD, TARGET_B19200, CBAUD, B19200 },	{ TARGET_CBAUD, TARGET_B38400, CBAUD, B38400 },	{ TARGET_CBAUD, TARGET_B57600, CBAUD, B57600 },	{ TARGET_CBAUD, TARGET_B115200, CBAUD, B115200 },	{ TARGET_CBAUD, TARGET_B230400, CBAUD, B230400 },	{ TARGET_CBAUD, TARGET_B460800, CBAUD, B460800 },	{ TARGET_CSIZE, TARGET_CS5, CSIZE, CS5 },	{ TARGET_CSIZE, TARGET_CS6, CSIZE, CS6 },	{ TARGET_CSIZE, TARGET_CS7, CSIZE, CS7 },	{ TARGET_CSIZE, TARGET_CS8, CSIZE, CS8 },	{ TARGET_CSTOPB, TARGET_CSTOPB, CSTOPB, CSTOPB },	{ TARGET_CREAD, TARGET_CREAD, CREAD, CREAD },	{ TARGET_PARENB, TARGET_PARENB, PARENB, PARENB },	{ TARGET_PARODD, TARGET_PARODD, PARODD, PARODD },	{ TARGET_HUPCL, TARGET_HUPCL, HUPCL, HUPCL },	{ TARGET_CLOCAL, TARGET_CLOCAL, CLOCAL, CLOCAL },	{ TARGET_CRTSCTS, TARGET_CRTSCTS, CRTSCTS, CRTSCTS },	{ 0, 0, 0, 0 }};bitmask_transtbl lflag_tbl[] = {	{ TARGET_ISIG, TARGET_ISIG, ISIG, ISIG },	{ TARGET_ICANON, TARGET_ICANON, ICANON, ICANON },	{ TARGET_XCASE, TARGET_XCASE, XCASE, XCASE },	{ TARGET_ECHO, TARGET_ECHO, ECHO, ECHO },	{ TARGET_ECHOE, TARGET_ECHOE, ECHOE, ECHOE },	{ TARGET_ECHOK, TARGET_ECHOK, ECHOK, ECHOK },	{ TARGET_ECHONL, TARGET_ECHONL, ECHONL, ECHONL },	{ TARGET_NOFLSH, TARGET_NOFLSH, NOFLSH, NOFLSH },	{ TARGET_TOSTOP, TARGET_TOSTOP, TOSTOP, TOSTOP },	{ TARGET_ECHOCTL, TARGET_ECHOCTL, ECHOCTL, ECHOCTL },	{ TARGET_ECHOPRT, TARGET_ECHOPRT, ECHOPRT, ECHOPRT },	{ TARGET_ECHOKE, TARGET_ECHOKE, ECHOKE, ECHOKE },	{ TARGET_FLUSHO, TARGET_FLUSHO, FLUSHO, FLUSHO },	{ TARGET_PENDIN, TARGET_PENDIN, PENDIN, PENDIN },	{ TARGET_IEXTEN, TARGET_IEXTEN, IEXTEN, IEXTEN },	{ 0, 0, 0, 0 }};static void target_to_host_termios (void *dst, const void *src){    struct host_termios *host = dst;    const struct target_termios *target = src;        host->c_iflag =         target_to_host_bitmask(tswap32(target->c_iflag), iflag_tbl);    host->c_oflag =         target_to_host_bitmask(tswap32(target->c_oflag), oflag_tbl);    host->c_cflag =         target_to_host_bitmask(tswap32(target->c_cflag), cflag_tbl);    host->c_lflag =         target_to_host_bitmask(tswap32(target->c_lflag), lflag_tbl);    host->c_line = target->c_line;        host->c_cc[VINTR] = target->c_cc[TARGET_VINTR];     host->c_cc[VQUIT] = target->c_cc[TARGET_VQUIT];     host->c_cc[VERASE] = target->c_cc[TARGET_VERASE];           host->c_cc[VKILL] = target->c_cc[TARGET_VKILL];     host->c_cc[VEOF] = target->c_cc[TARGET_VEOF];       host->c_cc[VTIME] = target->c_cc[TARGET_VTIME];     host->c_cc[VMIN] = target->c_cc[TARGET_VMIN];       host->c_cc[VSWTC] = target->c_cc[TARGET_VSWTC];     host->c_cc[VSTART] = target->c_cc[TARGET_VSTART];           host->c_cc[VSTOP] = target->c_cc[TARGET_VSTOP];     host->c_cc[VSUSP] = target->c_cc[TARGET_VSUSP];     host->c_cc[VEOL] = target->c_cc[TARGET_VEOL];       host->c_cc[VREPRINT] = target->c_cc[TARGET_VREPRINT];       host->c_cc[VDISCARD] = target->c_cc[TARGET_VDISCARD];       host->c_cc[VWERASE] = target->c_cc[TARGET_VWERASE];         host->c_cc[VLNEXT] = target->c_cc[TARGET_VLNEXT];           host->c_cc[VEOL2] = target->c_cc[TARGET_VEOL2]; }  static void host_to_target_termios (void *dst, const void *src){    struct target_termios *target = dst;    const struct host_termios *host = src;    target->c_iflag =         tswap32(host_to_target_bitmask(host->c_iflag, iflag_tbl));    target->c_oflag =         tswap32(host_to_target_bitmask(host->c_oflag, oflag_tbl));    target->c_cflag =         tswap32(host_to_target_bitmask(host->c_cflag, cflag_tbl));    target->c_lflag =         tswap32(host_to_target_bitmask(host->c_lflag, lflag_tbl));    target->c_line = host->c_line;      target->c_cc[TARGET_VINTR] = host->c_cc[VINTR];    target->c_cc[TARGET_VQUIT] = host->c_cc[VQUIT];    target->c_cc[TARGET_VERASE] = host->c_cc[VERASE];    target->c_cc[TARGET_VKILL] = host->c_cc[VKILL];    target->c_cc[TARGET_VEOF] = host->c_cc[VEOF];    target->c_cc[TARGET_VTIME] = host->c_cc[VTIME];    target->c_cc[TARGET_VMIN] = host->c_cc[VMIN];    target->c_cc[TARGET_VSWTC] = host->c_cc[VSWTC];    target->c_cc[TARGET_VSTART] = host->c_cc[VSTART];    target->c_cc[TARGET_VSTOP] = host->c_cc[VSTOP];    target->c_cc[TARGET_VSUSP] = host->c_cc[VSUSP];    target->c_cc[TARGET_VEOL] = host->c_cc[VEOL];    target->c_cc[TARGET_VREPRINT] = host->c_cc[VREPRINT];    target->c_cc[TARGET_VDISCARD] = host->c_cc[VDISCARD];    target->c_cc[TARGET_VWERASE] = host->c_cc[VWERASE];    target->c_cc[TARGET_VLNEXT] = host->c_cc[VLNEXT];    target->c_cc[TARGET_VEOL2] = host->c_cc[VEOL2];}StructEntry struct_termios_def = {    .convert = { host_to_target_termios, target_to_host_termios },    .size = { sizeof(struct target_termios), sizeof(struct host_termios) },    .align = { __alignof__(struct target_termios), __alignof__(struct host_termios) },};static bitmask_transtbl mmap_flags_tbl[] = {	{ TARGET_MAP_SHARED, TARGET_MAP_SHARED, MAP_SHARED, MAP_SHARED },	{ TARGET_MAP_PRIVATE, TARGET_MAP_PRIVATE, MAP_PRIVATE, MAP_PRIVATE },	{ TARGET_MAP_FIXED, TARGET_MAP_FIXED, MAP_FIXED, MAP_FIXED },	{ TARGET_MAP_ANONYMOUS, TARGET_MAP_ANONYMOUS, MAP_ANONYMOUS, MAP_ANONYMOUS },	{ TARGET_MAP_GROWSDOWN, TARGET_MAP_GROWSDOWN, MAP_GROWSDOWN, MAP_GROWSDOWN },	{ TARGET_MAP_DENYWRITE, TARGET_MAP_DENYWRITE, MAP_DENYWRITE, MAP_DENYWRITE },	{ TARGET_MAP_EXECUTABLE, TARGET_MAP_EXECUTABLE, MAP_EXECUTABLE, MAP_EXECUTABLE },	{ TARGET_MAP_LOCKED, TARGET_MAP_LOCKED, MAP_LOCKED, MAP_LOCKED },	{ 0, 0, 0, 0 }};static bitmask_transtbl fcntl_flags_tbl[] = {	{ TARGET_O_ACCMODE,   TARGET_O_WRONLY,    O_ACCMODE,   O_WRONLY,    },	{ TARGET_O_ACCMODE,   TARGET_O_RDWR,      O_ACCMODE,   O_RDWR,      },	{ TARGET_O_CREAT,     TARGET_O_CREAT,     O_CREAT,     O_CREAT,     },	{ TARGET_O_EXCL,      TARGET_O_EXCL,      O_EXCL,      O_EXCL,      },	{ TARGET_O_NOCTTY,    TARGET_O_NOCTTY,    O_NOCTTY,    O_NOCTTY,    },	{ TARGET_O_TRUNC,     TARGET_O_TRUNC,     O_TRUNC,     O_TRUNC,     },	{ TARGET_O_APPEND,    TARGET_O_APPEND,    O_APPEND,    O_APPEND,    },	{ TARGET_O_NONBLOCK,  TARGET_O_NONBLOCK,  O_NONBLOCK,  O_NONBLOCK,  },	{ TARGET_O_SYNC,      TARGET_O_SYNC,      O_SYNC,      O_SYNC,      },	{ TARGET_FASYNC,      TARGET_FASYNC,      FASYNC,      FASYNC,      },	{ TARGET_O_DIRECTORY, TARGET_O_DIRECTORY, O_DIRECTORY, O_DIRECTORY, },	{ TARGET_O_NOFOLLOW,  TARGET_O_NOFOLLOW,  O_NOFOLLOW,  O_NOFOLLOW,  },	{ TARGET_O_LARGEFILE, TARGET_O_LARGEFILE, O_LARGEFILE, O_LARGEFILE, },#if defined(O_DIRECT)	{ TARGET_O_DIRECT,    TARGET_O_DIRECT,    O_DIRECT,    O_DIRECT,    },#endif	{ 0, 0, 0, 0 }};#if defined(TARGET_I386)/* NOTE: there is really one LDT for all the threads */uint8_t *ldt_table;static int read_ldt(target_ulong ptr, unsigned long bytecount){    int size;    void *p;    if (!ldt_table)        return 0;    size = TARGET_LDT_ENTRIES * TARGET_LDT_ENTRY_SIZE;    if (size > bytecount)        size = bytecount;    p = lock_user(ptr, size, 0);    /* ??? Shoudl this by byteswapped?  */    memcpy(p, ldt_table, size);    unlock_user(p, ptr, size);    return size;}/* XXX: add locking support */static int write_ldt(CPUX86State *env,                      target_ulong ptr, unsigned long bytecount, int oldmode){    struct target_modify_ldt_ldt_s ldt_info;    struct target_modify_ldt_ldt_s *target_ldt_info;    int seg_32bit, contents, read_exec_only, limit_in_pages;    int seg_not_present, useable;    uint32_t *lp, entry_1, entry_2;    if (bytecount != sizeof(ldt_info))        return -EINVAL;    lock_user_struct(target_ldt_info, ptr, 1);    ldt_info.entry_number = tswap32(target_ldt_info->entry_number);    ldt_info.base_addr = tswapl(target_ldt_info->base_addr);    ldt_info.limit = tswap32(target_ldt_info->limit);    ldt_info.flags = tswap32(target_ldt_info->flags);    unlock_user_struct(target_ldt_info, ptr, 0);        if (ldt_info.entry_number >= TARGET_LDT_ENTRIES)        return -EINVAL;    seg_32bit = ldt_info.flags & 1;    contents = (ldt_info.flags >> 1) & 3;    read_exec_only = (ldt_info.flags >> 3) & 1;    limit_in_pages = (ldt_info.flags >> 4) & 1;    seg_not_present = (ldt_info.flags >> 5) & 1;    useable = (ldt_info.flags >> 6) & 1;    if (contents == 3) {        if (oldmode)            return -EINVAL;        if (seg_not_present == 0)            return -EINVAL;    }    /* allocate the LDT */    if (!ldt_table) {        ldt_table = malloc(TARGET_LDT_ENTRIES * TARGET_LDT_ENTRY_SIZE);        if (!ldt_table)            return -ENOMEM;        memset(ldt_table, 0, TARGET_LDT_ENTRIES * TARGET_LDT_ENTRY_SIZE);        env->ldt.base = h2g(ldt_table);        env->ldt.limit = 0xffff;    }    /* NOTE: same code as Linux kernel */    /* Allow LDTs to be cleared by the user. */    if (ldt_info.base_addr == 0 && ldt_info.limit == 0) {        if (oldmode ||            (contents == 0		&&             read_exec_only == 1	&&             seg_32bit == 0		&&             limit_in_pages == 0	&&             seg_not_present == 1	&&             useable == 0 )) {            entry_1 = 0;            entry_2 = 0;            goto install;        }    }        entry_1 = ((ldt_info.base_addr & 0x0000ffff) << 16) |        (ldt_info.limit & 0x0ffff);    entry_2 = (ldt_info.base_addr & 0xff000000) |        ((ldt_info.base_addr & 0x00ff0000) >> 16) |        (ldt_info.limit & 0xf0000) |        ((read_exec_only ^ 1) << 9) |        (contents << 10) |        ((seg_not_present ^ 1) << 15) |        (seg_32bit << 22) |        (limit_in_pages << 23) |        0x7000;    if (!oldmode)        entry_2 |= (useable << 20);    /* Install the new entry ...  */install:    lp = (uint32_t *)(ldt_table + (ldt_info.entry_number << 3));    lp[0] = tswap32(entry_1);    lp[1] = tswap32(entry_2);    return 0;}/* specific and weird i386 syscalls */int do_modify_ldt(CPUX86State *env, int func, target_ulong ptr, unsigned long bytecount){    int ret = -ENOSYS;        switch (func) {    case 0:        ret = read_ldt(ptr, bytecount);        break;    case 1:        ret = write_ldt(env, ptr, bytecount, 1);        break;    case 0x11:        ret = write_ldt(env, ptr, bytecount, 0);        break;    }    return ret;}#endif /* defined(TARGET_I386) *//* this stack is the equivalent of the kernel stack associated with a   thread/process */#define NEW_STACK_SIZE 8192static int clone_func(void *arg){    CPUState *env = arg;    cpu_loop(env);    /* never exits */    return 0;}int do_fork(CPUState *env, unsigned int flags, unsigned long newsp){    int ret;    TaskState *ts;    uint8_t *new_stack;    CPUState *new_env;        if (flags & CLONE_VM) {        ts = malloc(sizeof(TaskState) + NEW_STACK_SIZE);        memset(ts, 0, sizeof(TaskState));        new_stack = ts->stack;        ts->used = 1;        /* add in task state list */        ts->next = first_task_state;        first_task_state = ts;        /* we create a new CPU instance. */        new_env = cpu_init();        memcpy(new_env, env, sizeof(CPUState));#if defined(TARGET_I386)        if (!newsp)            newsp = env->regs[R_ESP];        new_env->regs[R_ESP] = newsp;        new_env->regs[R_EAX] = 0;#elif defined(TARGET_ARM)        if (!newsp)            newsp = env->regs[13];        new_env->regs[13] = newsp;        new_env->regs[0] = 0;#elif defined(TARGET_SPARC)        if (!newsp)            newsp = env->regwptr[22];        new_env->regwptr[22] = newsp;        new_env->regwptr[0] = 0;	/* XXXXX */        printf ("HELPME: %s:%d\n", __FILE__, __LINE__);#elif defined(TARGET_M68K)        if (!newsp)

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -