Refine gdbstub.

This commit is contained in:
Colin 2025-09-24 10:18:29 +00:00
parent e96a66291c
commit 06775f841a
3 changed files with 100 additions and 118 deletions

View File

@ -50,8 +50,7 @@ void gdb_init_gdb_state(void) {
gdb_state.sstep_flags &= gdb_state.supported_sstep_flags;
}
/* writes 2*len+1 bytes in buf */
void gdb_memtohex(GString *buf, const uint8_t *mem, int len) {
static void gdb_memtohex(GString *buf, const uint8_t *mem, int len) {
int i, c;
for (i = 0; i < len; i++) {
c = mem[i];
@ -169,43 +168,34 @@ const GDBFeature *gdb_find_static_feature(const char *xmlname) {
return feature;
}
}
g_assert_not_reached();
}
GArray *gdb_get_register_list(CPUState *cpu) {
GArray *results = g_array_new(true, true, sizeof(GDBRegDesc));
// GArray *gdb_get_register_list(CPUState *cpu) {
// GArray *results = g_array_new(true, true, sizeof(GDBRegDesc));
/* registers are only available once the CPU is initialised */
if (!cpu->gdb_regs) {
return results;
}
// /* registers are only available once the CPU is initialised */
// if (!cpu->gdb_regs) {
// return results;
// }
for (int f = 0; f < cpu->gdb_regs->len; f++) {
GDBRegisterState *r = &g_array_index(cpu->gdb_regs, GDBRegisterState, f);
for (int i = 0; i < r->feature->num_regs; i++) {
const char *name = r->feature->regs[i];
GDBRegDesc desc = {r->base_reg + i, name, r->feature->name};
g_array_append_val(results, desc);
}
}
// for (int f = 0; f < cpu->gdb_regs->len; f++) {
// GDBRegisterState *r = &g_array_index(cpu->gdb_regs, GDBRegisterState, f);
// for (int i = 0; i < r->feature->num_regs; i++) {
// const char *name = r->feature->regs[i];
// GDBRegDesc desc = {r->base_reg + i, name, r->feature->name};
// g_array_append_val(results, desc);
// }
// }
return results;
}
// return results;
// }
int gdb_read_register(CPUState *cpu, GByteArray *buf, int reg) {
GDBRegisterState *r;
if (reg < cpu->cc->gdb_num_core_regs) {
return cpu->cc->gdb_read_register(cpu, buf, reg);
}
// for (guint i = 0; i < cpu->gdb_regs->len; i++) {
// r = &g_array_index(cpu->gdb_regs, GDBRegisterState, i);
// if (r->base_reg <= reg && reg < r->base_reg + r->feature->num_regs) {
// return r->get_reg(cpu, buf, reg - r->base_reg);
// }
// }
return 0;
}
@ -216,12 +206,6 @@ int gdb_write_register(CPUState *cpu, uint8_t *mem_buf, int reg) {
return cpu->cc->gdb_write_register(cpu, mem_buf, reg);
}
// for (guint i = 0; i < cpu->gdb_regs->len; i++) {
// r = &g_array_index(cpu->gdb_regs, GDBRegisterState, i);
// if (r->base_reg <= reg && reg < r->base_reg + r->feature->num_regs) {
// return r->set_reg(cpu, mem_buf, reg - r->base_reg);
// }
// }
return 0;
}

View File

