|
@@ -51,7 +51,6 @@ typedef struct GDBRegisterState {
|
|
gdb_get_reg_cb get_reg;
|
|
gdb_get_reg_cb get_reg;
|
|
gdb_set_reg_cb set_reg;
|
|
gdb_set_reg_cb set_reg;
|
|
const char *xml;
|
|
const char *xml;
|
|
- struct GDBRegisterState *next;
|
|
|
|
} GDBRegisterState;
|
|
} GDBRegisterState;
|
|
|
|
|
|
GDBState gdbserver_state;
|
|
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,
|
|
static const char *get_feature_xml(const char *p, const char **newp,
|
|
GDBProcess *process)
|
|
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 (strncmp(p, "target.xml", len) == 0) {
|
|
if (!process->target_xml) {
|
|
if (!process->target_xml) {
|
|
GDBRegisterState *r;
|
|
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) {
|
|
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? */
|
|
/* Is it dynamically generated by the target? */
|
|
if (cc->gdb_get_dynamic_xml) {
|
|
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? */
|
|
/* 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) &&
|
|
if ((strncmp(name, p, len) == 0) &&
|
|
strlen(name) == len) {
|
|
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);
|
|
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) {
|
|
if (r->base_reg <= reg && reg < r->base_reg + r->num_regs) {
|
|
return r->get_reg(env, buf, reg - r->base_reg);
|
|
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);
|
|
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) {
|
|
if (r->base_reg <= reg && reg < r->base_reg + r->num_regs) {
|
|
return r->set_reg(env, mem_buf, reg - r->base_reg);
|
|
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)
|
|
int num_regs, const char *xml, int g_pos)
|
|
{
|
|
{
|
|
GDBRegisterState *s;
|
|
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->base_reg = cpu->gdb_num_regs;
|
|
s->num_regs = num_regs;
|
|
s->num_regs = num_regs;
|
|
s->get_reg = get_reg;
|
|
s->get_reg = get_reg;
|
|
@@ -480,7 +488,6 @@ void gdb_register_coprocessor(CPUState *cpu,
|
|
|
|
|
|
/* Add to end of list. */
|
|
/* Add to end of list. */
|
|
cpu->gdb_num_regs += num_regs;
|
|
cpu->gdb_num_regs += num_regs;
|
|
- *p = s;
|
|
|
|
if (g_pos) {
|
|
if (g_pos) {
|
|
if (g_pos != s->base_reg) {
|
|
if (g_pos != s->base_reg) {
|
|
error_report("Error: Bad gdb register numbering for '%s', "
|
|
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;
|
|
int reg_size;
|
|
|
|
|
|
- if (!gdb_get_cpu_process(gdbserver_state.g_cpu)->target_xml) {
|
|
|
|
- gdb_put_packet("");
|
|
|
|
- return;
|
|
|
|
- }
|
|
|
|
-
|
|
|
|
if (params->len != 2) {
|
|
if (params->len != 2) {
|
|
gdb_put_packet("E22");
|
|
gdb_put_packet("E22");
|
|
return;
|
|
return;
|
|
@@ -1102,11 +1104,6 @@ static void handle_get_reg(GArray *params, void *user_ctx)
|
|
{
|
|
{
|
|
int reg_size;
|
|
int reg_size;
|
|
|
|
|
|
- if (!gdb_get_cpu_process(gdbserver_state.g_cpu)->target_xml) {
|
|
|
|
- gdb_put_packet("");
|
|
|
|
- return;
|
|
|
|
- }
|
|
|
|
-
|
|
|
|
if (!params->len) {
|
|
if (!params->len) {
|
|
gdb_put_packet("E14");
|
|
gdb_put_packet("E14");
|
|
return;
|
|
return;
|