diff options
Diffstat (limited to 'gdbstub/gdbstub.c')
-rw-r--r-- | gdbstub/gdbstub.c | 95 |
1 files changed, 46 insertions, 49 deletions
diff --git a/gdbstub/gdbstub.c b/gdbstub/gdbstub.c index 8eea21450c..b1532118d1 100644 --- a/gdbstub/gdbstub.c +++ b/gdbstub/gdbstub.c @@ -51,7 +51,6 @@ typedef struct GDBRegisterState { gdb_get_reg_cb get_reg; gdb_set_reg_cb set_reg; const char *xml; - struct GDBRegisterState *next; } GDBRegisterState; GDBState gdbserver_state; @@ -349,11 +348,6 @@ static CPUState *gdb_get_cpu(uint32_t pid, uint32_t tid) } } -bool gdb_has_xml(void) -{ - return !!gdb_get_cpu_process(gdbserver_state.g_cpu)->target_xml; -} - static const char *get_feature_xml(const char *p, const char **newp, GDBProcess *process) { @@ -373,31 +367,37 @@ static const char *get_feature_xml(const char *p, const char **newp, if (strncmp(p, "target.xml", len) == 0) { if (!process->target_xml) { GDBRegisterState *r; - GString *xml = g_string_new("<?xml version=\"1.0\"?>"); + g_autoptr(GPtrArray) xml = g_ptr_array_new_with_free_func(g_free); - g_string_append(xml, - "<!DOCTYPE target SYSTEM \"gdb-target.dtd\">" - "<target>"); + g_ptr_array_add( + xml, + g_strdup("<?xml version=\"1.0\"?>" + "<!DOCTYPE target SYSTEM \"gdb-target.dtd\">" + "<target>")); if (cc->gdb_arch_name) { - g_autofree gchar *arch = cc->gdb_arch_name(cpu); - g_string_append_printf(xml, - "<architecture>%s</architecture>", - arch); + g_ptr_array_add( + xml, + g_markup_printf_escaped("<architecture>%s</architecture>", + cc->gdb_arch_name(cpu))); } - g_string_append(xml, "<xi:include href=\""); - g_string_append(xml, cc->gdb_core_xml_file); - g_string_append(xml, "\"/>"); - for (r = cpu->gdb_regs; r; r = r->next) { - g_string_append(xml, "<xi:include href=\""); - g_string_append(xml, r->xml); - g_string_append(xml, "\"/>"); + g_ptr_array_add( + xml, + g_markup_printf_escaped("<xi:include href=\"%s\"/>", + cc->gdb_core_xml_file)); + for (guint i = 0; i < cpu->gdb_regs->len; i++) { + r = &g_array_index(cpu->gdb_regs, GDBRegisterState, i); + g_ptr_array_add( + xml, + g_markup_printf_escaped("<xi:include href=\"%s\"/>", + r->xml)); } - g_string_append(xml, "</target>"); + g_ptr_array_add(xml, g_strdup("</target>")); + g_ptr_array_add(xml, NULL); - process->target_xml = g_string_free(xml, false); - return process->target_xml; + process->target_xml = g_strjoinv(NULL, (void *)xml->pdata); } + return process->target_xml; } /* Is it dynamically generated by the target? */ if (cc->gdb_get_dynamic_xml) { @@ -408,11 +408,11 @@ static const char *get_feature_xml(const char *p, const char **newp, } } /* Is it one of the encoded gdb-xml/ files? */ - for (int i = 0; xml_builtin[i][0]; i++) { - const char *name = xml_builtin[i][0]; + for (int i = 0; gdb_static_features[i].xmlname; i++) { + const char *name = gdb_static_features[i].xmlname; if ((strncmp(name, p, len) == 0) && strlen(name) == len) { - return xml_builtin[i][1]; + return gdb_static_features[i].xml; } } @@ -430,7 +430,8 @@ static int gdb_read_register(CPUState *cpu, GByteArray *buf, int reg) return cc->gdb_read_register(cpu, buf, reg); } - for (r = cpu->gdb_regs; r; r = r->next) { + 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->num_regs) { return r->get_reg(env, buf, reg - r->base_reg); } @@ -448,7 +449,8 @@ static int gdb_write_register(CPUState *cpu, uint8_t *mem_buf, int reg) return cc->gdb_write_register(cpu, mem_buf, reg); } - for (r = cpu->gdb_regs; r; r = r->next) { + 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->num_regs) { return r->set_reg(env, mem_buf, reg - r->base_reg); } @@ -461,17 +463,23 @@ void gdb_register_coprocessor(CPUState *cpu, int num_regs, const char *xml, int g_pos) { GDBRegisterState *s; - GDBRegisterState **p; - - p = &cpu->gdb_regs; - while (*p) { - /* Check for duplicates. */ - if (strcmp((*p)->xml, xml) == 0) - return; - p = &(*p)->next; + guint i; + + if (cpu->gdb_regs) { + for (i = 0; i < cpu->gdb_regs->len; i++) { + /* Check for duplicates. */ + s = &g_array_index(cpu->gdb_regs, GDBRegisterState, i); + if (strcmp(s->xml, xml) == 0) { + return; + } + } + } else { + cpu->gdb_regs = g_array_new(false, false, sizeof(GDBRegisterState)); + i = 0; } - s = g_new0(GDBRegisterState, 1); + g_array_set_size(cpu->gdb_regs, i + 1); + s = &g_array_index(cpu->gdb_regs, GDBRegisterState, i); s->base_reg = cpu->gdb_num_regs; s->num_regs = num_regs; s->get_reg = get_reg; @@ -480,7 +488,6 @@ void gdb_register_coprocessor(CPUState *cpu, /* Add to end of list. */ cpu->gdb_num_regs += num_regs; - *p = s; if (g_pos) { if (g_pos != s->base_reg) { error_report("Error: Bad gdb register numbering for '%s', " @@ -1081,11 +1088,6 @@ static void handle_set_reg(GArray *params, void *user_ctx) { int reg_size; - if (!gdb_get_cpu_process(gdbserver_state.g_cpu)->target_xml) { - gdb_put_packet(""); - return; - } - if (params->len != 2) { gdb_put_packet("E22"); return; @@ -1102,11 +1104,6 @@ static void handle_get_reg(GArray *params, void *user_ctx) { int reg_size; - if (!gdb_get_cpu_process(gdbserver_state.g_cpu)->target_xml) { - gdb_put_packet(""); - return; - } - if (!params->len) { gdb_put_packet("E14"); return; |