diff options
Diffstat (limited to 'target/arm/gdbstub.c')
| -rw-r--r-- | target/arm/gdbstub.c | 142 |
1 files changed, 69 insertions, 73 deletions
diff --git a/target/arm/gdbstub.c b/target/arm/gdbstub.c index 28f546a5ff..5949adfb31 100644 --- a/target/arm/gdbstub.c +++ b/target/arm/gdbstub.c @@ -26,11 +26,11 @@ #include "cpu-features.h" #include "cpregs.h" -typedef struct RegisterSysregXmlParam { +typedef struct RegisterSysregFeatureParam { CPUState *cs; - GString *s; + GDBFeatureBuilder builder; int n; -} RegisterSysregXmlParam; +} RegisterSysregFeatureParam; /* Old gdb always expect FPA registers. Newer (xml-aware) gdb only expect whatever the target description contains. Due to a historical mishap @@ -216,7 +216,7 @@ static int arm_gdb_get_sysreg(CPUARMState *env, GByteArray *buf, int reg) const ARMCPRegInfo *ri; uint32_t key; - key = cpu->dyn_sysreg_xml.data.cpregs.keys[reg]; + key = cpu->dyn_sysreg_feature.data.cpregs.keys[reg]; ri = get_arm_cp_reginfo(cpu->cp_regs, key); if (ri) { if (cpreg_field_is_64bit(ri)) { @@ -233,34 +233,32 @@ static int arm_gdb_set_sysreg(CPUARMState *env, uint8_t *buf, int reg) return 0; } -static void arm_gen_one_xml_sysreg_tag(GString *s, DynamicGDBXMLInfo *dyn_xml, +static void arm_gen_one_feature_sysreg(GDBFeatureBuilder *builder, + DynamicGDBFeatureInfo *dyn_feature, ARMCPRegInfo *ri, uint32_t ri_key, - int bitsize, int regnum) + int bitsize, int n) { - g_string_append_printf(s, "<reg name=\"%s\"", ri->name); - g_string_append_printf(s, " bitsize=\"%d\"", bitsize); - g_string_append_printf(s, " regnum=\"%d\"", regnum); - g_string_append_printf(s, " group=\"cp_regs\"/>"); - dyn_xml->data.cpregs.keys[dyn_xml->num] = ri_key; - dyn_xml->num++; + gdb_feature_builder_append_reg(builder, ri->name, bitsize, n, + "int", "cp_regs"); + + dyn_feature->data.cpregs.keys[n] = ri_key; } -static void arm_register_sysreg_for_xml(gpointer key, gpointer value, - gpointer p) +static void arm_register_sysreg_for_feature(gpointer key, gpointer value, + gpointer p) { uint32_t ri_key = (uintptr_t)key; ARMCPRegInfo *ri = value; - RegisterSysregXmlParam *param = (RegisterSysregXmlParam *)p; - GString *s = param->s; + RegisterSysregFeatureParam *param = p; ARMCPU *cpu = ARM_CPU(param->cs); CPUARMState *env = &cpu->env; - DynamicGDBXMLInfo *dyn_xml = &cpu->dyn_sysreg_xml; + DynamicGDBFeatureInfo *dyn_feature = &cpu->dyn_sysreg_feature; if (!(ri->type & (ARM_CP_NO_RAW | ARM_CP_NO_GDB))) { if (arm_feature(env, ARM_FEATURE_AARCH64)) { if (ri->state == ARM_CP_STATE_AA64) { - arm_gen_one_xml_sysreg_tag(s , dyn_xml, ri, ri_key, 64, - param->n++); + arm_gen_one_feature_sysreg(¶m->builder, dyn_feature, + ri, ri_key, 64, param->n++); } } else { if (ri->state == ARM_CP_STATE_AA32) { @@ -269,32 +267,32 @@ static void arm_register_sysreg_for_xml(gpointer key, gpointer value, return; } if (ri->type & ARM_CP_64BIT) { - arm_gen_one_xml_sysreg_tag(s , dyn_xml, ri, ri_key, 64, - param->n++); + arm_gen_one_feature_sysreg(¶m->builder, dyn_feature, + ri, ri_key, 64, param->n++); } else { - arm_gen_one_xml_sysreg_tag(s , dyn_xml, ri, ri_key, 32, - param->n++); + arm_gen_one_feature_sysreg(¶m->builder, dyn_feature, + ri, ri_key, 32, param->n++); } } } } } -static int arm_gen_dynamic_sysreg_xml(CPUState *cs, int base_reg) +static GDBFeature *arm_gen_dynamic_sysreg_feature(CPUState *cs, int base_reg) { ARMCPU *cpu = ARM_CPU(cs); - GString *s = g_string_new(NULL); - RegisterSysregXmlParam param = {cs, s, base_reg}; - - cpu->dyn_sysreg_xml.num = 0; - cpu->dyn_sysreg_xml.data.cpregs.keys = g_new(uint32_t, g_hash_table_size(cpu->cp_regs)); - g_string_printf(s, "<?xml version=\"1.0\"?>"); - g_string_append_printf(s, "<!DOCTYPE target SYSTEM \"gdb-target.dtd\">"); - g_string_append_printf(s, "<feature name=\"org.qemu.gdb.arm.sys.regs\">"); - g_hash_table_foreach(cpu->cp_regs, arm_register_sysreg_for_xml, ¶m); - g_string_append_printf(s, "</feature>"); - cpu->dyn_sysreg_xml.desc = g_string_free(s, false); - return cpu->dyn_sysreg_xml.num; + RegisterSysregFeatureParam param = {cs}; + gsize num_regs = g_hash_table_size(cpu->cp_regs); + + gdb_feature_builder_init(¶m.builder, + &cpu->dyn_sysreg_feature.desc, + "org.qemu.gdb.arm.sys.regs", + "system-registers.xml", + base_reg); + cpu->dyn_sysreg_feature.data.cpregs.keys = g_new(uint32_t, num_regs); + g_hash_table_foreach(cpu->cp_regs, arm_register_sysreg_for_feature, ¶m); + gdb_feature_builder_end(¶m.builder); + return &cpu->dyn_sysreg_feature.desc; } #ifdef CONFIG_TCG @@ -386,31 +384,29 @@ static int arm_gdb_set_m_systemreg(CPUARMState *env, uint8_t *buf, int reg) return 0; /* TODO */ } -static int arm_gen_dynamic_m_systemreg_xml(CPUState *cs, int orig_base_reg) +static GDBFeature *arm_gen_dynamic_m_systemreg_feature(CPUState *cs, + int base_reg) { ARMCPU *cpu = ARM_CPU(cs); CPUARMState *env = &cpu->env; - GString *s = g_string_new(NULL); - int base_reg = orig_base_reg; + GDBFeatureBuilder builder; + int reg = 0; int i; - g_string_printf(s, "<?xml version=\"1.0\"?>"); - g_string_append_printf(s, "<!DOCTYPE target SYSTEM \"gdb-target.dtd\">"); - g_string_append_printf(s, "<feature name=\"org.gnu.gdb.arm.m-system\">\n"); + gdb_feature_builder_init(&builder, &cpu->dyn_m_systemreg_feature.desc, + "org.gnu.gdb.arm.m-system", "arm-m-system.xml", + base_reg); for (i = 0; i < ARRAY_SIZE(m_sysreg_def); i++) { if (arm_feature(env, m_sysreg_def[i].feature)) { - g_string_append_printf(s, - "<reg name=\"%s\" bitsize=\"32\" regnum=\"%d\"/>\n", - m_sysreg_def[i].name, base_reg++); + gdb_feature_builder_append_reg(&builder, m_sysreg_def[i].name, 32, + reg++, "int", NULL); } } - g_string_append_printf(s, "</feature>"); - cpu->dyn_m_systemreg_xml.desc = g_string_free(s, false); - cpu->dyn_m_systemreg_xml.num = base_reg - orig_base_reg; + gdb_feature_builder_end(&builder); - return cpu->dyn_m_systemreg_xml.num; + return &cpu->dyn_m_systemreg_feature.desc; } #ifndef CONFIG_USER_ONLY @@ -428,31 +424,31 @@ static int arm_gdb_set_m_secextreg(CPUARMState *env, uint8_t *buf, int reg) return 0; /* TODO */ } -static int arm_gen_dynamic_m_secextreg_xml(CPUState *cs, int orig_base_reg) +static GDBFeature *arm_gen_dynamic_m_secextreg_feature(CPUState *cs, + int base_reg) { ARMCPU *cpu = ARM_CPU(cs); - GString *s = g_string_new(NULL); - int base_reg = orig_base_reg; + GDBFeatureBuilder builder; + char *name; + int reg = 0; int i; - g_string_printf(s, "<?xml version=\"1.0\"?>"); - g_string_append_printf(s, "<!DOCTYPE target SYSTEM \"gdb-target.dtd\">"); - g_string_append_printf(s, "<feature name=\"org.gnu.gdb.arm.secext\">\n"); + gdb_feature_builder_init(&builder, &cpu->dyn_m_secextreg_feature.desc, + "org.gnu.gdb.arm.secext", "arm-m-secext.xml", + base_reg); for (i = 0; i < ARRAY_SIZE(m_sysreg_def); i++) { - g_string_append_printf(s, - "<reg name=\"%s_ns\" bitsize=\"32\" regnum=\"%d\"/>\n", - m_sysreg_def[i].name, base_reg++); - g_string_append_printf(s, - "<reg name=\"%s_s\" bitsize=\"32\" regnum=\"%d\"/>\n", - m_sysreg_def[i].name, base_reg++); + name = g_strconcat(m_sysreg_def[i].name, "_ns", NULL); + gdb_feature_builder_append_reg(&builder, name, 32, reg++, + "int", NULL); + name = g_strconcat(m_sysreg_def[i].name, "_s", NULL); + gdb_feature_builder_append_reg(&builder, name, 32, reg++, + "int", NULL); } - g_string_append_printf(s, "</feature>"); - cpu->dyn_m_secextreg_xml.desc = g_string_free(s, false); - cpu->dyn_m_secextreg_xml.num = base_reg - orig_base_reg; + gdb_feature_builder_end(&builder); - return cpu->dyn_m_secextreg_xml.num; + return &cpu->dyn_m_secextreg_feature.desc; } #endif #endif /* CONFIG_TCG */ @@ -462,14 +458,14 @@ const char *arm_gdb_get_dynamic_xml(CPUState *cs, const char *xmlname) ARMCPU *cpu = ARM_CPU(cs); if (strcmp(xmlname, "system-registers.xml") == 0) { - return cpu->dyn_sysreg_xml.desc; + return cpu->dyn_sysreg_feature.desc.xml; } else if (strcmp(xmlname, "sve-registers.xml") == 0) { - return cpu->dyn_svereg_xml.desc; + return cpu->dyn_svereg_feature.desc.xml; } else if (strcmp(xmlname, "arm-m-system.xml") == 0) { - return cpu->dyn_m_systemreg_xml.desc; + return cpu->dyn_m_systemreg_feature.desc.xml; #ifndef CONFIG_USER_ONLY } else if (strcmp(xmlname, "arm-m-secext.xml") == 0) { - return cpu->dyn_m_secextreg_xml.desc; + return cpu->dyn_m_secextreg_feature.desc.xml; #endif } return NULL; @@ -487,7 +483,7 @@ void arm_cpu_register_gdb_regs_for_features(ARMCPU *cpu) */ #ifdef TARGET_AARCH64 if (isar_feature_aa64_sve(&cpu->isar)) { - int nreg = arm_gen_dynamic_svereg_xml(cs, cs->gdb_num_regs); + int nreg = arm_gen_dynamic_svereg_feature(cs, cs->gdb_num_regs)->num_regs; gdb_register_coprocessor(cs, aarch64_gdb_get_sve_reg, aarch64_gdb_set_sve_reg, nreg, "sve-registers.xml", 0); @@ -533,20 +529,20 @@ void arm_cpu_register_gdb_regs_for_features(ARMCPU *cpu) 1, "arm-m-profile-mve.xml", 0); } gdb_register_coprocessor(cs, arm_gdb_get_sysreg, arm_gdb_set_sysreg, - arm_gen_dynamic_sysreg_xml(cs, cs->gdb_num_regs), + arm_gen_dynamic_sysreg_feature(cs, cs->gdb_num_regs)->num_regs, "system-registers.xml", 0); #ifdef CONFIG_TCG if (arm_feature(env, ARM_FEATURE_M) && tcg_enabled()) { gdb_register_coprocessor(cs, arm_gdb_get_m_systemreg, arm_gdb_set_m_systemreg, - arm_gen_dynamic_m_systemreg_xml(cs, cs->gdb_num_regs), + arm_gen_dynamic_m_systemreg_feature(cs, cs->gdb_num_regs)->num_regs, "arm-m-system.xml", 0); #ifndef CONFIG_USER_ONLY if (arm_feature(env, ARM_FEATURE_M_SECURITY)) { gdb_register_coprocessor(cs, arm_gdb_get_m_secextreg, arm_gdb_set_m_secextreg, - arm_gen_dynamic_m_secextreg_xml(cs, cs->gdb_num_regs), + arm_gen_dynamic_m_secextreg_feature(cs, cs->gdb_num_regs)->num_regs, "arm-m-secext.xml", 0); } #endif |