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

📄 helper2.c

📁 qemu虚拟机代码
💻 C
📖 第 1 页 / 共 3 页
字号:
/* *  i386 helpers (without register variable usage) *  *  Copyright (c) 2003 Fabrice Bellard * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2 of the License, or (at your option) any later version. * * This library 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 * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA */#include <stdarg.h>#include <stdlib.h>#include <stdio.h>#include <string.h>#include <inttypes.h>#include <signal.h>#include <assert.h>#include "cpu.h"#include "exec-all.h"//#define DEBUG_MMU#ifdef USE_CODE_COPY#include <asm/ldt.h>#include <linux/unistd.h>#include <linux/version.h>_syscall3(int, modify_ldt, int, func, void *, ptr, unsigned long, bytecount)#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 5, 66)#define modify_ldt_ldt_s user_desc#endif#endif /* USE_CODE_COPY */CPUX86State *cpu_x86_init(void){    CPUX86State *env;    static int inited;    env = qemu_mallocz(sizeof(CPUX86State));    if (!env)        return NULL;    cpu_exec_init(env);    /* init various static tables */    if (!inited) {        inited = 1;        optimize_flags_init();    }#ifdef USE_CODE_COPY    /* testing code for code copy case */    {        struct modify_ldt_ldt_s ldt;        ldt.entry_number = 1;        ldt.base_addr = (unsigned long)env;        ldt.limit = (sizeof(CPUState) + 0xfff) >> 12;        ldt.seg_32bit = 1;        ldt.contents = MODIFY_LDT_CONTENTS_DATA;        ldt.read_exec_only = 0;        ldt.limit_in_pages = 1;        ldt.seg_not_present = 0;        ldt.useable = 1;        modify_ldt(1, &ldt, sizeof(ldt)); /* write ldt entry */                asm volatile ("movl %0, %%fs" : : "r" ((1 << 3) | 7));    }#endif    {        int family, model, stepping;#ifdef TARGET_X86_64        env->cpuid_vendor1 = 0x68747541; /* "Auth" */        env->cpuid_vendor2 = 0x69746e65; /* "enti" */        env->cpuid_vendor3 = 0x444d4163; /* "cAMD" */        family = 6;        model = 2;        stepping = 3;#else        env->cpuid_vendor1 = 0x756e6547; /* "Genu" */        env->cpuid_vendor2 = 0x49656e69; /* "ineI" */        env->cpuid_vendor3 = 0x6c65746e; /* "ntel" */#if 0        /* pentium 75-200 */        family = 5;        model = 2;        stepping = 11;#else        /* pentium pro */        family = 6;        model = 3;        stepping = 3;#endif#endif        env->cpuid_level = 2;        env->cpuid_version = (family << 8) | (model << 4) | stepping;        env->cpuid_features = (CPUID_FP87 | CPUID_DE | CPUID_PSE |                               CPUID_TSC | CPUID_MSR | CPUID_MCE |                               CPUID_CX8 | CPUID_PGE | CPUID_CMOV |                               CPUID_PAT);        env->pat = 0x0007040600070406ULL;        env->cpuid_ext_features = CPUID_EXT_SSE3;        env->cpuid_features |= CPUID_FXSR | CPUID_MMX | CPUID_SSE | CPUID_SSE2 | CPUID_PAE | CPUID_SEP;        env->cpuid_features |= CPUID_APIC;        env->cpuid_xlevel = 0;        {            const char *model_id = "QEMU Virtual CPU version " QEMU_VERSION;            int c, len, i;            len = strlen(model_id);            for(i = 0; i < 48; i++) {                if (i >= len)                    c = '\0';                else                    c = model_id[i];                env->cpuid_model[i >> 2] |= c << (8 * (i & 3));            }        }#ifdef TARGET_X86_64        /* currently not enabled for std i386 because not fully tested */        env->cpuid_ext2_features = (env->cpuid_features & 0x0183F3FF);        env->cpuid_ext2_features |= CPUID_EXT2_LM | CPUID_EXT2_SYSCALL | CPUID_EXT2_NX;        env->cpuid_xlevel = 0x80000008;        /* these features are needed for Win64 and aren't fully implemented */        env->cpuid_features |= CPUID_MTRR | CPUID_CLFLUSH | CPUID_MCA;#endif    }    cpu_reset(env);#ifdef USE_KQEMU    kqemu_init(env);#endif    return env;}/* NOTE: must be called outside the CPU execute loop */void cpu_reset(CPUX86State *env){    int i;    memset(env, 0, offsetof(CPUX86State, breakpoints));    tlb_flush(env, 1);    /* init to reset state */#ifdef CONFIG_SOFTMMU    env->hflags |= HF_SOFTMMU_MASK;#endif    cpu_x86_update_cr0(env, 0x60000010);    env->a20_mask = 0xffffffff;        env->idt.limit = 0xffff;    env->gdt.limit = 0xffff;    env->ldt.limit = 0xffff;    env->ldt.flags = DESC_P_MASK;    env->tr.limit = 0xffff;    env->tr.flags = DESC_P_MASK;        cpu_x86_load_seg_cache(env, R_CS, 0xf000, 0xffff0000, 0xffff, 0);     cpu_x86_load_seg_cache(env, R_DS, 0, 0, 0xffff, 0);    cpu_x86_load_seg_cache(env, R_ES, 0, 0, 0xffff, 0);    cpu_x86_load_seg_cache(env, R_SS, 0, 0, 0xffff, 0);    cpu_x86_load_seg_cache(env, R_FS, 0, 0, 0xffff, 0);    cpu_x86_load_seg_cache(env, R_GS, 0, 0, 0xffff, 0);        env->eip = 0xfff0;    env->regs[R_EDX] = 0x600; /* indicate P6 processor */        env->eflags = 0x2;        /* FPU init */    for(i = 0;i < 8; i++)        env->fptags[i] = 1;    env->fpuc = 0x37f;    env->mxcsr = 0x1f80;}void cpu_x86_close(CPUX86State *env){    free(env);}/***********************************************************//* x86 debug */static const char *cc_op_str[] = {    "DYNAMIC",    "EFLAGS",    "MULB",    "MULW",    "MULL",    "MULQ",    "ADDB",    "ADDW",    "ADDL",    "ADDQ",    "ADCB",    "ADCW",    "ADCL",    "ADCQ",    "SUBB",    "SUBW",    "SUBL",    "SUBQ",    "SBBB",    "SBBW",    "SBBL",    "SBBQ",    "LOGICB",    "LOGICW",    "LOGICL",    "LOGICQ",    "INCB",    "INCW",    "INCL",    "INCQ",    "DECB",    "DECW",    "DECL",    "DECQ",    "SHLB",    "SHLW",    "SHLL",    "SHLQ",    "SARB",    "SARW",    "SARL",    "SARQ",};void cpu_dump_state(CPUState *env, FILE *f,                     int (*cpu_fprintf)(FILE *f, const char *fmt, ...),                    int flags){    int eflags, i, nb;    char cc_op_name[32];    static const char *seg_name[6] = { "ES", "CS", "SS", "DS", "FS", "GS" };    eflags = env->eflags;#ifdef TARGET_X86_64    if (env->hflags & HF_CS64_MASK) {        cpu_fprintf(f,                     "RAX=%016llx RBX=%016llx RCX=%016llx RDX=%016llx\n"                    "RSI=%016llx RDI=%016llx RBP=%016llx RSP=%016llx\n"                    "R8 =%016llx R9 =%016llx R10=%016llx R11=%016llx\n"                    "R12=%016llx R13=%016llx R14=%016llx R15=%016llx\n"                    "RIP=%016llx RFL=%08x [%c%c%c%c%c%c%c] CPL=%d II=%d A20=%d HLT=%d\n",                    env->regs[R_EAX],                     env->regs[R_EBX],                     env->regs[R_ECX],                     env->regs[R_EDX],                     env->regs[R_ESI],                     env->regs[R_EDI],                     env->regs[R_EBP],                     env->regs[R_ESP],                     env->regs[8],                     env->regs[9],                     env->regs[10],                     env->regs[11],                     env->regs[12],                     env->regs[13],                     env->regs[14],                     env->regs[15],                     env->eip, eflags,                    eflags & DF_MASK ? 'D' : '-',                    eflags & CC_O ? 'O' : '-',                    eflags & CC_S ? 'S' : '-',                    eflags & CC_Z ? 'Z' : '-',                    eflags & CC_A ? 'A' : '-',                    eflags & CC_P ? 'P' : '-',                    eflags & CC_C ? 'C' : '-',                    env->hflags & HF_CPL_MASK,                     (env->hflags >> HF_INHIBIT_IRQ_SHIFT) & 1,                    (env->a20_mask >> 20) & 1,                    (env->hflags >> HF_HALTED_SHIFT) & 1);    } else #endif    {        cpu_fprintf(f, "EAX=%08x EBX=%08x ECX=%08x EDX=%08x\n"                    "ESI=%08x EDI=%08x EBP=%08x ESP=%08x\n"                    "EIP=%08x EFL=%08x [%c%c%c%c%c%c%c] CPL=%d II=%d A20=%d HLT=%d\n",                    (uint32_t)env->regs[R_EAX],                     (uint32_t)env->regs[R_EBX],                     (uint32_t)env->regs[R_ECX],                     (uint32_t)env->regs[R_EDX],                     (uint32_t)env->regs[R_ESI],                     (uint32_t)env->regs[R_EDI],                     (uint32_t)env->regs[R_EBP],                     (uint32_t)env->regs[R_ESP],                     (uint32_t)env->eip, eflags,                    eflags & DF_MASK ? 'D' : '-',                    eflags & CC_O ? 'O' : '-',                    eflags & CC_S ? 'S' : '-',                    eflags & CC_Z ? 'Z' : '-',                    eflags & CC_A ? 'A' : '-',                    eflags & CC_P ? 'P' : '-',                    eflags & CC_C ? 'C' : '-',                    env->hflags & HF_CPL_MASK,                     (env->hflags >> HF_INHIBIT_IRQ_SHIFT) & 1,                    (env->a20_mask >> 20) & 1,                    (env->hflags >> HF_HALTED_SHIFT) & 1);    }#ifdef TARGET_X86_64    if (env->hflags & HF_LMA_MASK) {        for(i = 0; i < 6; i++) {            SegmentCache *sc = &env->segs[i];            cpu_fprintf(f, "%s =%04x %016llx %08x %08x\n",                        seg_name[i],                        sc->selector,                        sc->base,                        sc->limit,                        sc->flags);        }        cpu_fprintf(f, "LDT=%04x %016llx %08x %08x\n",                    env->ldt.selector,                    env->ldt.base,                    env->ldt.limit,                    env->ldt.flags);        cpu_fprintf(f, "TR =%04x %016llx %08x %08x\n",                    env->tr.selector,                    env->tr.base,

⌨️ 快捷键说明

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