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

📄 main.c

📁 qemu虚拟机代码
💻 C
📖 第 1 页 / 共 4 页
字号:
    unsigned int syscall_num;    target_ulong arg5, arg6, sp_reg;    for(;;) {        trapnr = cpu_mips_exec(env);        switch(trapnr) {        case EXCP_SYSCALL:            {                syscall_num = env->gpr[2] - 4000;                if (syscall_num >= sizeof(mips_syscall_args)) {                    ret = -ENOSYS;                } else {                    nb_args = mips_syscall_args[syscall_num];                    if (nb_args >= 5) {                        sp_reg = env->gpr[29];                        /* these arguments are taken from the stack */                        arg5 = tgetl(sp_reg + 16);                        if (nb_args >= 6) {                            arg6 = tgetl(sp_reg + 20);                        } else {                            arg6 = 0;                        }                    } else {                        arg5 = 0;                        arg6 = 0;                    }                    ret = do_syscall(env,                                      env->gpr[2],                                      env->gpr[4],                                     env->gpr[5],                                     env->gpr[6],                                     env->gpr[7],                                     arg5,                                      arg6);                }                fail:                env->PC += 4;                if ((unsigned int)ret >= (unsigned int)(-1133)) {                    env->gpr[7] = 1; /* error flag */                    ret = -ret;                    env->gpr[0] = ret;                    env->gpr[2] = ret;                } else {                    env->gpr[7] = 0; /* error flag */                    env->gpr[2] = ret;                }            }            break;        case EXCP_CpU:        case EXCP_RI:            {                uint32_t insn, op;                insn = tget32(env->PC);                op = insn >> 26;                //                printf("insn=%08x op=%02x\n", insn, op);                /* XXX: totally dummy FP ops just to be able to launch                   a few executables */                switch(op) {                case 0x31: /* LWC1 */                    env->PC += 4;                    break;                case 0x39: /* SWC1 */                    env->PC += 4;                    break;                case 0x11:                    switch((insn >> 21) & 0x1f) {                    case 0x02: /* CFC1 */                        env->PC += 4;                        break;                    default:                        goto sigill;                    }                    break;                default:                sigill:                    info.si_signo = TARGET_SIGILL;                    info.si_errno = 0;                    info.si_code = 0;                    queue_signal(info.si_signo, &info);                    break;                }            }            break;        default:            //        error:            fprintf(stderr, "qemu: unhandled CPU exception 0x%x - aborting\n",                     trapnr);            cpu_dump_state(env, stderr, fprintf, 0);            abort();        }        process_pending_signals(env);    }}#endif#ifdef TARGET_SH4void cpu_loop (CPUState *env){    int trapnr, ret;    //    target_siginfo_t info;        while (1) {        trapnr = cpu_sh4_exec (env);                switch (trapnr) {        case 0x160:            ret = do_syscall(env,                              env->gregs[0x13],                              env->gregs[0x14],                              env->gregs[0x15],                              env->gregs[0x16],                              env->gregs[0x17],                              env->gregs[0x10],                              0);            env->gregs[0x10] = ret;            env->pc += 2;            break;        default:            printf ("Unhandled trap: 0x%x\n", trapnr);            cpu_dump_state(env, stderr, fprintf, 0);            exit (1);        }        process_pending_signals (env);    }}#endifvoid usage(void){    printf("qemu-" TARGET_ARCH " version " QEMU_VERSION ", Copyright (c) 2003-2005 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 #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 (elf_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, "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;    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_MIPS)    {        int i;        for(i = 0; i < 32; i++) {            env->gpr[i] = regs->regs[i];        }        env->PC = regs->cp0_epc;    }#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 + -