Refine gdbstub.
This commit is contained in:
parent
e96a66291c
commit
06775f841a
|
|
@ -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;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
|
||||
|
|
|
|||
166
gdbstub/system.c
166
gdbstub/system.c
|
|
@ -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();
|
||||
}
|
||||
}
|
||||
Loading…
Reference in New Issue