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

📄 vm86.c

📁 qemu虚拟机代码
💻 C
📖 第 1 页 / 共 2 页
字号:
/* *  vm86 linux syscall support *  *  Copyright (c) 2003 Fabrice Bellard * *  This program is free software; you can redistribute it and/or modify *  it under the terms of the GNU General Public License as published by *  the Free Software Foundation; either version 2 of the License, or *  (at your option) any later version. * *  This program is distributed in the hope that it will be useful, *  but WITHOUT ANY WARRANTY; without even the implied warranty of *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the *  GNU General Public License for more details. * *  You should have received a copy of the GNU General Public License *  along with this program; if not, write to the Free Software *  Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */#include <stdlib.h>#include <stdio.h>#include <stdarg.h>#include <string.h>#include <errno.h>#include <unistd.h>#include "qemu.h"//#define DEBUG_VM86#define set_flags(X,new,mask) \((X) = ((X) & ~(mask)) | ((new) & (mask)))#define SAFE_MASK	(0xDD5)#define RETURN_MASK	(0xDFF)static inline int is_revectored(int nr, struct target_revectored_struct *bitmap){    return (((uint8_t *)bitmap)[nr >> 3] >> (nr & 7)) & 1;}static inline void vm_putw(uint8_t *segptr, unsigned int reg16, unsigned int val){    stw(segptr + (reg16 & 0xffff), val);}static inline void vm_putl(uint8_t *segptr, unsigned int reg16, unsigned int val){    stl(segptr + (reg16 & 0xffff), val);}static inline unsigned int vm_getw(uint8_t *segptr, unsigned int reg16){    return lduw(segptr + (reg16 & 0xffff));}static inline unsigned int vm_getl(uint8_t *segptr, unsigned int reg16){    return ldl(segptr + (reg16 & 0xffff));}void save_v86_state(CPUX86State *env){    TaskState *ts = env->opaque;    struct target_vm86plus_struct * target_v86;    lock_user_struct(target_v86, ts->target_v86, 0);    /* put the VM86 registers in the userspace register structure */    target_v86->regs.eax = tswap32(env->regs[R_EAX]);    target_v86->regs.ebx = tswap32(env->regs[R_EBX]);    target_v86->regs.ecx = tswap32(env->regs[R_ECX]);    target_v86->regs.edx = tswap32(env->regs[R_EDX]);    target_v86->regs.esi = tswap32(env->regs[R_ESI]);    target_v86->regs.edi = tswap32(env->regs[R_EDI]);    target_v86->regs.ebp = tswap32(env->regs[R_EBP]);    target_v86->regs.esp = tswap32(env->regs[R_ESP]);    target_v86->regs.eip = tswap32(env->eip);    target_v86->regs.cs = tswap16(env->segs[R_CS].selector);    target_v86->regs.ss = tswap16(env->segs[R_SS].selector);    target_v86->regs.ds = tswap16(env->segs[R_DS].selector);    target_v86->regs.es = tswap16(env->segs[R_ES].selector);    target_v86->regs.fs = tswap16(env->segs[R_FS].selector);    target_v86->regs.gs = tswap16(env->segs[R_GS].selector);    set_flags(env->eflags, ts->v86flags, VIF_MASK | ts->v86mask);    target_v86->regs.eflags = tswap32(env->eflags);    unlock_user_struct(target_v86, ts->target_v86, 1);#ifdef DEBUG_VM86    fprintf(logfile, "save_v86_state: eflags=%08x cs:ip=%04x:%04x\n",             env->eflags, env->segs[R_CS].selector, env->eip);#endif    /* restore 32 bit registers */    env->regs[R_EAX] = ts->vm86_saved_regs.eax;    env->regs[R_EBX] = ts->vm86_saved_regs.ebx;    env->regs[R_ECX] = ts->vm86_saved_regs.ecx;    env->regs[R_EDX] = ts->vm86_saved_regs.edx;    env->regs[R_ESI] = ts->vm86_saved_regs.esi;    env->regs[R_EDI] = ts->vm86_saved_regs.edi;    env->regs[R_EBP] = ts->vm86_saved_regs.ebp;    env->regs[R_ESP] = ts->vm86_saved_regs.esp;    env->eflags = ts->vm86_saved_regs.eflags;    env->eip = ts->vm86_saved_regs.eip;    cpu_x86_load_seg(env, R_CS, ts->vm86_saved_regs.cs);    cpu_x86_load_seg(env, R_SS, ts->vm86_saved_regs.ss);    cpu_x86_load_seg(env, R_DS, ts->vm86_saved_regs.ds);    cpu_x86_load_seg(env, R_ES, ts->vm86_saved_regs.es);    cpu_x86_load_seg(env, R_FS, ts->vm86_saved_regs.fs);    cpu_x86_load_seg(env, R_GS, ts->vm86_saved_regs.gs);}/* return from vm86 mode to 32 bit. The vm86() syscall will return   'retval' */static inline void return_to_32bit(CPUX86State *env, int retval){#ifdef DEBUG_VM86    fprintf(logfile, "return_to_32bit: ret=0x%x\n", retval);#endif    save_v86_state(env);    env->regs[R_EAX] = retval;}static inline int set_IF(CPUX86State *env){    TaskState *ts = env->opaque;        ts->v86flags |= VIF_MASK;    if (ts->v86flags & VIP_MASK) {        return_to_32bit(env, TARGET_VM86_STI);        return 1;    }    return 0;}static inline void clear_IF(CPUX86State *env){    TaskState *ts = env->opaque;    ts->v86flags &= ~VIF_MASK;}static inline void clear_TF(CPUX86State *env){    env->eflags &= ~TF_MASK;}static inline void clear_AC(CPUX86State *env){    env->eflags &= ~AC_MASK;}static inline int set_vflags_long(unsigned long eflags, CPUX86State *env){    TaskState *ts = env->opaque;    set_flags(ts->v86flags, eflags, ts->v86mask);    set_flags(env->eflags, eflags, SAFE_MASK);    if (eflags & IF_MASK)        return set_IF(env);    else        clear_IF(env);    return 0;}static inline int set_vflags_short(unsigned short flags, CPUX86State *env){    TaskState *ts = env->opaque;    set_flags(ts->v86flags, flags, ts->v86mask & 0xffff);    set_flags(env->eflags, flags, SAFE_MASK);    if (flags & IF_MASK)        return set_IF(env);    else        clear_IF(env);    return 0;}static inline unsigned int get_vflags(CPUX86State *env){    TaskState *ts = env->opaque;    unsigned int flags;    flags = env->eflags & RETURN_MASK;    if (ts->v86flags & VIF_MASK)        flags |= IF_MASK;    flags |= IOPL_MASK;    return flags | (ts->v86flags & ts->v86mask);}#define ADD16(reg, val) reg = (reg & ~0xffff) | ((reg + (val)) & 0xffff)/* handle VM86 interrupt (NOTE: the CPU core currently does not   support TSS interrupt revectoring, so this code is always executed) */static void do_int(CPUX86State *env, int intno){    TaskState *ts = env->opaque;    uint32_t *int_ptr, segoffs;    uint8_t *ssp;    unsigned int sp;    if (env->segs[R_CS].selector == TARGET_BIOSSEG)        goto cannot_handle;    if (is_revectored(intno, &ts->vm86plus.int_revectored))        goto cannot_handle;    if (intno == 0x21 && is_revectored((env->regs[R_EAX] >> 8) & 0xff,                                        &ts->vm86plus.int21_revectored))        goto cannot_handle;    int_ptr = (uint32_t *)(intno << 2);    segoffs = tswap32(*int_ptr);    if ((segoffs >> 16) == TARGET_BIOSSEG)        goto cannot_handle;#if defined(DEBUG_VM86)    fprintf(logfile, "VM86: emulating int 0x%x. CS:IP=%04x:%04x\n",             intno, segoffs >> 16, segoffs & 0xffff);#endif    /* save old state */    ssp = (uint8_t *)(env->segs[R_SS].selector << 4);    sp = env->regs[R_ESP] & 0xffff;    vm_putw(ssp, sp - 2, get_vflags(env));    vm_putw(ssp, sp - 4, env->segs[R_CS].selector);    vm_putw(ssp, sp - 6, env->eip);    ADD16(env->regs[R_ESP], -6);    /* goto interrupt handler */    env->eip = segoffs & 0xffff;    cpu_x86_load_seg(env, R_CS, segoffs >> 16);    clear_TF(env);    clear_IF(env);    clear_AC(env);    return; cannot_handle:#if defined(DEBUG_VM86)    fprintf(logfile, "VM86: return to 32 bits int 0x%x\n", intno);#endif    return_to_32bit(env, TARGET_VM86_INTx | (intno << 8));}void handle_vm86_trap(CPUX86State *env, int trapno){    if (trapno == 1 || trapno == 3) {        return_to_32bit(env, TARGET_VM86_TRAP + (trapno << 8));    } else {        do_int(env, trapno);

⌨️ 快捷键说明

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