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

📄 main.c

📁 qemu性能直逼VMware的仿真器QEMU 的模擬速度約為實機的 25%;約為 Bochs 的 60 倍。Plex86、User-Mode-Linux、VMware 和 Virtual PC 則比
💻 C
📖 第 1 页 / 共 4 页
字号:
        switch (trapnr) {        case 0x160:            ret = do_syscall(env,                              env->gregs[3],                              env->gregs[4],                              env->gregs[5],                              env->gregs[6],                              env->gregs[7],                              env->gregs[0],                              0);            env->gregs[0] = ret;            env->pc += 2;            break;        case EXCP_DEBUG:            {                int sig;                sig = gdb_handlesig (env, TARGET_SIGTRAP);                if (sig)                  {                    info.si_signo = sig;                    info.si_errno = 0;                    info.si_code = TARGET_TRAP_BRKPT;                    queue_signal(info.si_signo, &info);                  }            }            break;        default:            printf ("Unhandled trap: 0x%x\n", trapnr);            cpu_dump_state(env, stderr, fprintf, 0);            exit (1);        }        process_pending_signals (env);    }}#endif#ifdef TARGET_M68Kvoid cpu_loop(CPUM68KState *env){    int trapnr;    unsigned int n;    target_siginfo_t info;    TaskState *ts = env->opaque;        for(;;) {        trapnr = cpu_m68k_exec(env);        switch(trapnr) {        case EXCP_ILLEGAL:            {                if (ts->sim_syscalls) {                    uint16_t nr;                    nr = lduw(env->pc + 2);                    env->pc += 4;                    do_m68k_simcall(env, nr);                } else {                    goto do_sigill;                }            }            break;        case EXCP_HALTED:            /* Semihosing syscall.  */            env->pc += 2;            do_m68k_semihosting(env, env->dregs[0]);            break;        case EXCP_LINEA:        case EXCP_LINEF:        case EXCP_UNSUPPORTED:        do_sigill:            info.si_signo = SIGILL;            info.si_errno = 0;            info.si_code = TARGET_ILL_ILLOPN;            info._sifields._sigfault._addr = env->pc;            queue_signal(info.si_signo, &info);            break;        case EXCP_TRAP0:            {                ts->sim_syscalls = 0;                n = env->dregs[0];                env->pc += 2;                env->dregs[0] = do_syscall(env,                                           n,                                           env->dregs[1],                                          env->dregs[2],                                          env->dregs[3],                                          env->dregs[4],                                          env->dregs[5],                                          env->dregs[6]);            }            break;        case EXCP_INTERRUPT:            /* just indicate that signals should be handled asap */            break;        case EXCP_ACCESS:            {                info.si_signo = SIGSEGV;                info.si_errno = 0;                /* XXX: check env->error_code */                info.si_code = TARGET_SEGV_MAPERR;                info._sifields._sigfault._addr = env->mmu.ar;                queue_signal(info.si_signo, &info);            }            break;        case EXCP_DEBUG:            {                int sig;                sig = gdb_handlesig (env, TARGET_SIGTRAP);                if (sig)                  {                    info.si_signo = sig;                    info.si_errno = 0;                    info.si_code = TARGET_TRAP_BRKPT;                    queue_signal(info.si_signo, &info);                  }            }            break;        default:            fprintf(stderr, "qemu: unhandled CPU exception 0x%x - aborting\n",                     trapnr);            cpu_dump_state(env, stderr, fprintf, 0);            abort();        }        process_pending_signals(env);    }}#endif /* TARGET_M68K */void usage(void){    printf("qemu-" TARGET_ARCH " version " QEMU_VERSION ", Copyright (c) 2003-2007 Fabrice Bellard\n"           "usage: qemu-" TARGET_ARCH " [-h] [-g] [-d opts] [-L path] [-s size] program [arguments...]\n"           "Linux CPU emulator (compiled for %s emulation)\n"           "\n"           "-h           print this help\n"           "-g port      wait gdb connection to port\n"           "-L path      set the elf interpreter prefix (default=%s)\n"           "-s size      set the stack size in bytes (default=%ld)\n"           "\n"           "debug options:\n"#ifdef USE_CODE_COPY           "-no-code-copy   disable code copy acceleration\n"#endif           "-d options   activate log (logfile=%s)\n"           "-p pagesize  set the host page size to 'pagesize'\n",           TARGET_ARCH,           interp_prefix,            x86_stack_size,           DEBUG_LOGFILE);    _exit(1);}/* XXX: currently only used for async signals (see signal.c) */CPUState *global_env;/* used to free thread contexts */TaskState *first_task_state;int main(int argc, char **argv){    const char *filename;    struct target_pt_regs regs1, *regs = &regs1;    struct image_info info1, *info = &info1;    TaskState ts1, *ts = &ts1;    CPUState *env;    int optind;    const char *r;    int gdbstub_port = 0;        if (argc <= 1)        usage();    /* init debug */    cpu_set_log_filename(DEBUG_LOGFILE);    optind = 1;    for(;;) {        if (optind >= argc)            break;        r = argv[optind];        if (r[0] != '-')            break;        optind++;        r++;        if (!strcmp(r, "-")) {            break;        } else if (!strcmp(r, "d")) {            int mask;            CPULogItem *item;	    if (optind >= argc)		break;            	    r = argv[optind++];            mask = cpu_str_to_log_mask(r);            if (!mask) {                printf("Log items (comma separated):\n");                for(item = cpu_log_items; item->mask != 0; item++) {                    printf("%-10s %s\n", item->name, item->help);                }                exit(1);            }            cpu_set_log(mask);        } else if (!strcmp(r, "s")) {            r = argv[optind++];            x86_stack_size = strtol(r, (char **)&r, 0);            if (x86_stack_size <= 0)                usage();            if (*r == 'M')                x86_stack_size *= 1024 * 1024;            else if (*r == 'k' || *r == 'K')                x86_stack_size *= 1024;        } else if (!strcmp(r, "L")) {            interp_prefix = argv[optind++];        } else if (!strcmp(r, "p")) {            qemu_host_page_size = atoi(argv[optind++]);            if (qemu_host_page_size == 0 ||                (qemu_host_page_size & (qemu_host_page_size - 1)) != 0) {                fprintf(stderr, "page size must be a power of two\n");                exit(1);            }        } else if (!strcmp(r, "g")) {            gdbstub_port = atoi(argv[optind++]);	} else if (!strcmp(r, "r")) {	    qemu_uname_release = argv[optind++];        } else #ifdef USE_CODE_COPY        if (!strcmp(r, "no-code-copy")) {            code_copy_enabled = 0;        } else #endif        {            usage();        }    }    if (optind >= argc)        usage();    filename = argv[optind];    /* Zero out regs */    memset(regs, 0, sizeof(struct target_pt_regs));    /* Zero out image_info */    memset(info, 0, sizeof(struct image_info));    /* Scan interp_prefix dir for replacement files. */    init_paths(interp_prefix);    /* NOTE: we need to init the CPU at this stage to get       qemu_host_page_size */    env = cpu_init();    global_env = env;        if (loader_exec(filename, argv+optind, environ, regs, info) != 0) {	printf("Error loading %s\n", filename);	_exit(1);    }        if (loglevel) {        page_dump(logfile);            fprintf(logfile, "start_brk   0x%08lx\n" , info->start_brk);        fprintf(logfile, "end_code    0x%08lx\n" , info->end_code);        fprintf(logfile, "start_code  0x%08lx\n" , info->start_code);        fprintf(logfile, "start_data  0x%08lx\n" , info->start_data);        fprintf(logfile, "end_data    0x%08lx\n" , info->end_data);        fprintf(logfile, "start_stack 0x%08lx\n" , info->start_stack);        fprintf(logfile, "brk         0x%08lx\n" , info->brk);        fprintf(logfile, "entry       0x%08lx\n" , info->entry);    }    target_set_brk(info->brk);    syscall_init();    signal_init();    /* build Task State */    memset(ts, 0, sizeof(TaskState));    env->opaque = ts;    ts->used = 1;    ts->info = info;    env->user_mode_only = 1;    #if defined(TARGET_I386)    cpu_x86_set_cpl(env, 3);    env->cr[0] = CR0_PG_MASK | CR0_WP_MASK | CR0_PE_MASK;    env->hflags |= HF_PE_MASK;    if (env->cpuid_features & CPUID_SSE) {        env->cr[4] |= CR4_OSFXSR_MASK;        env->hflags |= HF_OSFXSR_MASK;    }    /* flags setup : we activate the IRQs by default as in user mode */    env->eflags |= IF_MASK;        /* linux register setup */    env->regs[R_EAX] = regs->eax;    env->regs[R_EBX] = regs->ebx;    env->regs[R_ECX] = regs->ecx;    env->regs[R_EDX] = regs->edx;    env->regs[R_ESI] = regs->esi;    env->regs[R_EDI] = regs->edi;    env->regs[R_EBP] = regs->ebp;    env->regs[R_ESP] = regs->esp;    env->eip = regs->eip;    /* linux interrupt setup */    env->idt.base = h2g(idt_table);    env->idt.limit = sizeof(idt_table) - 1;    set_idt(0, 0);    set_idt(1, 0);    set_idt(2, 0);    set_idt(3, 3);    set_idt(4, 3);    set_idt(5, 3);    set_idt(6, 0);    set_idt(7, 0);    set_idt(8, 0);    set_idt(9, 0);    set_idt(10, 0);    set_idt(11, 0);    set_idt(12, 0);    set_idt(13, 0);    set_idt(14, 0);    set_idt(15, 0);    set_idt(16, 0);    set_idt(17, 0);    set_idt(18, 0);    set_idt(19, 0);    set_idt(0x80, 3);    /* linux segment setup */    env->gdt.base = h2g(gdt_table);    env->gdt.limit = sizeof(gdt_table) - 1;    write_dt(&gdt_table[__USER_CS >> 3], 0, 0xfffff,             DESC_G_MASK | DESC_B_MASK | DESC_P_MASK | DESC_S_MASK |              (3 << DESC_DPL_SHIFT) | (0xa << DESC_TYPE_SHIFT));    write_dt(&gdt_table[__USER_DS >> 3], 0, 0xfffff,             DESC_G_MASK | DESC_B_MASK | DESC_P_MASK | DESC_S_MASK |              (3 << DESC_DPL_SHIFT) | (0x2 << DESC_TYPE_SHIFT));    cpu_x86_load_seg(env, R_CS, __USER_CS);    cpu_x86_load_seg(env, R_DS, __USER_DS);    cpu_x86_load_seg(env, R_ES, __USER_DS);    cpu_x86_load_seg(env, R_SS, __USER_DS);    cpu_x86_load_seg(env, R_FS, __USER_DS);    cpu_x86_load_seg(env, R_GS, __USER_DS);#elif defined(TARGET_ARM)    {        int i;        cpu_arm_set_model(env, ARM_CPUID_ARM1026);        cpsr_write(env, regs->uregs[16], 0xffffffff);        for(i = 0; i < 16; i++) {            env->regs[i] = regs->uregs[i];        }        ts->stack_base = info->start_stack;        ts->heap_base = info->brk;        /* This will be filled in on the first SYS_HEAPINFO call.  */        ts->heap_limit = 0;    }#elif defined(TARGET_SPARC)    {        int i;	env->pc = regs->pc;	env->npc = regs->npc;        env->y = regs->y;        for(i = 0; i < 8; i++)            env->gregs[i] = regs->u_regs[i];        for(i = 0; i < 8; i++)            env->regwptr[i] = regs->u_regs[i + 8];    }#elif defined(TARGET_PPC)    {        ppc_def_t *def;        int i;        /* Choose and initialise CPU */        /* XXX: CPU model (or PVR) should be provided on command line */        //        ppc_find_by_name("750gx", &def);        //        ppc_find_by_name("750fx", &def);        //        ppc_find_by_name("750p", &def);        ppc_find_by_name("750", &def);        //        ppc_find_by_name("G3", &def);        //        ppc_find_by_name("604r", &def);        //        ppc_find_by_name("604e", &def);        //        ppc_find_by_name("604", &def);        if (def == NULL) {            cpu_abort(env,                      "Unable to find PowerPC CPU definition\n");        }        cpu_ppc_register(env, def);        for (i = 0; i < 32; i++) {            if (i != 12 && i != 6 && i != 13)                env->msr[i] = (regs->msr >> i) & 1;        }        env->nip = regs->nip;        for(i = 0; i < 32; i++) {            env->gpr[i] = regs->gpr[i];        }    }#elif defined(TARGET_M68K)    {        m68k_def_t *def;        def = m68k_find_by_name("cfv4e");        if (def == NULL) {            cpu_abort(cpu_single_env,                      "Unable to find m68k CPU definition\n");        }        cpu_m68k_register(cpu_single_env, def);        env->pc = regs->pc;        env->dregs[0] = regs->d0;        env->dregs[1] = regs->d1;        env->dregs[2] = regs->d2;        env->dregs[3] = regs->d3;        env->dregs[4] = regs->d4;        env->dregs[5] = regs->d5;        env->dregs[6] = regs->d6;        env->dregs[7] = regs->d7;        env->aregs[0] = regs->a0;        env->aregs[1] = regs->a1;        env->aregs[2] = regs->a2;        env->aregs[3] = regs->a3;        env->aregs[4] = regs->a4;        env->aregs[5] = regs->a5;        env->aregs[6] = regs->a6;        env->aregs[7] = regs->usp;        env->sr = regs->sr;        ts->sim_syscalls = 1;    }#elif defined(TARGET_MIPS)    {        int i;        for(i = 0; i < 32; i++) {            env->gpr[i] = regs->regs[i];        }        env->PC = regs->cp0_epc;#ifdef MIPS_USES_FPU        env->CP0_Status |= (1 << CP0St_CU1);#endif    }#elif defined(TARGET_SH4)    {        int i;        for(i = 0; i < 16; i++) {            env->gregs[i] = regs->regs[i];        }        env->pc = regs->pc;    }#else#error unsupported target CPU#endif    if (gdbstub_port) {        gdbserver_start (gdbstub_port);        gdb_handlesig(env, 0);    }    cpu_loop(env);    /* never exits */    return 0;}

⌨️ 快捷键说明

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