@samitouri / QOSamiQemu / commits / b3e88abb20

gdbstub: Consider GDBFeature::base_reg in gdb_register_coprocessor()

When a feature XML file provides a "regnum=" tag to indicate the registers base index, respect it, as it might not be the same as our current number of registered entries, in particular when there are gaps. This fixes a bug with the "power-fpu.xml" file [*] which was loaded at index 70 while the base register is 71. This latent bug was exposed by commit 1ec0fbe2dda ("target/ppc: Fix CPUClass::gdb_num_core_regs value"). [*] https://lore.kernel.org/qemu-devel/e44df309-d40d-46f0-88a8-7ac55f9a3634@fhofhammer.de/ Reported-by: Florian Hofhammer <florian.hofhammer@fhofhammer.de> Signed-off-by: Philippe Mathieu-Daudé <philmd@linaro.org> Reviewed-by: Pierrick Bouvier <pierrick.bouvier@linaro.org> Tested-by: Pierrick Bouvier <pierrick.bouvier@linaro.org> Link: https://lore.kernel.org/qemu-devel/20260310232045.58440-13-philmd@linaro.org Signed-off-by: Pierrick Bouvier <pierrick.bouvier@linaro.org>

Philippe Mathieu-Daudé committed Mar 11, 2026 at 00:20 UTC b3e88abb200c357235ae1de34cd17b0b1fb24d78
2 files changed +7
gdbstub/gdbstub.c
+6
@@ -601,6 +601,7 @@ void gdb_init_cpu(CPUState *cpu)
601 if (xmlfile) {
602 assert(!cc->gdb_num_core_regs);
603 feature = gdb_find_static_feature(xmlfile);
604 + assert(feature->base_reg == 0);
605 gdb_register_feature(cpu, 0,
606 cc->gdb_read_register, cc->gdb_write_register,
607 feature);
@@ -630,6 +631,11 @@ void gdb_register_coprocessor(CPUState *cpu,
631 }
632 }
633
634 + if (base_reg < feature->base_reg) {
635 + trace_gdbxml_register_coprocessor_gap(base_reg,
636 + feature->base_reg);
637 + base_reg = feature->base_reg;
638 + }
639 gdb_register_feature(cpu, base_reg, get_reg, set_reg, feature);
640
641 /* Add to end of list. */
gdbstub/trace-events
+1
@@ -29,6 +29,7 @@ gdbstub_err_checksum_incorrect(uint8_t expected, uint8_t got) "got command packe
29 gdbstub_err_unexpected_runpkt(uint8_t ch) "unexpected packet (0x%02x) while target running"
30
31 gdbxml_init_cpu(const char *typename, unsigned id, unsigned gdb_num_regs, unsigned gdb_num_g_regs, unsigned gdb_num_core_regs) "%s:%d regs:%u g_regs:%u core_regs:%u"
32 +gdbxml_register_coprocessor_gap(unsigned gdb_num_regs, unsigned base_reg) "regs %u -> %u"
33 gdbxml_register_feature(const char *featname, const char *xmlname, unsigned base_reg, unsigned num_regs) "%s (%s) @%u +%u"
34 gdbxml_feature_builder_header(const char *name, const char *xmlname, int num_regs) "%s (%s) regs:%d"
35 gdbxml_feature_builder_content(const char *xml) "%s"