int main(int ac, char **av, char **ep) { int rc; cpu_t *cpu; xec_guest_info_t guest_info; xec_mem_if_t *mem_if; xec_monitor_t *monitor; xec_us_syscall_if_t *us_syscall; m88k_uintptr_t stack_top; nix_env_t *env; bool debugging = false; aspace_lock(); if (ac < 2) { fprintf(stderr, "usage: %s <executable> [args...]\n", *av); exit(EXIT_FAILURE); } /* Initialize xec, nix and loader. */ xec_init(); obsd41_init(); loader_init(); /* Create CPU */ cpu = cpu_new(CPU_ARCH_M88K, CPU_FLAG_ENDIAN_BIG, 0); if (cpu == NULL) { fprintf(stderr, "error: failed initializing M88K architecture.\n"); exit(EXIT_FAILURE); } /* Create XEC bridge mem-if */ mem_if = run88_new_mem_if(); /* Create the XEC US Syscall */ us_syscall = obsd41_us_syscall_create(mem_if); if (us_syscall == NULL) { fprintf(stderr, "error: failed creating xec userspace syscall.\n"); exit(EXIT_FAILURE); } /* Create NIX env */ env = nix_env_create(mem_if); if (env == NULL) { fprintf(stderr, "error: failed creating nix environment.\n"); exit(EXIT_FAILURE); } /* Load the executable */ rc = loader_load(mem_if, av[1]); if (rc != LOADER_SUCCESS) { fprintf(stderr, "error: cannot load executable '%s', error=%d.\n", av[1], rc); exit(EXIT_FAILURE); } /* Setup arguments */ g_uframe_log = xec_log_register("uframe"); #ifndef DEBUGGER xec_log_disable("nix"); xec_log_disable("openbsd41"); xec_log_disable("uframe"); xec_log_disable(NULL); #endif openbsd_m88k_setup_uframe(cpu, mem_if, ac - 1, av + 1, ep, &stack_top); /* Setup the CPU */ cpu_set_flags_codegen(cpu, CPU_CODEGEN_OPTIMIZE|CPU_CODEGEN_TAG_LIMIT); cpu_set_flags_debug(cpu, CPU_DEBUG_NONE); //cpu_set_flags_debug(cpu, CPU_DEBUG_SINGLESTEP_BB); cpu_set_flags_hint(cpu, CPU_HINT_TRAP_RETURNS_TWICE); cpu_set_ram(cpu, RAM); /* Create XEC bridge monitor */ guest_info.name = cpu->info.name; guest_info.endian = (cpu->info.common_flags & CPU_FLAG_ENDIAN_MASK) == CPU_FLAG_ENDIAN_BIG ? XEC_ENDIAN_BIG : XEC_ENDIAN_LITTLE; guest_info.byte_size = cpu->info.byte_size; guest_info.word_size = cpu->info.word_size; guest_info.page_size = cpu->info.default_page_size; monitor = xec_monitor_create(&guest_info, mem_if, cpu->rf.grf, NULL); if (monitor == NULL) { fprintf(stderr, "error: failed createc xec monitor.\n"); exit(EXIT_FAILURE); } /* Setup registers for execution */ PC = g_ahdr.entry; R[31] = stack_top; // Stack Pointer R[1] = -1; // Return Address cpu->code_start = g_ahdr.tstart; cpu->code_end = g_ahdr.tstart + g_ahdr.tsize; cpu->code_entry = g_ahdr.entry; cpu_tag(cpu, cpu->code_entry); dump_state(RAM, (m88k_grf_t*)cpu->rf.grf); #ifdef DEBUGGER debugging = true; #else fprintf(stderr, "Translating..."); fflush(stderr); cpu_translate(cpu); fprintf(stderr, "done.\n"); #endif aspace_unlock(); for (;;) { if (debugging) { rc = cpu_debugger(cpu, debug_function); if (rc < 0) { debugging = false; continue; } } else { rc = cpu_run(cpu, debug_function); } switch (rc) { case JIT_RETURN_NOERR: /* JIT code wants us to end execution */ break; case JIT_RETURN_FUNCNOTFOUND: #ifndef DEBUGGER fprintf(stderr, "%s: error: 0x%llX not found!\n", __func__, (unsigned long long)PC); fprintf(stderr, "Translating..."); fflush(stderr); cpu_tag(cpu, PC); cpu_flush(cpu); cpu_translate(cpu); fprintf(stderr, "done.\n"); #else dump_state(RAM, (m88k_grf_t*)cpu->rf.grf); if (PC == (uint32_t)(-1U)) goto exit_loop; // bad :( fprintf(stderr, "%s: warning: 0x%llX not found!\n", __func__, (unsigned long long)PC); fprintf(stderr, "PC: "); for (size_t i = 0; i < 16; i++) fprintf(stderr, "%02X ", RAM[PC+i]); fprintf(stderr, "\n"); exit(EXIT_FAILURE); #endif break; case JIT_RETURN_TRAP: // printf("TRAP %u / %u!\n", TRAPNO, R[13]); if (TRAPNO == 0x80 && R[13] == 1) // exit goto exit_loop; // printf("BEFORE:\n"); // dump_state(RAM, (m88k_grf_t*)cpu->rf.grf); xec_us_syscall_dispatch(us_syscall, monitor); // printf("AFTER:\n"); // dump_state(RAM, (m88k_grf_t*)cpu->rf.grf); break; case JIT_RETURN_SINGLESTEP: break; default: fprintf(stderr, "unknown return code: %d\n", rc); goto exit_loop; } if (cpu->flags_debug & (CPU_DEBUG_SINGLESTEP | CPU_DEBUG_SINGLESTEP_BB)) cpu_flush(cpu); } exit_loop: cpu_free(cpu); fprintf(stderr, ">> run88 success\n"); exit(EXIT_SUCCESS); }
int lst_parse_entry(easyflash_cart_t * cart, const char *buf_in) { int res = -1; char *filename = NULL; char *menuname = NULL; char *typestr = NULL; lst_type_t type = LST_TYPE_NORMAL; char *buf = strdup(buf_in); filename = strtok(buf, LST_SEP_CHAR "\r\n"); menuname = strtok(NULL, LST_SEP_CHAR "\r\n"); if (menuname != NULL) { typestr = strtok(NULL, "\r\n"); if ((typestr != NULL) && (typestr[1] != 0)) { util_error("too long type!"); goto fail; } } if (typestr != NULL) { for (type = LST_TYPE_NORMAL; type < LST_TYPE_NUM; ++type) { if (lst_type_char[type] == typestr[0]) { break; } } if (type == LST_TYPE_NUM) { util_error("invalid type '%c'!", typestr[0]); goto fail; } } switch (type) { case LST_TYPE_NORMAL: case LST_TYPE_HIDDEN: case LST_TYPE_ALIGN64K: res = main_flash_add_file(cart, filename, menuname, type == LST_TYPE_HIDDEN, type == LST_TYPE_ALIGN64K, 0); break; case LST_TYPE_EAPI: res = eapi_load(cart, filename) || eapi_inject(cart, 1); break; case LST_TYPE_BOOTO: case LST_TYPE_BOOTN: res = boot_load(cart, filename, type == LST_TYPE_BOOTO); break; case LST_TYPE_LOADERO: case LST_TYPE_LOADERN: res = loader_load(cart, filename, type == LST_TYPE_LOADERO); break; default: break; } free(buf); return res; fail: free(buf); return -1; }