diff --git a/nemu/src/isa/riscv32/reg.c b/nemu/src/isa/riscv32/reg.c index 52e6ba0..c15d349 100644 --- a/nemu/src/isa/riscv32/reg.c +++ b/nemu/src/isa/riscv32/reg.c @@ -14,9 +14,10 @@ ***************************************************************************************/ #include "local-include/reg.h" -#include "gdbstub.h" #include "macro.h" +#include #include +#include #include const char *regs[] = {"$0", "ra", "sp", "gp", "tp", "t0", "t1", "t2", @@ -76,6 +77,6 @@ int isa_write_reg(void *args, int regno, size_t data) { return 0; } -arch_info_t isa_arch_info = {.reg_num = 33, - .reg_byte = MUXDEF(CONFIG_RV64, 8, 4), - .target_desc = TARGET_RV32}; +__EXPORT arch_info_t isa_arch_info = {.reg_num = 32, + .reg_byte = MUXDEF(CONFIG_RV64, 8, 4), + .target_desc = TARGET_RV32}; diff --git a/nemu/src/monitor/filelist.mk b/nemu/src/monitor/filelist.mk index 07c4fe5..61231fe 100644 --- a/nemu/src/monitor/filelist.mk +++ b/nemu/src/monitor/filelist.mk @@ -1,3 +1,4 @@ DIRS-y += src/monitor CXXSRC += src/monitor/gdbstub.cc +LIBS += -lgdbstub diff --git a/nemu/src/monitor/gdbstub.cc b/nemu/src/monitor/gdbstub.cc index 40aa594..8f2d26c 100644 --- a/nemu/src/monitor/gdbstub.cc +++ b/nemu/src/monitor/gdbstub.cc @@ -4,27 +4,27 @@ extern "C" { #include #include +#include #include #include #include #include #include #include -} typedef struct { std::vector *bp; bool halt; } DbgState; -int nemu_read_mem(void *args, size_t addr, size_t len, void *val) { +__EXPORT int nemu_read_mem(void *args, size_t addr, size_t len, void *val) { if (!in_pmem(addr)) return EINVAL; memcpy(val, guest_to_host(addr), len); return 0; } -int nemu_write_mem(void *args, size_t addr, size_t len, void *val) { +__EXPORT int nemu_write_mem(void *args, size_t addr, size_t len, void *val) { if (!in_pmem(addr)) return EINVAL; memcpy(guest_to_host(addr), val, len); @@ -35,21 +35,25 @@ static void nemu_is_stopped(gdb_action_t *act, breakpoint_t *stopped_at) { switch (nemu_state.state) { case NEMU_RUNNING: nemu_state.state = NEMU_STOP; - switch (stopped_at->type) { - case BP_SOFTWARE: - act->reason = gdb_action_t::ACT_BREAKPOINT; - break; - case BP_ACCESS: - act->reason = gdb_action_t::ACT_WATCH; - break; - case BP_WRITE: - act->reason = gdb_action_t::ACT_WWATCH; - break; - case BP_READ: - act->reason = gdb_action_t::ACT_RWATCH; - break; + if (stopped_at == NULL) { + act->reason = gdb_action_t::ACT_NONE; + } else { + switch (stopped_at->type) { + case BP_SOFTWARE: + act->reason = gdb_action_t::ACT_BREAKPOINT; + break; + case BP_ACCESS: + act->reason = gdb_action_t::ACT_WATCH; + break; + case BP_WRITE: + act->reason = gdb_action_t::ACT_WWATCH; + break; + case BP_READ: + act->reason = gdb_action_t::ACT_RWATCH; + break; + } + act->data = stopped_at->addr; } - act->data = stopped_at->addr; break; default: @@ -58,21 +62,21 @@ static void nemu_is_stopped(gdb_action_t *act, breakpoint_t *stopped_at) { } } -void nemu_cont(void *args, gdb_action_t *res) { +__EXPORT void nemu_cont(void *args, gdb_action_t *res) { DbgState *dbg_state = (DbgState *)args; breakpoint_t *stopped_at = cpu_exec_with_bp(-1, dbg_state->bp->data(), dbg_state->bp->size()); nemu_is_stopped(res, stopped_at); } -void nemu_stepi(void *args, gdb_action_t *res) { +__EXPORT void nemu_stepi(void *args, gdb_action_t *res) { DbgState *dbg_state = (DbgState *)args; breakpoint_t *stopped_at = cpu_exec_with_bp(1, dbg_state->bp->data(), dbg_state->bp->size()); nemu_is_stopped(res, stopped_at); } -bool nemu_set_bp(void *args, size_t addr, bp_type_t type) { +__EXPORT bool nemu_set_bp(void *args, size_t addr, bp_type_t type) { DbgState *dbg_state = (DbgState *)args; for (const auto &bp : *dbg_state->bp) { if (bp.addr == addr && bp.type == type) { @@ -83,7 +87,7 @@ bool nemu_set_bp(void *args, size_t addr, bp_type_t type) { return true; } -bool nemu_del_bp(void *args, size_t addr, bp_type_t type) { +__EXPORT bool nemu_del_bp(void *args, size_t addr, bp_type_t type) { DbgState *dbg_state = (DbgState *)args; for (auto it = dbg_state->bp->begin(); it != dbg_state->bp->end(); it++) { if (it->addr == addr && it->type == type) { @@ -95,24 +99,44 @@ bool nemu_del_bp(void *args, size_t addr, bp_type_t type) { return false; } -void nemu_on_interrupt(void *args) { +__EXPORT void nemu_on_interrupt(void *args) { // fputs("Not implemented", stderr); } +__EXPORT int nemu_read_reg(void *args, int regno, size_t *data) { + return isa_read_reg(args, regno, data); +} +__EXPORT int nemu_write_reg(void *args, int regno, size_t data) { + return isa_write_reg(args, regno, data); +} +__EXPORT size_t argsize = sizeof(DbgState); + static struct target_ops nemu_gdbstub_ops = {.cont = nemu_cont, .stepi = nemu_stepi, - .read_reg = isa_read_reg, - .write_reg = isa_write_reg, + .read_reg = nemu_read_reg, + .write_reg = nemu_write_reg, .read_mem = nemu_read_mem, .write_mem = nemu_write_mem, .set_bp = nemu_set_bp, .del_bp = nemu_del_bp, .on_interrupt = NULL}; static DbgState dbg; -extern "C" { static gdbstub_t gdbstub_priv; #define SOCKET_ADDR "127.0.0.1:1234" -int nemu_gdbstub_init() { + +__EXPORT void nemu_init(void *args) { + DbgState *dbg_state = (DbgState *)args; + dbg_state->bp = new std::vector(); + dbg_state->halt = 0; + Assert(dbg_state->bp != NULL, "Failed to allocate breakpoint"); + + void init_mem(); + init_mem(); + /* Perform ISA dependent initialization. */ + init_isa(); +} + +__EXPORT int nemu_gdbstub_init() { dbg.bp = new std::vector(); assert(dbg.bp); if (!gdbstub_init(&gdbstub_priv, &nemu_gdbstub_ops, @@ -121,7 +145,8 @@ int nemu_gdbstub_init() { } return 0; } -int nemu_gdbstub_run() { + +__EXPORT int nemu_gdbstub_run() { puts("Waiting for gdb connection at " SOCKET_ADDR); bool success = gdbstub_run(&gdbstub_priv, &dbg); gdbstub_close(&gdbstub_priv); diff --git a/nemu/src/monitor/monitor.c b/nemu/src/monitor/monitor.c index b9b343e..264d463 100644 --- a/nemu/src/monitor/monitor.c +++ b/nemu/src/monitor/monitor.c @@ -25,7 +25,7 @@ void init_mem(); void init_difftest(char *ref_so_file, long img_size, int port); void init_device(); void init_disasm(const char *triple); -int nemu_gdbstub_init(); +void nemu_init(); static void welcome() { Log("Trace: %s", MUXDEF(CONFIG_TRACE, ANSI_FMT("ON", ANSI_FG_GREEN), @@ -60,7 +60,8 @@ static long load_img() { // Image file is searched from paths in environment variable NEMU_IMAGES_PATH if it's a relative path if (img_file[0] != '/') { char *search_paths = getenv("NEMU_IMAGES_PATH"); - if(search_paths == NULL) search_paths = "./"; + if (search_paths == NULL) + search_paths = "./"; search_paths = strdup(search_paths); Trace("NEMU_IMAGES_PATH=%s", search_paths); @@ -68,8 +69,10 @@ static long load_img() { char *p_start = search_paths; do { char *p = strchr(p_start, ':'); - if (p != NULL) *p = '\0'; - else p = paths_end; + if (p != NULL) + *p = '\0'; + else + p = paths_end; char *file_path = malloc(p - p_start + img_filename_len + 2); strcpy(file_path, p_start); @@ -86,7 +89,7 @@ static long load_img() { Assert(fp != NULL || errno == ENOENT, "Cannot open '%s'", img_file); p_start = p + 1; - } while(p_start < paths_end); + } while (p_start < paths_end); free(search_paths); Assert(fp, "Cannot find '%s'", img_file); @@ -178,10 +181,11 @@ void init_monitor(int argc, char *argv[]) { init_difftest(diff_so_file, img_size, difftest_port); /* Initialize debugger */ - if (nemu_gdbstub_init()) { - Error("Failed to init"); - exit(1); - } + // if (nemu_init()) { + // Error("Failed to init"); + // exit(1); + // } + nemu_init(); // printf("elf_file: %s\n", elf_file); if (elf_file != NULL) {