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

📄 vm86.c

📁 qemu虚拟机代码
💻 C
📖 第 1 页 / 共 2 页
字号:
    }}#define CHECK_IF_IN_TRAP() \      if ((ts->vm86plus.vm86plus.flags & TARGET_vm86dbg_active) && \          (ts->vm86plus.vm86plus.flags & TARGET_vm86dbg_TFpendig)) \		newflags |= TF_MASK#define VM86_FAULT_RETURN \        if ((ts->vm86plus.vm86plus.flags & TARGET_force_return_for_pic) && \            (ts->v86flags & (IF_MASK | VIF_MASK))) \            return_to_32bit(env, TARGET_VM86_PICRETURN); \        returnvoid handle_vm86_fault(CPUX86State *env){    TaskState *ts = env->opaque;    uint8_t *csp, *pc, *ssp;    unsigned int ip, sp, newflags, newip, newcs, opcode, intno;    int data32, pref_done;    csp = (uint8_t *)(env->segs[R_CS].selector << 4);    ip = env->eip & 0xffff;    pc = csp + ip;        ssp = (uint8_t *)(env->segs[R_SS].selector << 4);    sp = env->regs[R_ESP] & 0xffff;#if defined(DEBUG_VM86)    fprintf(logfile, "VM86 exception %04x:%08x %02x %02x\n",            env->segs[R_CS].selector, env->eip, pc[0], pc[1]);#endif    data32 = 0;    pref_done = 0;    do {        opcode = csp[ip];        ADD16(ip, 1);        switch (opcode) {        case 0x66:      /* 32-bit data */     data32=1; break;        case 0x67:      /* 32-bit address */  break;        case 0x2e:      /* CS */              break;        case 0x3e:      /* DS */              break;        case 0x26:      /* ES */              break;        case 0x36:      /* SS */              break;        case 0x65:      /* GS */              break;        case 0x64:      /* FS */              break;        case 0xf2:      /* repnz */	      break;        case 0xf3:      /* rep */             break;        default: pref_done = 1;        }    } while (!pref_done);    /* VM86 mode */    switch(opcode) {    case 0x9c: /* pushf */        if (data32) {            vm_putl(ssp, sp - 4, get_vflags(env));            ADD16(env->regs[R_ESP], -4);        } else {            vm_putw(ssp, sp - 2, get_vflags(env));            ADD16(env->regs[R_ESP], -2);        }        env->eip = ip;        VM86_FAULT_RETURN;    case 0x9d: /* popf */        if (data32) {            newflags = vm_getl(ssp, sp);            ADD16(env->regs[R_ESP], 4);        } else {            newflags = vm_getw(ssp, sp);            ADD16(env->regs[R_ESP], 2);        }        env->eip = ip;        CHECK_IF_IN_TRAP();        if (data32) {            if (set_vflags_long(newflags, env))                return;        } else {            if (set_vflags_short(newflags, env))                return;        }        VM86_FAULT_RETURN;    case 0xcd: /* int */        intno = csp[ip];        ADD16(ip, 1);        env->eip = ip;        if (ts->vm86plus.vm86plus.flags & TARGET_vm86dbg_active) {            if ( (ts->vm86plus.vm86plus.vm86dbg_intxxtab[intno >> 3] >>                   (intno &7)) & 1) {                return_to_32bit(env, TARGET_VM86_INTx + (intno << 8));                return;            }        }        do_int(env, intno);        break;    case 0xcf: /* iret */        if (data32) {            newip = vm_getl(ssp, sp) & 0xffff;            newcs = vm_getl(ssp, sp + 4) & 0xffff;            newflags = vm_getl(ssp, sp + 8);            ADD16(env->regs[R_ESP], 12);        } else {            newip = vm_getw(ssp, sp);            newcs = vm_getw(ssp, sp + 2);            newflags = vm_getw(ssp, sp + 4);            ADD16(env->regs[R_ESP], 6);        }        env->eip = newip;        cpu_x86_load_seg(env, R_CS, newcs);        CHECK_IF_IN_TRAP();        if (data32) {            if (set_vflags_long(newflags, env))                return;        } else {            if (set_vflags_short(newflags, env))                return;        }        VM86_FAULT_RETURN;            case 0xfa: /* cli */        env->eip = ip;        clear_IF(env);        VM86_FAULT_RETURN;            case 0xfb: /* sti */        env->eip = ip;        if (set_IF(env))            return;        VM86_FAULT_RETURN;    default:        /* real VM86 GPF exception */        return_to_32bit(env, TARGET_VM86_UNKNOWN);        break;    }}int do_vm86(CPUX86State *env, long subfunction, target_ulong vm86_addr){    TaskState *ts = env->opaque;    struct target_vm86plus_struct * target_v86;    int ret;        switch (subfunction) {    case TARGET_VM86_REQUEST_IRQ:    case TARGET_VM86_FREE_IRQ:    case TARGET_VM86_GET_IRQ_BITS:    case TARGET_VM86_GET_AND_RESET_IRQ:        gemu_log("qemu: unsupported vm86 subfunction (%ld)\n", subfunction);        ret = -EINVAL;        goto out;    case TARGET_VM86_PLUS_INSTALL_CHECK:        /* NOTE: on old vm86 stuff this will return the error           from verify_area(), because the subfunction is           interpreted as (invalid) address to vm86_struct.           So the installation check works.            */        ret = 0;        goto out;    }    /* save current CPU regs */    ts->vm86_saved_regs.eax = 0; /* default vm86 syscall return code */    ts->vm86_saved_regs.ebx = env->regs[R_EBX];    ts->vm86_saved_regs.ecx = env->regs[R_ECX];    ts->vm86_saved_regs.edx = env->regs[R_EDX];    ts->vm86_saved_regs.esi = env->regs[R_ESI];    ts->vm86_saved_regs.edi = env->regs[R_EDI];    ts->vm86_saved_regs.ebp = env->regs[R_EBP];    ts->vm86_saved_regs.esp = env->regs[R_ESP];    ts->vm86_saved_regs.eflags = env->eflags;    ts->vm86_saved_regs.eip  = env->eip;    ts->vm86_saved_regs.cs = env->segs[R_CS].selector;    ts->vm86_saved_regs.ss = env->segs[R_SS].selector;    ts->vm86_saved_regs.ds = env->segs[R_DS].selector;    ts->vm86_saved_regs.es = env->segs[R_ES].selector;    ts->vm86_saved_regs.fs = env->segs[R_FS].selector;    ts->vm86_saved_regs.gs = env->segs[R_GS].selector;    ts->target_v86 = vm86_addr;    lock_user_struct(target_v86, vm86_addr, 1);    /* build vm86 CPU state */    ts->v86flags = tswap32(target_v86->regs.eflags);    env->eflags = (env->eflags & ~SAFE_MASK) |         (tswap32(target_v86->regs.eflags) & SAFE_MASK) | VM_MASK;    ts->vm86plus.cpu_type = tswapl(target_v86->cpu_type);    switch (ts->vm86plus.cpu_type) {    case TARGET_CPU_286:        ts->v86mask = 0;        break;    case TARGET_CPU_386:        ts->v86mask = NT_MASK | IOPL_MASK;        break;    case TARGET_CPU_486:        ts->v86mask = AC_MASK | NT_MASK | IOPL_MASK;        break;    default:        ts->v86mask = ID_MASK | AC_MASK | NT_MASK | IOPL_MASK;        break;    }    env->regs[R_EBX] = tswap32(target_v86->regs.ebx);    env->regs[R_ECX] = tswap32(target_v86->regs.ecx);    env->regs[R_EDX] = tswap32(target_v86->regs.edx);    env->regs[R_ESI] = tswap32(target_v86->regs.esi);    env->regs[R_EDI] = tswap32(target_v86->regs.edi);    env->regs[R_EBP] = tswap32(target_v86->regs.ebp);    env->regs[R_ESP] = tswap32(target_v86->regs.esp);    env->eip = tswap32(target_v86->regs.eip);    cpu_x86_load_seg(env, R_CS, tswap16(target_v86->regs.cs));    cpu_x86_load_seg(env, R_SS, tswap16(target_v86->regs.ss));    cpu_x86_load_seg(env, R_DS, tswap16(target_v86->regs.ds));    cpu_x86_load_seg(env, R_ES, tswap16(target_v86->regs.es));    cpu_x86_load_seg(env, R_FS, tswap16(target_v86->regs.fs));    cpu_x86_load_seg(env, R_GS, tswap16(target_v86->regs.gs));    ret = tswap32(target_v86->regs.eax); /* eax will be restored at                                            the end of the syscall */    memcpy(&ts->vm86plus.int_revectored,            &target_v86->int_revectored, 32);    memcpy(&ts->vm86plus.int21_revectored,            &target_v86->int21_revectored, 32);    ts->vm86plus.vm86plus.flags = tswapl(target_v86->vm86plus.flags);    memcpy(&ts->vm86plus.vm86plus.vm86dbg_intxxtab,            target_v86->vm86plus.vm86dbg_intxxtab, 32);    unlock_user_struct(target_v86, vm86_addr, 0);    #ifdef DEBUG_VM86    fprintf(logfile, "do_vm86: cs:ip=%04x:%04x\n",             env->segs[R_CS].selector, env->eip);#endif    /* now the virtual CPU is ready for vm86 execution ! */ out:    return ret;}

⌨️ 快捷键说明

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