コード例 #1
0
ファイル: run88.cpp プロジェクト: fantomid/libcpu
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);
}
コード例 #2
0
ファイル: lst.c プロジェクト: biappi/EasyCart
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;
}