gdb_foreach_feature() enumerates features that are useful to identify registers. gdb_read_register() actually reads registers.
Signed-off-by: Akihiko Odaki <akihiko.od...@daynix.com> --- include/exec/gdbstub.h | 6 ++++++ gdbstub/gdbstub.c | 38 ++++++++++++++++++++++++++++++-------- 2 files changed, 36 insertions(+), 8 deletions(-) diff --git a/include/exec/gdbstub.h b/include/exec/gdbstub.h index cbd1e6ead4..5e5789f7bb 100644 --- a/include/exec/gdbstub.h +++ b/include/exec/gdbstub.h @@ -38,6 +38,12 @@ int gdbserver_start(const char *port_or_device); const GDBFeature *gdb_find_static_feature(const char *xmlname); +void gdb_foreach_feature(CPUState *cpu, + void (* callback)(void *, const GDBFeature *, int), + void *opaque); + +int gdb_read_register(CPUState *cpu, GByteArray *buf, int reg, bool has_xml); + void gdb_set_stop_cpu(CPUState *cpu); /* in gdbstub-xml.c, generated by scripts/feature_to_c.py */ diff --git a/gdbstub/gdbstub.c b/gdbstub/gdbstub.c index caef6aabab..5f76ff7271 100644 --- a/gdbstub/gdbstub.c +++ b/gdbstub/gdbstub.c @@ -416,14 +416,32 @@ const GDBFeature *gdb_find_static_feature(const char *xmlname) return NULL; } -static int gdb_read_register(CPUState *cpu, GByteArray *buf, int reg) +void gdb_foreach_feature(CPUState *cpu, + void (* callback)(void *, const GDBFeature *, int), + void *opaque) +{ + CPUClass *cc = CPU_GET_CLASS(cpu); + GDBRegisterState *r; + + if (!cc->gdb_core_feature) { + return; + } + + callback(opaque, cc->gdb_core_feature, 0); + + for (r = cpu->gdb_regs; r; r = r->next) { + callback(opaque, r->feature, r->base_reg); + } +} + +int gdb_read_register(CPUState *cpu, GByteArray *buf, int reg, bool has_xml) { CPUClass *cc = CPU_GET_CLASS(cpu); CPUArchState *env = cpu->env_ptr; GDBRegisterState *r; if (reg < cc->gdb_num_core_regs) { - return cc->gdb_read_register(cpu, buf, reg, gdb_has_xml); + return cc->gdb_read_register(cpu, buf, reg, has_xml); } for (r = cpu->gdb_regs; r; r = r->next) { @@ -434,14 +452,15 @@ static int gdb_read_register(CPUState *cpu, GByteArray *buf, int reg) return 0; } -static int gdb_write_register(CPUState *cpu, uint8_t *mem_buf, int reg) +static int gdb_write_register(CPUState *cpu, uint8_t *mem_buf, int reg, + bool has_xml) { CPUClass *cc = CPU_GET_CLASS(cpu); CPUArchState *env = cpu->env_ptr; GDBRegisterState *r; if (reg < cc->gdb_num_core_regs) { - return cc->gdb_write_register(cpu, mem_buf, reg, gdb_has_xml); + return cc->gdb_write_register(cpu, mem_buf, reg, has_xml); } for (r = cpu->gdb_regs; r; r = r->next) { @@ -1067,7 +1086,7 @@ static void handle_set_reg(GArray *params, void *user_ctx) reg_size = strlen(get_param(params, 1)->data) / 2; gdb_hextomem(gdbserver_state.mem_buf, get_param(params, 1)->data, reg_size); gdb_write_register(gdbserver_state.g_cpu, gdbserver_state.mem_buf->data, - get_param(params, 0)->val_ull); + get_param(params, 0)->val_ull, gdb_has_xml); gdb_put_packet("OK"); } @@ -1087,7 +1106,8 @@ static void handle_get_reg(GArray *params, void *user_ctx) reg_size = gdb_read_register(gdbserver_state.g_cpu, gdbserver_state.mem_buf, - get_param(params, 0)->val_ull); + get_param(params, 0)->val_ull, + gdb_has_xml); if (!reg_size) { gdb_put_packet("E14"); return; @@ -1174,7 +1194,8 @@ static void handle_write_all_regs(GArray *params, void *user_ctx) for (reg_id = 0; reg_id < gdbserver_state.g_cpu->gdb_num_g_regs && len > 0; reg_id++) { - reg_size = gdb_write_register(gdbserver_state.g_cpu, registers, reg_id); + reg_size = gdb_write_register(gdbserver_state.g_cpu, registers, reg_id, + gdb_has_xml); len -= reg_size; registers += reg_size; } @@ -1192,7 +1213,8 @@ static void handle_read_all_regs(GArray *params, void *user_ctx) for (reg_id = 0; reg_id < gdbserver_state.g_cpu->gdb_num_g_regs; reg_id++) { len += gdb_read_register(gdbserver_state.g_cpu, gdbserver_state.mem_buf, - reg_id); + reg_id, + gdb_has_xml); } g_assert(len == gdbserver_state.mem_buf->len); -- 2.41.0