@ -228,7 +228,6 @@ static inline void cpu_physical_memory_read(hwaddr addr, const void *buf, hwaddr
bool runstate_needs_reset(void);
bool vm_prepare_start(bool step_requested);
void qemu_clock_enable();
int gdb_target_memory_rw_debug(CPUState *cs, hwaddr addr, uint8_t *buf, int len, bool is_write);
@ -238,7 +237,6 @@ const char *gdb_get_core_xml_file(CPUState *cpu);
void cpu_register_gdb_commands();
int cpu_common_gdb_read_register(CPUState *cpu, GByteArray *buf, int reg);
int cpu_common_gdb_write_register(CPUState *cpu, uint8_t *buf, int reg);

View File

@ -30,17 +30,25 @@ void gdb_chr_receive(const uint8_t *buf, int size) {
}
}
int gdb_target_memory_rw_debug(CPUState *cpu, hwaddr addr, uint8_t *buf, int len, bool is_write) {
if (is_write) {
cpu_physical_memory_write(addr, buf, len);
} else {
cpu_physical_memory_read(addr, buf, len);
void gdb_put_buffer(const uint8_t *buf, int len) { conn_send_str(gdb_state.conn, (char *)buf, len); }
bool gdb_got_immediate_ack(void) {
int i = conn_get_char(gdb_state.conn);
if (i < 0) {
return true; /* no response, continue anyway */
}
return 0;
if (i == '+') {
return true; /* received correctly, continue */
}
return false; /* anything else, including '-' then try again */
}
CPUState *get_cpu() { return gdb_state.c_cpu; }
unsigned int gdb_get_max_cpus(void) { return 1; }
bool gdb_supports_guest_debug(void) { return false; }
void gdb_handle_query_qemu_phy_mem_mode(GArray *params, void *ctx) {
g_string_printf(gdb_state.str_buf, "%d", 1);
gdb_put_strbuf();
@ -54,6 +62,7 @@ void gdb_handle_set_qemu_phy_mem_mode(GArray *params, void *ctx) {
gdb_put_packet("OK");
}
// Remote command 用于发送特定的命令
void gdb_handle_query_rcmd(GArray *params, void *ctx) {
const guint8 zero = 0;
int len;
@ -82,12 +91,6 @@ void gdb_handle_query_rcmd(GArray *params, void *ctx) {
void gdb_handle_query_attached(GArray *params, void *ctx) { gdb_put_packet("1"); }
void gdb_continue(void) {
if (!runstate_needs_reset()) {
vm_start();
}
}
int gdb_continue_partial(char *newstates) {
CPUState *cpu;
int res = 0;
@ -109,13 +112,10 @@ int gdb_continue_partial(char *newstates) {
case 1:
break; /* nothing to do here */
case 's':
// trace_gdbstub_op_stepping(c->cpu_index);
cpu_single_step(c, gdb_state.sstep_flags);
cpu_resume(c);
flag = 1;
break;
case 'c':
// trace_gdbstub_op_continue_cpu(c->cpu_index);
cpu_resume(c);
flag = 1;
break;
@ -124,9 +124,6 @@ int gdb_continue_partial(char *newstates) {
break;
}
}
if (flag) {
qemu_clock_enable();
}
return res;
}
@ -143,48 +140,6 @@ int gdb_signal_to_target(int sig) {
}
}
bool runstate_is_running() {
auto c = get_cpu();
return c->running;
}
void vm_stop() { get_cpu()->running = false; }
void vm_start() { get_cpu()->running = true; }
void cpu_synchronize_state(CPUState *cpu) {}
void gdb_exit(int i) {};
void gdb_qemu_exit(int i) {};
CPUState *get_cpu() { return gdb_state.c_cpu; }
void gdb_breakpoint_remove_all(CPUState *cs) {}
bool gdb_supports_guest_debug(void) { return false; }
int gdb_breakpoint_insert(CPUState *cs, int type, vaddr addr, vaddr len) { return 0; }
int gdb_breakpoint_remove(CPUState *cs, int type, vaddr addr, vaddr len) { return 0; }
void gdb_put_buffer(const uint8_t *buf, int len) { conn_send_str(gdb_state.conn, (char *)buf, len); }
bool gdb_got_immediate_ack(void) {
int i = conn_get_char(gdb_state.conn);
if (i < 0) {
return true; /* no response, continue anyway */
}
if (i == '+') {
return true; /* received correctly, continue */
}
return false; /* anything else, including '-' then try again */
}
static inline void cpu_physical_memory_write(hwaddr addr, const void *buf, hwaddr len) {}
static inline void cpu_physical_memory_read(hwaddr addr, const void *buf, hwaddr len) {}
bool runstate_needs_reset(void) { return false; }
bool vm_prepare_start(bool step_requested) { return true; }
void qemu_clock_enable() {}
void gdb_handle_file_io(GArray *params, void *user_ctx) {}
void gdb_disable_syscalls(void) {}
void cpu_single_step(CPUState *cpu, int enabled) {}
const char *get_feature_xml(const char *p, const char **newp, GDBProcess *process) {
CPUState *cpu = get_cpu();
GDBRegisterState *r;
@ -275,6 +230,27 @@ void gdb_init_cpu() {
// }
}
void cpu_register_gdb_commands() {
g_autoptr(GPtrArray) query_table = g_ptr_array_new();
g_autoptr(GPtrArray) set_table = g_ptr_array_new();
g_autoptr(GString) qsupported_features = g_string_new(NULL);
/* Set arch-specific handlers for 'q' commands. */
if (query_table->len) {
gdb_extend_query_table(query_table);
}
/* Set arch-specific handlers for 'Q' commands. */
if (set_table->len) {
gdb_extend_set_table(set_table);
}
/* Set arch-specific qSupported feature. */
if (qsupported_features->len) {
gdb_extend_qsupported_features(qsupported_features->str);
}
}
void gdb_register_coprocessor(CPUState *cpu, gdb_get_reg_cb get_reg, gdb_set_reg_cb set_reg, const GDBFeature *feature,
int g_pos) {
GDBRegisterState *s;
@ -327,31 +303,40 @@ const char *gdb_get_core_xml_file(CPUState *cpu) {
return cc->gdb_core_xml_file;
}
bool runstate_is_running() {
auto c = get_cpu();
return c->running;
}
///////
/////// local cpu operation
///////
void vm_stop() { get_cpu()->running = false; }
void vm_start() { get_cpu()->running = true; }
void cpu_synchronize_state(CPUState *cpu) {}
void gdb_exit(int i) {};
void gdb_qemu_exit(int i) {};
void gdb_breakpoint_remove_all(CPUState *cs) {}
int gdb_breakpoint_insert(CPUState *cs, int type, vaddr addr, vaddr len) { return 0; }
int gdb_breakpoint_remove(CPUState *cs, int type, vaddr addr, vaddr len) { return 0; }
static inline void cpu_physical_memory_write(hwaddr addr, const void *buf, hwaddr len) {}
static inline void cpu_physical_memory_read(hwaddr addr, const void *buf, hwaddr len) {}
bool runstate_needs_reset(void) { return false; }
bool vm_prepare_start(bool step_requested) { return true; }
void gdb_handle_file_io(GArray *params, void *user_ctx) {}
void gdb_disable_syscalls(void) {}
void cpu_single_step(CPUState *cpu, int enabled) {}
void cpu_resume(CPUState *cpu) {
cpu->stop = false;
cpu->stopped = false;
// qemu_cpu_kick(cpu);
}
void cpu_register_gdb_commands() {
g_autoptr(GPtrArray) query_table = g_ptr_array_new();
g_autoptr(GPtrArray) set_table = g_ptr_array_new();
g_autoptr(GString) qsupported_features = g_string_new(NULL);
/* Set arch-specific handlers for 'q' commands. */
if (query_table->len) {
gdb_extend_query_table(query_table);
}
/* Set arch-specific handlers for 'Q' commands. */
if (set_table->len) {
gdb_extend_set_table(set_table);
}
/* Set arch-specific qSupported feature. */
if (qsupported_features->len) {
gdb_extend_qsupported_features(qsupported_features->str);
}
}
int cpu_common_gdb_read_register(CPUState *cpu, GByteArray *buf, int reg) {
@ -360,4 +345,19 @@ int cpu_common_gdb_read_register(CPUState *cpu, GByteArray *buf, int reg) {
return 8;
}
int cpu_common_gdb_write_register(CPUState *cpu, uint8_t *buf, int reg) { return 0; }
int cpu_common_gdb_write_register(CPUState *cpu, uint8_t *buf, int reg) { return 0; }
int gdb_target_memory_rw_debug(CPUState *cpu, hwaddr addr, uint8_t *buf, int len, bool is_write) {
if (is_write) {
cpu_physical_memory_write(addr, buf, len);
} else {
cpu_physical_memory_read(addr, buf, len);
}
return 0;
}
void gdb_continue(void) {
if (!runstate_needs_reset()) {
vm_start();
}
}