* [PATCH 00/10] monitor/hmp: replace MonitorDef with GDB registers
@ 2026-09-11 12:27 Marc-André Lureau
2026-09-11 12:27 ` [PATCH 01/10] hmp: don't crash on invalid register Marc-André Lureau
` (9 more replies)
0 siblings, 10 replies; 12+ messages in thread
From: Marc-André Lureau @ 2026-09-11 12:27 UTC (permalink / raw)
To: qemu-devel
Cc: Dr. David Alan Gilbert, Alex Bennée,
Philippe Mathieu-Daudé, Zhao Liu, Peter Maydell,
Chinmay Rath, Nicholas Piggin, Glenn Miles, Harsh Prateek Bora,
Palmer Dabbelt, Alistair Francis, Weiwei Li,
Daniel Henrique Barboza, Liu Zhiwei, Chao Liu, Max Filippov,
qemu-arm, qemu-ppc, qemu-riscv, Paolo Bonzini, Laurent Vivier,
Mark Cave-Ayland, Artyom Tarasenko, Helge Deller,
Pierrick Bouvier, Warner Losh, Kyle Evans, Marc-André Lureau
Hi,
HMP monitor supports printing $register expression. The lookup
was done via GDB stub registers, and supplementary MonitorDef
HMP-specific tables.
Migrate HMP registers to use the GDB infrastructure and remove the
legacy HMP MonitorDef. Use a "qemu-debug" register group, as they are
aliases or synthetic registers, but gdb doesn't seem to care.
Known behavioural changes on RISC-V: CSR lookup is now case-sensitive
and vector registers now report "unkown register" instead of a
target-specific message ("Unable to print the value of vector vreg 'v0'
from this API")
Signed-off-by: Marc-André Lureau <marcandre.lureau@redhat.com>
---
Marc-André Lureau (10):
hmp: don't crash on invalid register
gdbstub: fix next register base after register gaps
gdbstub: set feature->base_reg for dynamic features
target/i386: expose segment limits via GDB
monitor/hmp: add CPUClass::get_pc fallback for HMP $pc
target/m68k: expose system registers via GDB
target/sparc64: expose system registers via GDB
target/riscv: bypass smstateen check in debugger mode
target/riscv: expose register aliases via GDB
monitor/hmp: remove legacy MonitorDef infrastructure
configs/targets/i386-softmmu.mak | 2 +-
configs/targets/m68k-softmmu.mak | 2 +-
configs/targets/riscv32-linux-user.mak | 2 +-
configs/targets/riscv32-softmmu.mak | 2 +-
configs/targets/riscv64-bsd-user.mak | 2 +-
configs/targets/riscv64-linux-user.mak | 2 +-
configs/targets/riscv64-softmmu.mak | 2 +-
configs/targets/sparc64-softmmu.mak | 2 +-
configs/targets/x86_64-softmmu.mak | 2 +-
gdbstub/gdb-xml/i386-segments.xml | 14 +++
gdbstub/gdb-xml/m68k-system.xml | 32 +++++++
gdbstub/gdb-xml/riscv-32bit-alias.xml | 105 ++++++++++++++++++++++
gdbstub/gdb-xml/riscv-32bit-fpu-alias.xml | 40 +++++++++
gdbstub/gdb-xml/riscv-64bit-alias.xml | 105 ++++++++++++++++++++++
gdbstub/gdb-xml/riscv-64bit-fpu-alias.xml | 46 ++++++++++
gdbstub/gdb-xml/sparc64-system.xml | 22 +++++
gdbstub/gdbstub.c | 14 +--
include/hw/core/cpu.h | 2 +-
include/hw/core/sysemu-cpu-ops.h | 16 ----
include/monitor/hmp.h | 6 --
include/qemu/typedefs.h | 1 -
monitor/hmp.c | 52 ++---------
target/arm/gdbstub.c | 8 +-
target/arm/gdbstub64.c | 10 ++-
target/i386/cpu.c | 32 -------
target/i386/gdbstub.c | 24 +++++
target/m68k/cpu.c | 22 -----
target/m68k/helper.c | 47 ++++++++++
target/ppc/gdbstub.c | 2 +-
target/riscv/cpu.c | 1 -
target/riscv/gdbstub.c | 52 ++++++++++-
target/riscv/internals.h | 3 -
target/riscv/monitor.c | 140 ------------------------------
target/riscv/tcg/csr.c | 3 +-
target/sparc/cpu.c | 19 ----
target/sparc/gdbstub.c | 38 ++++++++
target/xtensa/cpu.c | 2 +-
37 files changed, 562 insertions(+), 314 deletions(-)
---
base-commit: 209b2afaface001c7d4d981e38f186afe7b24a50
change-id: 20260910-query-reg-80cd59cf4707
Best regards,
--
Marc-André Lureau <marcandre.lureau@redhat.com>
^ permalink raw reply [flat|nested] 12+ messages in thread
* [PATCH 01/10] hmp: don't crash on invalid register
2026-09-11 12:27 [PATCH 00/10] monitor/hmp: replace MonitorDef with GDB registers Marc-André Lureau
@ 2026-09-11 12:27 ` Marc-André Lureau
2026-09-11 12:27 ` [PATCH 02/10] gdbstub: fix next register base after register gaps Marc-André Lureau
` (8 subsequent siblings)
9 siblings, 0 replies; 12+ messages in thread
From: Marc-André Lureau @ 2026-09-11 12:27 UTC (permalink / raw)
To: qemu-devel
Cc: Dr. David Alan Gilbert, Alex Bennée,
Philippe Mathieu-Daudé, Zhao Liu, Peter Maydell,
Chinmay Rath, Nicholas Piggin, Glenn Miles, Harsh Prateek Bora,
Palmer Dabbelt, Alistair Francis, Weiwei Li,
Daniel Henrique Barboza, Liu Zhiwei, Chao Liu, Max Filippov,
qemu-arm, qemu-ppc, qemu-riscv, Paolo Bonzini, Laurent Vivier,
Mark Cave-Ayland, Artyom Tarasenko, Helge Deller,
Pierrick Bouvier, Warner Losh, Kyle Evans, Marc-André Lureau
When printing an invalid/denied register, QEMU crashes with:
ERROR:include/qemu/bswap.h:488:ldn_le_p: code should not be reached
(ex: "p $sireg" when siselect=0 on riscv)
Return false instead.
Signed-off-by: Marc-André Lureau <marcandre.lureau@redhat.com>
---
monitor/hmp.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/monitor/hmp.c b/monitor/hmp.c
index 488ec23937df..10e19e417aba 100644
--- a/monitor/hmp.c
+++ b/monitor/hmp.c
@@ -424,7 +424,7 @@ static bool gdb_get_register(MonitorHMP *hmp, int64_t *pval, const char *name)
buf = g_byte_array_new();
reg_size = gdb_read_register(cs, buf, reg->gdb_reg);
- if (reg_size > sizeof(*pval)) {
+ if (reg_size == 0 || reg_size > sizeof(*pval)) {
return false;
}
--
2.55.0.543.g5ebe2ebe4ea8
^ permalink raw reply related [flat|nested] 12+ messages in thread
* [PATCH 02/10] gdbstub: fix next register base after register gaps
2026-09-11 12:27 [PATCH 00/10] monitor/hmp: replace MonitorDef with GDB registers Marc-André Lureau
2026-09-11 12:27 ` [PATCH 01/10] hmp: don't crash on invalid register Marc-André Lureau
@ 2026-09-11 12:27 ` Marc-André Lureau
2026-09-11 15:29 ` Alex Bennée
2026-09-11 12:27 ` [PATCH 03/10] gdbstub: set feature->base_reg for dynamic features Marc-André Lureau
` (7 subsequent siblings)
9 siblings, 1 reply; 12+ messages in thread
From: Marc-André Lureau @ 2026-09-11 12:27 UTC (permalink / raw)
To: qemu-devel
Cc: Dr. David Alan Gilbert, Alex Bennée,
Philippe Mathieu-Daudé, Zhao Liu, Peter Maydell,
Chinmay Rath, Nicholas Piggin, Glenn Miles, Harsh Prateek Bora,
Palmer Dabbelt, Alistair Francis, Weiwei Li,
Daniel Henrique Barboza, Liu Zhiwei, Chao Liu, Max Filippov,
qemu-arm, qemu-ppc, qemu-riscv, Paolo Bonzini, Laurent Vivier,
Mark Cave-Ayland, Artyom Tarasenko, Helge Deller,
Pierrick Bouvier, Warner Losh, Kyle Evans, Marc-André Lureau
Commit b3e88abb200c ("gdbstub: Consider GDBFeature::base_reg in
gdb_register_coprocessor()") identified that register numbers may
have gaps. We also need to adjust the next base_reg correctly
to avoid overlapping registers. Rename the field to be more
explicit about its usage.
Signed-off-by: Marc-André Lureau <marcandre.lureau@redhat.com>
---
gdbstub/gdbstub.c | 13 ++++++-------
include/hw/core/cpu.h | 2 +-
target/arm/gdbstub.c | 8 +++++---
target/arm/gdbstub64.c | 10 ++++++----
target/ppc/gdbstub.c | 2 +-
target/riscv/gdbstub.c | 9 ++++++---
target/xtensa/cpu.c | 2 +-
7 files changed, 26 insertions(+), 20 deletions(-)
diff --git a/gdbstub/gdbstub.c b/gdbstub/gdbstub.c
index 0a328b0dd488..0ce871d74929 100644
--- a/gdbstub/gdbstub.c
+++ b/gdbstub/gdbstub.c
@@ -605,13 +605,13 @@ void gdb_init_cpu(CPUState *cpu)
gdb_register_feature(cpu, 0,
cc->gdb_read_register, cc->gdb_write_register,
feature);
- cpu->gdb_num_regs = cpu->gdb_num_g_regs = feature->num_regs;
+ cpu->gdb_next_base_reg = cpu->gdb_num_g_regs = feature->num_regs;
} else {
- cpu->gdb_num_regs = cpu->gdb_num_g_regs = cc->gdb_num_core_regs;
+ cpu->gdb_next_base_reg = cpu->gdb_num_g_regs = cc->gdb_num_core_regs;
}
trace_gdbxml_init_cpu(object_get_typename(OBJECT(cpu)), cpu->cpu_index,
- cpu->gdb_num_regs, cpu->gdb_num_g_regs,
+ cpu->gdb_next_base_reg, cpu->gdb_num_g_regs,
cc->gdb_num_core_regs);
}
@@ -621,7 +621,7 @@ void gdb_register_coprocessor(CPUState *cpu,
{
GDBRegisterState *s;
guint i;
- int base_reg = cpu->gdb_num_regs;
+ int base_reg = cpu->gdb_next_base_reg;
for (i = 0; i < cpu->gdb_regs->len; i++) {
/* Check for duplicates. */
@@ -639,7 +639,7 @@ void gdb_register_coprocessor(CPUState *cpu,
gdb_register_feature(cpu, base_reg, get_reg, set_reg, feature);
/* Add to end of list. */
- cpu->gdb_num_regs += feature->num_regs;
+ cpu->gdb_next_base_reg = base_reg + feature->num_regs;
}
void gdb_unregister_coprocessor_all(CPUState *cpu)
@@ -651,7 +651,7 @@ void gdb_unregister_coprocessor_all(CPUState *cpu)
g_array_free(cpu->gdb_regs, true);
cpu->gdb_regs = NULL;
- cpu->gdb_num_regs = 0;
+ cpu->gdb_next_base_reg = 0;
cpu->gdb_num_g_regs = 0;
}
@@ -2522,4 +2522,3 @@ void gdb_create_default_process(GDBState *s)
process->attached = false;
process->target_xml = NULL;
}
-
diff --git a/include/hw/core/cpu.h b/include/hw/core/cpu.h
index 328e30045ce1..02212f555c2e 100644
--- a/include/hw/core/cpu.h
+++ b/include/hw/core/cpu.h
@@ -521,7 +521,7 @@ struct CPUState {
struct CPUJumpCache *tb_jmp_cache;
GArray *gdb_regs;
- int gdb_num_regs;
+ int gdb_next_base_reg;
int gdb_num_g_regs;
QTAILQ_ENTRY(CPUState) node;
diff --git a/target/arm/gdbstub.c b/target/arm/gdbstub.c
index d6e29c4cf467..e5cbe4d951ef 100644
--- a/target/arm/gdbstub.c
+++ b/target/arm/gdbstub.c
@@ -555,19 +555,21 @@ void arm_cpu_register_gdb_regs_for_features(ARMCPU *cpu)
gdb_register_coprocessor(cs, mve_gdb_get_reg, mve_gdb_set_reg,
gdb_find_static_feature("arm-m-profile-mve.xml"));
}
+ GDBFeature *feature =
+ arm_gen_dynamic_sysreg_feature(cs, cs->gdb_next_base_reg);
gdb_register_coprocessor(cs, arm_gdb_get_sysreg, arm_gdb_set_sysreg,
- arm_gen_dynamic_sysreg_feature(cs, cs->gdb_num_regs));
+ feature);
#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_feature(cs, cs->gdb_num_regs));
+ arm_gen_dynamic_m_systemreg_feature(cs, cs->gdb_next_base_reg));
#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_feature(cs, cs->gdb_num_regs));
+ arm_gen_dynamic_m_secextreg_feature(cs, cs->gdb_next_base_reg));
}
#endif
}
diff --git a/target/arm/gdbstub64.c b/target/arm/gdbstub64.c
index 0c3e5b30bd6a..cf5b95b54641 100644
--- a/target/arm/gdbstub64.c
+++ b/target/arm/gdbstub64.c
@@ -885,7 +885,8 @@ void aarch64_cpu_register_gdb_regs_for_features(ARMCPU *cpu)
CPUState *cs = CPU(cpu);
if (isar_feature_aa64_sve(&cpu->isar) ||
isar_feature_aa64_sme(&cpu->isar)) {
- GDBFeature *feature = arm_gen_dynamic_svereg_feature(cs, cs->gdb_num_regs);
+ GDBFeature *feature =
+ arm_gen_dynamic_svereg_feature(cs, cs->gdb_next_base_reg);
gdb_register_coprocessor(cs, aarch64_gdb_get_sve_reg,
aarch64_gdb_set_sve_reg, feature);
} else {
@@ -896,7 +897,7 @@ void aarch64_cpu_register_gdb_regs_for_features(ARMCPU *cpu)
if (isar_feature_aa64_sme(&cpu->isar)) {
GDBFeature *sme_feature =
- arm_gen_dynamic_smereg_feature(cs, cs->gdb_num_regs);
+ arm_gen_dynamic_smereg_feature(cs, cs->gdb_next_base_reg);
gdb_register_coprocessor(cs, aarch64_gdb_get_sme_reg,
aarch64_gdb_set_sme_reg, sme_feature);
if (isar_feature_aa64_sme2(&cpu->isar)) {
@@ -927,7 +928,8 @@ void aarch64_cpu_register_gdb_regs_for_features(ARMCPU *cpu)
#endif
/* All AArch64 CPUs have at least TPIDR */
+ GDBFeature *tls_feature =
+ arm_gen_dynamic_tls_feature(cs, cs->gdb_next_base_reg);
gdb_register_coprocessor(cs, aarch64_gdb_get_tls_reg,
- aarch64_gdb_set_tls_reg,
- arm_gen_dynamic_tls_feature(cs, cs->gdb_num_regs));
+ aarch64_gdb_set_tls_reg, tls_feature);
}
diff --git a/target/ppc/gdbstub.c b/target/ppc/gdbstub.c
index 4d622c5cad59..ec25c541c685 100644
--- a/target/ppc/gdbstub.c
+++ b/target/ppc/gdbstub.c
@@ -206,7 +206,7 @@ static void gdb_gen_spr_feature(CPUState *cs)
gdb_feature_builder_init(&builder, &pcc->gdb_spr,
"org.qemu.power.spr", "power-spr.xml",
- cs->gdb_num_regs);
+ cs->gdb_next_base_reg);
for (i = 0; i < ARRAY_SIZE(env->spr_cb); i++) {
ppc_spr_t *spr = &env->spr_cb[i];
diff --git a/target/riscv/gdbstub.c b/target/riscv/gdbstub.c
index 9abbf5bcdf0e..f279f4ab2461 100644
--- a/target/riscv/gdbstub.c
+++ b/target/riscv/gdbstub.c
@@ -348,9 +348,10 @@ void riscv_cpu_register_gdb_regs_for_features(CPUState *cs)
gdb_find_static_feature("riscv-32bit-fpu.xml"));
}
if (cpu->cfg.ext_zve32x) {
+ GDBFeature *feature =
+ ricsv_gen_dynamic_vector_feature(cs, cs->gdb_next_base_reg);
gdb_register_coprocessor(cs, riscv_gdb_get_vector,
- riscv_gdb_set_vector,
- ricsv_gen_dynamic_vector_feature(cs, cs->gdb_num_regs));
+ riscv_gdb_set_vector, feature);
}
#ifdef CONFIG_TCG
@@ -373,8 +374,10 @@ void riscv_cpu_register_gdb_regs_for_features(CPUState *cs)
}
if (cpu->cfg.ext_zicsr) {
+ GDBFeature *feature =
+ riscv_gen_dynamic_csr_feature(cs, cs->gdb_next_base_reg);
gdb_register_coprocessor(cs, riscv_gdb_get_csr, riscv_gdb_set_csr,
- riscv_gen_dynamic_csr_feature(cs, cs->gdb_num_regs));
+ feature);
}
#endif
}
diff --git a/target/xtensa/cpu.c b/target/xtensa/cpu.c
index 7c25b9ab707a..48863a1859d4 100644
--- a/target/xtensa/cpu.c
+++ b/target/xtensa/cpu.c
@@ -263,7 +263,7 @@ static void xtensa_cpu_realizefn(DeviceState *dev, Error **errp)
return;
}
- cs->gdb_num_regs = xcc->config->gdb_regmap.num_regs;
+ cs->gdb_next_base_reg = xcc->config->gdb_regmap.num_regs;
qemu_init_vcpu(cs);
--
2.55.0.543.g5ebe2ebe4ea8
^ permalink raw reply related [flat|nested] 12+ messages in thread
* [PATCH 03/10] gdbstub: set feature->base_reg for dynamic features
2026-09-11 12:27 [PATCH 00/10] monitor/hmp: replace MonitorDef with GDB registers Marc-André Lureau
2026-09-11 12:27 ` [PATCH 01/10] hmp: don't crash on invalid register Marc-André Lureau
2026-09-11 12:27 ` [PATCH 02/10] gdbstub: fix next register base after register gaps Marc-André Lureau
@ 2026-09-11 12:27 ` Marc-André Lureau
2026-09-11 12:27 ` [PATCH 04/10] target/i386: expose segment limits via GDB Marc-André Lureau
` (6 subsequent siblings)
9 siblings, 0 replies; 12+ messages in thread
From: Marc-André Lureau @ 2026-09-11 12:27 UTC (permalink / raw)
To: qemu-devel
Cc: Dr. David Alan Gilbert, Alex Bennée,
Philippe Mathieu-Daudé, Zhao Liu, Peter Maydell,
Chinmay Rath, Nicholas Piggin, Glenn Miles, Harsh Prateek Bora,
Palmer Dabbelt, Alistair Francis, Weiwei Li,
Daniel Henrique Barboza, Liu Zhiwei, Chao Liu, Max Filippov,
qemu-arm, qemu-ppc, qemu-riscv, Paolo Bonzini, Laurent Vivier,
Mark Cave-Ayland, Artyom Tarasenko, Helge Deller,
Pierrick Bouvier, Warner Losh, Kyle Evans, Marc-André Lureau
gdb_feature_builder_end() never propagated builder->base_reg into
feature->base_reg, leaving it at 0 for all dynamically-built features.
This made the trace log at gdb_get_register_list() report an incorrect
base_reg for dynamic features.
GDBRegisterState::base_reg was correctly set, so this doesn't fix
an actual issue.
Signed-off-by: Marc-André Lureau <marcandre.lureau@redhat.com>
---
gdbstub/gdbstub.c | 1 +
1 file changed, 1 insertion(+)
diff --git a/gdbstub/gdbstub.c b/gdbstub/gdbstub.c
index 0ce871d74929..912e31b66744 100644
--- a/gdbstub/gdbstub.c
+++ b/gdbstub/gdbstub.c
@@ -476,6 +476,7 @@ void gdb_feature_builder_end(const GDBFeatureBuilder *builder)
g_ptr_array_free(builder->xml, TRUE);
+ builder->feature->base_reg = builder->base_reg;
builder->feature->num_regs = builder->regs->len;
builder->feature->regs = (void *)g_ptr_array_free(builder->regs, FALSE);
trace_gdbxml_feature_builder_header(builder->feature->name,
--
2.55.0.543.g5ebe2ebe4ea8
^ permalink raw reply related [flat|nested] 12+ messages in thread
* [PATCH 04/10] target/i386: expose segment limits via GDB
2026-09-11 12:27 [PATCH 00/10] monitor/hmp: replace MonitorDef with GDB registers Marc-André Lureau
` (2 preceding siblings ...)
2026-09-11 12:27 ` [PATCH 03/10] gdbstub: set feature->base_reg for dynamic features Marc-André Lureau
@ 2026-09-11 12:27 ` Marc-André Lureau
2026-09-11 12:27 ` [PATCH 05/10] monitor/hmp: add CPUClass::get_pc fallback for HMP $pc Marc-André Lureau
` (5 subsequent siblings)
9 siblings, 0 replies; 12+ messages in thread
From: Marc-André Lureau @ 2026-09-11 12:27 UTC (permalink / raw)
To: qemu-devel
Cc: Dr. David Alan Gilbert, Alex Bennée,
Philippe Mathieu-Daudé, Zhao Liu, Peter Maydell,
Chinmay Rath, Nicholas Piggin, Glenn Miles, Harsh Prateek Bora,
Palmer Dabbelt, Alistair Francis, Weiwei Li,
Daniel Henrique Barboza, Liu Zhiwei, Chao Liu, Max Filippov,
qemu-arm, qemu-ppc, qemu-riscv, Paolo Bonzini, Laurent Vivier,
Mark Cave-Ayland, Artyom Tarasenko, Helge Deller,
Pierrick Bouvier, Warner Losh, Kyle Evans, Marc-André Lureau
Add an i386-segments.xml GDB feature that exposes the six segment
limit registers (cs, ds, es, ss, fs, gs) as read-only system
registers through the GDB coprocessor interface. This makes them
accessible to both GDB and HMP without relying on the legacy
MonitorDef table, which will be removed in a subsequent commit.
Signed-off-by: Marc-André Lureau <marcandre.lureau@redhat.com>
---
configs/targets/i386-softmmu.mak | 2 +-
configs/targets/x86_64-softmmu.mak | 2 +-
gdbstub/gdb-xml/i386-segments.xml | 14 ++++++++++++++
target/i386/gdbstub.c | 24 ++++++++++++++++++++++++
4 files changed, 40 insertions(+), 2 deletions(-)
diff --git a/configs/targets/i386-softmmu.mak b/configs/targets/i386-softmmu.mak
index 38a8f85201f9..89cdaa072ef7 100644
--- a/configs/targets/i386-softmmu.mak
+++ b/configs/targets/i386-softmmu.mak
@@ -1,6 +1,6 @@
TARGET_ARCH=i386
TARGET_KVM_HAVE_GUEST_DEBUG=y
TARGET_KVM_HAVE_RESET_PARKED_VCPU=y
-TARGET_XML_FILES= i386-32bit.xml
+TARGET_XML_FILES= i386-32bit.xml i386-segments.xml
TARGET_LONG_BITS=32
TARGET_NOT_USING_LEGACY_LDST_PHYS_API=y
diff --git a/configs/targets/x86_64-softmmu.mak b/configs/targets/x86_64-softmmu.mak
index c7f8746b4f58..0af699971de0 100644
--- a/configs/targets/x86_64-softmmu.mak
+++ b/configs/targets/x86_64-softmmu.mak
@@ -2,6 +2,6 @@ TARGET_ARCH=x86_64
TARGET_BASE_ARCH=i386
TARGET_KVM_HAVE_GUEST_DEBUG=y
TARGET_KVM_HAVE_RESET_PARKED_VCPU=y
-TARGET_XML_FILES= i386-64bit.xml i386-64bit-apx.xml
+TARGET_XML_FILES= i386-64bit.xml i386-64bit-apx.xml i386-segments.xml
TARGET_LONG_BITS=64
TARGET_NOT_USING_LEGACY_LDST_PHYS_API=y
diff --git a/gdbstub/gdb-xml/i386-segments.xml b/gdbstub/gdb-xml/i386-segments.xml
new file mode 100644
index 000000000000..6fbf3f91957e
--- /dev/null
+++ b/gdbstub/gdb-xml/i386-segments.xml
@@ -0,0 +1,14 @@
+<?xml version="1.0"?>
+<!--
+ SPDX-License-Identifier: GPL-2.0-or-later
+-->
+<!DOCTYPE feature SYSTEM "gdb-target.dtd">
+<!-- Segment-cache values are read-only; writes are ignored. -->
+<feature name="org.qemu.gdb.i386.segments">
+ <reg name="cs.limit" bitsize="32" type="uint32" group="qemu-debug" save-restore="no"/>
+ <reg name="ds.limit" bitsize="32" type="uint32" group="qemu-debug" save-restore="no"/>
+ <reg name="es.limit" bitsize="32" type="uint32" group="qemu-debug" save-restore="no"/>
+ <reg name="ss.limit" bitsize="32" type="uint32" group="qemu-debug" save-restore="no"/>
+ <reg name="fs.limit" bitsize="32" type="uint32" group="qemu-debug" save-restore="no"/>
+ <reg name="gs.limit" bitsize="32" type="uint32" group="qemu-debug" save-restore="no"/>
+</feature>
diff --git a/target/i386/gdbstub.c b/target/i386/gdbstub.c
index 5c5fa7272163..2729b0f5bc1e 100644
--- a/target/i386/gdbstub.c
+++ b/target/i386/gdbstub.c
@@ -493,6 +493,25 @@ static int i386_cpu_gdb_set_egprs(CPUState *cs, uint8_t *mem_buf, int n)
}
#endif
+#ifndef CONFIG_USER_ONLY
+static int x86_gdb_read_segment_limit(CPUState *cs, GByteArray *buf, int n)
+{
+ CPUX86State *env = cpu_env(cs);
+ static const int segments[] = { R_CS, R_DS, R_ES, R_SS, R_FS, R_GS };
+
+ if (n < 0 || n >= ARRAY_SIZE(segments)) {
+ return 0;
+ }
+ return gdb_get_reg32(buf, env->segs[segments[n]].limit);
+}
+
+static int x86_gdb_write_segment_limit(CPUState *cs, uint8_t *buf, int n)
+{
+ /* Segment caches are exposed for inspection only. Ignore writes. */
+ return 4;
+}
+#endif
+
void x86_cpu_gdb_init(CPUState *cs)
{
#ifdef TARGET_X86_64
@@ -514,4 +533,9 @@ void x86_cpu_gdb_init(CPUState *cs)
gdb_find_static_feature("i386-32bit-linux.xml"));
#endif
#endif
+#ifndef CONFIG_USER_ONLY
+ gdb_register_coprocessor(cs, x86_gdb_read_segment_limit,
+ x86_gdb_write_segment_limit,
+ gdb_find_static_feature("i386-segments.xml"));
+#endif
}
--
2.55.0.543.g5ebe2ebe4ea8
^ permalink raw reply related [flat|nested] 12+ messages in thread
* [PATCH 05/10] monitor/hmp: add CPUClass::get_pc fallback for HMP $pc
2026-09-11 12:27 [PATCH 00/10] monitor/hmp: replace MonitorDef with GDB registers Marc-André Lureau
` (3 preceding siblings ...)
2026-09-11 12:27 ` [PATCH 04/10] target/i386: expose segment limits via GDB Marc-André Lureau
@ 2026-09-11 12:27 ` Marc-André Lureau
2026-09-11 12:27 ` [PATCH 06/10] target/m68k: expose system registers via GDB Marc-André Lureau
` (4 subsequent siblings)
9 siblings, 0 replies; 12+ messages in thread
From: Marc-André Lureau @ 2026-09-11 12:27 UTC (permalink / raw)
To: qemu-devel
Cc: Dr. David Alan Gilbert, Alex Bennée,
Philippe Mathieu-Daudé, Zhao Liu, Peter Maydell,
Chinmay Rath, Nicholas Piggin, Glenn Miles, Harsh Prateek Bora,
Palmer Dabbelt, Alistair Francis, Weiwei Li,
Daniel Henrique Barboza, Liu Zhiwei, Chao Liu, Max Filippov,
qemu-arm, qemu-ppc, qemu-riscv, Paolo Bonzini, Laurent Vivier,
Mark Cave-Ayland, Artyom Tarasenko, Helge Deller,
Pierrick Bouvier, Warner Losh, Kyle Evans, Marc-André Lureau
Some targets, including x86, have no GDB register named "pc" (x86
uses eip/rip). When the GDB register lookup fails for "$pc" in
HMP expressions, fall back to CPUClass::get_pc so that "p $pc",
"x $pc" etc. work without relying on the legacy MonitorDef table.
This prepares for the eventual removal of MonitorDef while making
$pc available immediately for all targets that implement get_pc.
Signed-off-by: Marc-André Lureau <marcandre.lureau@redhat.com>
---
monitor/hmp.c | 8 ++++++--
1 file changed, 6 insertions(+), 2 deletions(-)
diff --git a/monitor/hmp.c b/monitor/hmp.c
index 10e19e417aba..0a74247ca66a 100644
--- a/monitor/hmp.c
+++ b/monitor/hmp.c
@@ -402,7 +402,7 @@ void hmp_help_cmd(MonitorHMP *mon, const char *name)
* Set @pval to the value in the register identified by @name.
* return %true if the register is found, %false otherwise.
*/
-static bool gdb_get_register(MonitorHMP *hmp, int64_t *pval, const char *name)
+static bool get_register(MonitorHMP *hmp, int64_t *pval, const char *name)
{
g_autoptr(GArray) regs = NULL;
CPUState *cs = monitor_hmp_get_cpu(hmp);
@@ -435,6 +435,10 @@ static bool gdb_get_register(MonitorHMP *hmp, int64_t *pval, const char *name)
}
return true;
}
+ if (!strcmp(name, "pc") && cs->cc->get_pc) {
+ *pval = cs->cc->get_pc(cs);
+ return true;
+ }
return false;
}
@@ -526,7 +530,7 @@ static int64_t expr_unary(MonitorHMP *mon)
pch++;
}
*q = 0;
- if (!gdb_get_register(mon, ®, buf)
+ if (!get_register(mon, ®, buf)
&& get_monitor_def(mon, ®, buf) < 0) {
expr_error(mon, "unknown register");
}
--
2.55.0.543.g5ebe2ebe4ea8
^ permalink raw reply related [flat|nested] 12+ messages in thread
* [PATCH 06/10] target/m68k: expose system registers via GDB
2026-09-11 12:27 [PATCH 00/10] monitor/hmp: replace MonitorDef with GDB registers Marc-André Lureau
` (4 preceding siblings ...)
2026-09-11 12:27 ` [PATCH 05/10] monitor/hmp: add CPUClass::get_pc fallback for HMP $pc Marc-André Lureau
@ 2026-09-11 12:27 ` Marc-André Lureau
2026-09-11 12:27 ` [PATCH 07/10] target/sparc64: " Marc-André Lureau
` (3 subsequent siblings)
9 siblings, 0 replies; 12+ messages in thread
From: Marc-André Lureau @ 2026-09-11 12:27 UTC (permalink / raw)
To: qemu-devel
Cc: Dr. David Alan Gilbert, Alex Bennée,
Philippe Mathieu-Daudé, Zhao Liu, Peter Maydell,
Chinmay Rath, Nicholas Piggin, Glenn Miles, Harsh Prateek Bora,
Palmer Dabbelt, Alistair Francis, Weiwei Li,
Daniel Henrique Barboza, Liu Zhiwei, Chao Liu, Max Filippov,
qemu-arm, qemu-ppc, qemu-riscv, Paolo Bonzini, Laurent Vivier,
Mark Cave-Ayland, Artyom Tarasenko, Helge Deller,
Pierrick Bouvier, Warner Losh, Kyle Evans, Marc-André Lureau
Add an m68k-system.xml GDB feature that exposes supervisor stack
pointers (ssp, usp, isp), function code registers (sfc, dfc), MMU
registers (urp, srp, dttr0/1, ittr0/1, mmusr) as read-only system
registers through the GDB coprocessor interface.
Signed-off-by: Marc-André Lureau <marcandre.lureau@redhat.com>
---
configs/targets/m68k-softmmu.mak | 2 +-
gdbstub/gdb-xml/m68k-system.xml | 32 +++++++++++++++++++++++++++
target/m68k/helper.c | 47 ++++++++++++++++++++++++++++++++++++++++
3 files changed, 80 insertions(+), 1 deletion(-)
diff --git a/configs/targets/m68k-softmmu.mak b/configs/targets/m68k-softmmu.mak
index 0bc889f326e3..f3ac9b74c862 100644
--- a/configs/targets/m68k-softmmu.mak
+++ b/configs/targets/m68k-softmmu.mak
@@ -1,4 +1,4 @@
TARGET_ARCH=m68k
TARGET_BIG_ENDIAN=y
-TARGET_XML_FILES= cf-core.xml cf-fp.xml m68k-core.xml m68k-fp.xml
+TARGET_XML_FILES= cf-core.xml cf-fp.xml m68k-core.xml m68k-fp.xml m68k-system.xml
TARGET_LONG_BITS=32
diff --git a/gdbstub/gdb-xml/m68k-system.xml b/gdbstub/gdb-xml/m68k-system.xml
new file mode 100644
index 000000000000..0a91be0edc00
--- /dev/null
+++ b/gdbstub/gdb-xml/m68k-system.xml
@@ -0,0 +1,32 @@
+<?xml version="1.0"?>
+<!--
+ SPDX-License-Identifier: GPL-2.0-or-later
+-->
+<!DOCTYPE feature SYSTEM "gdb-target.dtd">
+<!-- System-register values are read-only; writes are ignored. -->
+<feature name="org.qemu.gdb.m68k.system">
+ <reg name="ssp" bitsize="32" type="uint32"
+ group="qemu-debug" save-restore="no"/>
+ <reg name="usp" bitsize="32" type="uint32"
+ group="qemu-debug" save-restore="no"/>
+ <reg name="isp" bitsize="32" type="uint32"
+ group="qemu-debug" save-restore="no"/>
+ <reg name="sfc" bitsize="32" type="uint32"
+ group="qemu-debug" save-restore="no"/>
+ <reg name="dfc" bitsize="32" type="uint32"
+ group="qemu-debug" save-restore="no"/>
+ <reg name="urp" bitsize="32" type="uint32"
+ group="qemu-debug" save-restore="no"/>
+ <reg name="srp" bitsize="32" type="uint32"
+ group="qemu-debug" save-restore="no"/>
+ <reg name="dttr0" bitsize="32" type="uint32"
+ group="qemu-debug" save-restore="no"/>
+ <reg name="dttr1" bitsize="32" type="uint32"
+ group="qemu-debug" save-restore="no"/>
+ <reg name="ittr0" bitsize="32" type="uint32"
+ group="qemu-debug" save-restore="no"/>
+ <reg name="ittr1" bitsize="32" type="uint32"
+ group="qemu-debug" save-restore="no"/>
+ <reg name="mmusr" bitsize="32" type="uint32"
+ group="qemu-debug" save-restore="no"/>
+</feature>
diff --git a/target/m68k/helper.c b/target/m68k/helper.c
index 5f91d206f596..f2615d5bcfb8 100644
--- a/target/m68k/helper.c
+++ b/target/m68k/helper.c
@@ -123,6 +123,48 @@ static int m68k_fpu_gdb_set_reg(CPUState *cs, uint8_t *mem_buf, int n)
return 0;
}
+#ifndef CONFIG_USER_ONLY
+static int m68k_gdb_read_system_register(CPUState *cs, GByteArray *buf, int n)
+{
+ CPUM68KState *env = cpu_env(cs);
+ static const int stacks[] = { M68K_SSP, M68K_USP, M68K_ISP };
+
+ if (n >= 0 && n < ARRAY_SIZE(stacks)) {
+ int sp = stacks[n];
+
+ return gdb_get_reg32(buf, env->sp[sp]);
+ }
+ switch (n) {
+ case 3:
+ return gdb_get_reg32(buf, env->sfc);
+ case 4:
+ return gdb_get_reg32(buf, env->dfc);
+ case 5:
+ return gdb_get_reg32(buf, env->mmu.urp);
+ case 6:
+ return gdb_get_reg32(buf, env->mmu.srp);
+ case 7:
+ return gdb_get_reg32(buf, env->mmu.ttr[M68K_DTTR0]);
+ case 8:
+ return gdb_get_reg32(buf, env->mmu.ttr[M68K_DTTR1]);
+ case 9:
+ return gdb_get_reg32(buf, env->mmu.ttr[M68K_ITTR0]);
+ case 10:
+ return gdb_get_reg32(buf, env->mmu.ttr[M68K_ITTR1]);
+ case 11:
+ return gdb_get_reg32(buf, env->mmu.mmusr);
+ default:
+ return 0;
+ }
+}
+
+static int m68k_gdb_write_system_register(CPUState *cs, uint8_t *buf, int n)
+{
+ /* These registers are exposed for inspection only. Ignore writes. */
+ return 4;
+}
+#endif
+
void m68k_cpu_init_gdb(M68kCPU *cpu)
{
CPUState *cs = CPU(cpu);
@@ -135,6 +177,11 @@ void m68k_cpu_init_gdb(M68kCPU *cpu)
gdb_register_coprocessor(cs, m68k_fpu_gdb_get_reg, m68k_fpu_gdb_set_reg,
gdb_find_static_feature("m68k-fp.xml"));
}
+#ifndef CONFIG_USER_ONLY
+ gdb_register_coprocessor(cs, m68k_gdb_read_system_register,
+ m68k_gdb_write_system_register,
+ gdb_find_static_feature("m68k-system.xml"));
+#endif
/* TODO: Add [E]MAC registers. */
}
--
2.55.0.543.g5ebe2ebe4ea8
^ permalink raw reply related [flat|nested] 12+ messages in thread
* [PATCH 07/10] target/sparc64: expose system registers via GDB
2026-09-11 12:27 [PATCH 00/10] monitor/hmp: replace MonitorDef with GDB registers Marc-André Lureau
` (5 preceding siblings ...)
2026-09-11 12:27 ` [PATCH 06/10] target/m68k: expose system registers via GDB Marc-André Lureau
@ 2026-09-11 12:27 ` Marc-André Lureau
2026-09-11 12:27 ` [PATCH 08/10] target/riscv: bypass smstateen check in debugger mode Marc-André Lureau
` (2 subsequent siblings)
9 siblings, 0 replies; 12+ messages in thread
From: Marc-André Lureau @ 2026-09-11 12:27 UTC (permalink / raw)
To: qemu-devel
Cc: Dr. David Alan Gilbert, Alex Bennée,
Philippe Mathieu-Daudé, Zhao Liu, Peter Maydell,
Chinmay Rath, Nicholas Piggin, Glenn Miles, Harsh Prateek Bora,
Palmer Dabbelt, Alistair Francis, Weiwei Li,
Daniel Henrique Barboza, Liu Zhiwei, Chao Liu, Max Filippov,
qemu-arm, qemu-ppc, qemu-riscv, Paolo Bonzini, Laurent Vivier,
Mark Cave-Ayland, Artyom Tarasenko, Helge Deller,
Pierrick Bouvier, Warner Losh, Kyle Evans, Marc-André Lureau
Add a sparc64-system.xml GDB feature that exposes asi, pstate,
cansave, canrestore, otherwin, wstate, and cleanwin as read-only
system registers through the GDB coprocessor interface.
Signed-off-by: Marc-André Lureau <marcandre.lureau@redhat.com>
---
configs/targets/sparc64-softmmu.mak | 2 +-
gdbstub/gdb-xml/sparc64-system.xml | 22 +++++++++++++++++++++
target/sparc/gdbstub.c | 38 +++++++++++++++++++++++++++++++++++++
3 files changed, 61 insertions(+), 1 deletion(-)
diff --git a/configs/targets/sparc64-softmmu.mak b/configs/targets/sparc64-softmmu.mak
index 4e621fb8e39e..7f2789136653 100644
--- a/configs/targets/sparc64-softmmu.mak
+++ b/configs/targets/sparc64-softmmu.mak
@@ -1,7 +1,7 @@
TARGET_ARCH=sparc64
TARGET_BASE_ARCH=sparc
TARGET_BIG_ENDIAN=y
-TARGET_XML_FILES=sparc64-cpu.xml sparc64-fpu.xml sparc64-cp0.xml
+TARGET_XML_FILES=sparc64-cpu.xml sparc64-fpu.xml sparc64-cp0.xml sparc64-system.xml
TARGET_LONG_BITS=64
TARGET_NOT_USING_LEGACY_LDST_PHYS_API=y
TARGET_NOT_USING_LEGACY_NATIVE_ENDIAN_API=y
diff --git a/gdbstub/gdb-xml/sparc64-system.xml b/gdbstub/gdb-xml/sparc64-system.xml
new file mode 100644
index 000000000000..e00baedb467e
--- /dev/null
+++ b/gdbstub/gdb-xml/sparc64-system.xml
@@ -0,0 +1,22 @@
+<?xml version="1.0"?>
+<!--
+ SPDX-License-Identifier: GPL-2.0-or-later
+-->
+<!DOCTYPE feature SYSTEM "gdb-target.dtd">
+<!-- System-register values are read-only; writes are ignored. -->
+<feature name="org.qemu.gdb.sparc.system">
+ <reg name="asi" bitsize="32" type="uint32"
+ group="qemu-debug" save-restore="no"/>
+ <reg name="pstate" bitsize="32" type="uint32"
+ group="qemu-debug" save-restore="no"/>
+ <reg name="cansave" bitsize="32" type="uint32"
+ group="qemu-debug" save-restore="no"/>
+ <reg name="canrestore" bitsize="32" type="uint32"
+ group="qemu-debug" save-restore="no"/>
+ <reg name="otherwin" bitsize="32" type="uint32"
+ group="qemu-debug" save-restore="no"/>
+ <reg name="wstate" bitsize="32" type="uint32"
+ group="qemu-debug" save-restore="no"/>
+ <reg name="cleanwin" bitsize="32" type="uint32"
+ group="qemu-debug" save-restore="no"/>
+</feature>
diff --git a/target/sparc/gdbstub.c b/target/sparc/gdbstub.c
index 2874ce1b3501..ca23a4a94532 100644
--- a/target/sparc/gdbstub.c
+++ b/target/sparc/gdbstub.c
@@ -266,6 +266,39 @@ static int sparc_cp0_gdb_write_register(CPUState *cs, uint8_t *mem_buf, int n)
#endif
}
+#if defined(TARGET_SPARC64) && !defined(CONFIG_USER_ONLY)
+static int sparc64_gdb_read_system_register(CPUState *cs, GByteArray *buf,
+ int n)
+{
+ CPUSPARCState *env = cpu_env(cs);
+
+ switch (n) {
+ case 0:
+ return gdb_get_reg32(buf, env->asi);
+ case 1:
+ return gdb_get_reg32(buf, env->pstate);
+ case 2:
+ return gdb_get_reg32(buf, env->cansave);
+ case 3:
+ return gdb_get_reg32(buf, env->canrestore);
+ case 4:
+ return gdb_get_reg32(buf, env->otherwin);
+ case 5:
+ return gdb_get_reg32(buf, env->wstate);
+ case 6:
+ return gdb_get_reg32(buf, env->cleanwin);
+ default:
+ return 0;
+ }
+}
+
+static int sparc64_gdb_write_system_register(CPUState *cs, uint8_t *buf, int n)
+{
+ /* These registers are exposed for inspection only. Ignore writes. */
+ return 4;
+}
+#endif
+
void sparc_cpu_register_gdb_regs(CPUState *cs)
{
#if defined(TARGET_ABI32) || !defined(TARGET_SPARC64)
@@ -282,5 +315,10 @@ void sparc_cpu_register_gdb_regs(CPUState *cs)
gdb_register_coprocessor(cs, sparc_cp0_gdb_read_register,
sparc_cp0_gdb_write_register,
gdb_find_static_feature("sparc64-cp0.xml"));
+#ifndef CONFIG_USER_ONLY
+ gdb_register_coprocessor(cs, sparc64_gdb_read_system_register,
+ sparc64_gdb_write_system_register,
+ gdb_find_static_feature("sparc64-system.xml"));
+#endif
#endif
}
--
2.55.0.543.g5ebe2ebe4ea8
^ permalink raw reply related [flat|nested] 12+ messages in thread
* [PATCH 08/10] target/riscv: bypass smstateen check in debugger mode
2026-09-11 12:27 [PATCH 00/10] monitor/hmp: replace MonitorDef with GDB registers Marc-André Lureau
` (6 preceding siblings ...)
2026-09-11 12:27 ` [PATCH 07/10] target/sparc64: " Marc-André Lureau
@ 2026-09-11 12:27 ` Marc-André Lureau
2026-09-11 12:27 ` [PATCH 09/10] target/riscv: expose register aliases via GDB Marc-André Lureau
2026-09-11 12:27 ` [PATCH 10/10] monitor/hmp: remove legacy MonitorDef infrastructure Marc-André Lureau
9 siblings, 0 replies; 12+ messages in thread
From: Marc-André Lureau @ 2026-09-11 12:27 UTC (permalink / raw)
To: qemu-devel
Cc: Dr. David Alan Gilbert, Alex Bennée,
Philippe Mathieu-Daudé, Zhao Liu, Peter Maydell,
Chinmay Rath, Nicholas Piggin, Glenn Miles, Harsh Prateek Bora,
Palmer Dabbelt, Alistair Francis, Weiwei Li,
Daniel Henrique Barboza, Liu Zhiwei, Chao Liu, Max Filippov,
qemu-arm, qemu-ppc, qemu-riscv, Paolo Bonzini, Laurent Vivier,
Mark Cave-Ayland, Artyom Tarasenko, Helge Deller,
Pierrick Bouvier, Warner Losh, Kyle Evans, Marc-André Lureau
Allow to read CSRs gated by Smstateen extension when env->debugger.
Signed-off-by: Marc-André Lureau <marcandre.lureau@redhat.com>
---
target/riscv/tcg/csr.c | 3 ++-
1 file changed, 2 insertions(+), 1 deletion(-)
diff --git a/target/riscv/tcg/csr.c b/target/riscv/tcg/csr.c
index bd4b6dc114bc..93a7f419f29f 100644
--- a/target/riscv/tcg/csr.c
+++ b/target/riscv/tcg/csr.c
@@ -53,7 +53,8 @@ RISCVException smstateen_acc_ok(CPURISCVState *env, int index, uint64_t bit)
{
bool virt = env->virt_enabled;
- if (env->priv == PRV_M || !riscv_cpu_cfg(env)->ext_smstateen) {
+ if (env->debugger || env->priv == PRV_M ||
+ !riscv_cpu_cfg(env)->ext_smstateen) {
return RISCV_EXCP_NONE;
}
--
2.55.0.543.g5ebe2ebe4ea8
^ permalink raw reply related [flat|nested] 12+ messages in thread
* [PATCH 09/10] target/riscv: expose register aliases via GDB
2026-09-11 12:27 [PATCH 00/10] monitor/hmp: replace MonitorDef with GDB registers Marc-André Lureau
` (7 preceding siblings ...)
2026-09-11 12:27 ` [PATCH 08/10] target/riscv: bypass smstateen check in debugger mode Marc-André Lureau
@ 2026-09-11 12:27 ` Marc-André Lureau
2026-09-11 12:27 ` [PATCH 10/10] monitor/hmp: remove legacy MonitorDef infrastructure Marc-André Lureau
9 siblings, 0 replies; 12+ messages in thread
From: Marc-André Lureau @ 2026-09-11 12:27 UTC (permalink / raw)
To: qemu-devel
Cc: Dr. David Alan Gilbert, Alex Bennée,
Philippe Mathieu-Daudé, Zhao Liu, Peter Maydell,
Chinmay Rath, Nicholas Piggin, Glenn Miles, Harsh Prateek Bora,
Palmer Dabbelt, Alistair Francis, Weiwei Li,
Daniel Henrique Barboza, Liu Zhiwei, Chao Liu, Max Filippov,
qemu-arm, qemu-ppc, qemu-riscv, Paolo Bonzini, Laurent Vivier,
Mark Cave-Ayland, Artyom Tarasenko, Helge Deller,
Pierrick Bouvier, Warner Losh, Kyle Evans, Marc-André Lureau
The core GDB XML uses ABI names (zero, ra, sp, fp, ft0, fs0, etc.)
but users also refer to registers by their numeric names (x0-x31,
f0-f31) and the s0 alias for fp. The legacy MonitorDef mechanism
supported both via split "x0/zero" name matching.
Register a feature that maps:
- x0-x31 and s0 to the corresponding core integer registers
- x0h-x31h and their ABI aliases (zeroh, rah, ...) to env->gprh[]
- f0-f31 to the corresponding FPU registers (when FPU is present)
This preserves full HMP $register compatibility after the MonitorDef
removal.
Signed-off-by: Marc-André Lureau <marcandre.lureau@redhat.com>
---
configs/targets/riscv32-linux-user.mak | 2 +-
configs/targets/riscv32-softmmu.mak | 2 +-
configs/targets/riscv64-bsd-user.mak | 2 +-
configs/targets/riscv64-linux-user.mak | 2 +-
configs/targets/riscv64-softmmu.mak | 2 +-
gdbstub/gdb-xml/riscv-32bit-alias.xml | 105 ++++++++++++++++++++++++++++++
gdbstub/gdb-xml/riscv-32bit-fpu-alias.xml | 40 ++++++++++++
gdbstub/gdb-xml/riscv-64bit-alias.xml | 105 ++++++++++++++++++++++++++++++
gdbstub/gdb-xml/riscv-64bit-fpu-alias.xml | 46 +++++++++++++
target/riscv/gdbstub.c | 43 ++++++++++++
10 files changed, 344 insertions(+), 5 deletions(-)
diff --git a/configs/targets/riscv32-linux-user.mak b/configs/targets/riscv32-linux-user.mak
index d88fdf5e1b2f..8ee14fa14383 100644
--- a/configs/targets/riscv32-linux-user.mak
+++ b/configs/targets/riscv32-linux-user.mak
@@ -1,7 +1,7 @@
TARGET_ARCH=riscv32
TARGET_BASE_ARCH=riscv
TARGET_ABI_DIR=riscv
-TARGET_XML_FILES= riscv-32bit-cpu.xml riscv-32bit-fpu.xml riscv-64bit-fpu.xml riscv-32bit-virtual.xml
+TARGET_XML_FILES= riscv-32bit-cpu.xml riscv-32bit-fpu.xml riscv-64bit-fpu.xml riscv-32bit-virtual.xml riscv-32bit-alias.xml riscv-32bit-fpu-alias.xml riscv-64bit-fpu-alias.xml
CONFIG_SEMIHOSTING=y
CONFIG_ARM_COMPATIBLE_SEMIHOSTING=y
TARGET_SYSTBL_ABI=32
diff --git a/configs/targets/riscv32-softmmu.mak b/configs/targets/riscv32-softmmu.mak
index 5d5016d00832..c717940344f0 100644
--- a/configs/targets/riscv32-softmmu.mak
+++ b/configs/targets/riscv32-softmmu.mak
@@ -1,6 +1,6 @@
TARGET_ARCH=riscv32
TARGET_BASE_ARCH=riscv
-TARGET_XML_FILES= riscv-32bit-cpu.xml riscv-32bit-fpu.xml riscv-64bit-fpu.xml riscv-32bit-virtual.xml
+TARGET_XML_FILES= riscv-32bit-cpu.xml riscv-32bit-fpu.xml riscv-64bit-fpu.xml riscv-32bit-virtual.xml riscv-32bit-alias.xml riscv-32bit-fpu-alias.xml riscv-64bit-fpu-alias.xml
# needed by boot.c
TARGET_NEED_FDT=y
TARGET_LONG_BITS=32
diff --git a/configs/targets/riscv64-bsd-user.mak b/configs/targets/riscv64-bsd-user.mak
index 5b4e138099fc..1d37e018c871 100644
--- a/configs/targets/riscv64-bsd-user.mak
+++ b/configs/targets/riscv64-bsd-user.mak
@@ -1,6 +1,6 @@
TARGET_ARCH=riscv64
TARGET_BASE_ARCH=riscv
TARGET_ABI_DIR=riscv
-TARGET_XML_FILES= riscv-64bit-cpu.xml riscv-32bit-fpu.xml riscv-64bit-fpu.xml riscv-64bit-virtual.xml
+TARGET_XML_FILES= riscv-64bit-cpu.xml riscv-32bit-fpu.xml riscv-64bit-fpu.xml riscv-64bit-virtual.xml riscv-64bit-alias.xml riscv-32bit-fpu-alias.xml riscv-64bit-fpu-alias.xml
TARGET_LONG_BITS=64
TARGET_NOT_USING_LEGACY_NATIVE_ENDIAN_API=y
diff --git a/configs/targets/riscv64-linux-user.mak b/configs/targets/riscv64-linux-user.mak
index 35621520c560..564d15aaca8c 100644
--- a/configs/targets/riscv64-linux-user.mak
+++ b/configs/targets/riscv64-linux-user.mak
@@ -1,7 +1,7 @@
TARGET_ARCH=riscv64
TARGET_BASE_ARCH=riscv
TARGET_ABI_DIR=riscv
-TARGET_XML_FILES= riscv-64bit-cpu.xml riscv-32bit-fpu.xml riscv-64bit-fpu.xml riscv-64bit-virtual.xml
+TARGET_XML_FILES= riscv-64bit-cpu.xml riscv-32bit-fpu.xml riscv-64bit-fpu.xml riscv-64bit-virtual.xml riscv-64bit-alias.xml riscv-32bit-fpu-alias.xml riscv-64bit-fpu-alias.xml
CONFIG_SEMIHOSTING=y
CONFIG_ARM_COMPATIBLE_SEMIHOSTING=y
TARGET_SYSTBL_ABI=64
diff --git a/configs/targets/riscv64-softmmu.mak b/configs/targets/riscv64-softmmu.mak
index a10dc03c04c8..28bfcdc575fb 100644
--- a/configs/targets/riscv64-softmmu.mak
+++ b/configs/targets/riscv64-softmmu.mak
@@ -1,7 +1,7 @@
TARGET_ARCH=riscv64
TARGET_BASE_ARCH=riscv
TARGET_KVM_HAVE_GUEST_DEBUG=y
-TARGET_XML_FILES= riscv-64bit-cpu.xml riscv-32bit-fpu.xml riscv-64bit-fpu.xml riscv-64bit-virtual.xml riscv-32bit-cpu.xml riscv-32bit-virtual.xml
+TARGET_XML_FILES= riscv-64bit-cpu.xml riscv-32bit-fpu.xml riscv-64bit-fpu.xml riscv-64bit-virtual.xml riscv-32bit-cpu.xml riscv-32bit-virtual.xml riscv-32bit-alias.xml riscv-64bit-alias.xml riscv-32bit-fpu-alias.xml riscv-64bit-fpu-alias.xml
# needed by boot.c
TARGET_NEED_FDT=y
TARGET_LONG_BITS=64
diff --git a/gdbstub/gdb-xml/riscv-32bit-alias.xml b/gdbstub/gdb-xml/riscv-32bit-alias.xml
new file mode 100644
index 000000000000..a00a86ebdf95
--- /dev/null
+++ b/gdbstub/gdb-xml/riscv-32bit-alias.xml
@@ -0,0 +1,105 @@
+<?xml version="1.0"?>
+<!--
+ SPDX-License-Identifier: GPL-2.0-or-later
+-->
+
+<!DOCTYPE feature SYSTEM "gdb-target.dtd">
+<feature name="org.qemu.gdb.riscv.alias">
+ <reg name="x0" bitsize="32" type="int" group="qemu-debug"/>
+ <reg name="x1" bitsize="32" type="int" group="qemu-debug"/>
+ <reg name="x2" bitsize="32" type="int" group="qemu-debug"/>
+ <reg name="x3" bitsize="32" type="int" group="qemu-debug"/>
+ <reg name="x4" bitsize="32" type="int" group="qemu-debug"/>
+ <reg name="x5" bitsize="32" type="int" group="qemu-debug"/>
+ <reg name="x6" bitsize="32" type="int" group="qemu-debug"/>
+ <reg name="x7" bitsize="32" type="int" group="qemu-debug"/>
+ <reg name="x8" bitsize="32" type="int" group="qemu-debug"/>
+ <reg name="x9" bitsize="32" type="int" group="qemu-debug"/>
+ <reg name="x10" bitsize="32" type="int" group="qemu-debug"/>
+ <reg name="x11" bitsize="32" type="int" group="qemu-debug"/>
+ <reg name="x12" bitsize="32" type="int" group="qemu-debug"/>
+ <reg name="x13" bitsize="32" type="int" group="qemu-debug"/>
+ <reg name="x14" bitsize="32" type="int" group="qemu-debug"/>
+ <reg name="x15" bitsize="32" type="int" group="qemu-debug"/>
+ <reg name="x16" bitsize="32" type="int" group="qemu-debug"/>
+ <reg name="x17" bitsize="32" type="int" group="qemu-debug"/>
+ <reg name="x18" bitsize="32" type="int" group="qemu-debug"/>
+ <reg name="x19" bitsize="32" type="int" group="qemu-debug"/>
+ <reg name="x20" bitsize="32" type="int" group="qemu-debug"/>
+ <reg name="x21" bitsize="32" type="int" group="qemu-debug"/>
+ <reg name="x22" bitsize="32" type="int" group="qemu-debug"/>
+ <reg name="x23" bitsize="32" type="int" group="qemu-debug"/>
+ <reg name="x24" bitsize="32" type="int" group="qemu-debug"/>
+ <reg name="x25" bitsize="32" type="int" group="qemu-debug"/>
+ <reg name="x26" bitsize="32" type="int" group="qemu-debug"/>
+ <reg name="x27" bitsize="32" type="int" group="qemu-debug"/>
+ <reg name="x28" bitsize="32" type="int" group="qemu-debug"/>
+ <reg name="x29" bitsize="32" type="int" group="qemu-debug"/>
+ <reg name="x30" bitsize="32" type="int" group="qemu-debug"/>
+ <reg name="x31" bitsize="32" type="int" group="qemu-debug"/>
+ <reg name="s0" bitsize="32" type="int" group="qemu-debug"/>
+ <reg name="x0h" bitsize="32" type="int" group="qemu-debug"/>
+ <reg name="zeroh" bitsize="32" type="int" group="qemu-debug"/>
+ <reg name="x1h" bitsize="32" type="int" group="qemu-debug"/>
+ <reg name="rah" bitsize="32" type="int" group="qemu-debug"/>
+ <reg name="x2h" bitsize="32" type="int" group="qemu-debug"/>
+ <reg name="sph" bitsize="32" type="int" group="qemu-debug"/>
+ <reg name="x3h" bitsize="32" type="int" group="qemu-debug"/>
+ <reg name="gph" bitsize="32" type="int" group="qemu-debug"/>
+ <reg name="x4h" bitsize="32" type="int" group="qemu-debug"/>
+ <reg name="tph" bitsize="32" type="int" group="qemu-debug"/>
+ <reg name="x5h" bitsize="32" type="int" group="qemu-debug"/>
+ <reg name="t0h" bitsize="32" type="int" group="qemu-debug"/>
+ <reg name="x6h" bitsize="32" type="int" group="qemu-debug"/>
+ <reg name="t1h" bitsize="32" type="int" group="qemu-debug"/>
+ <reg name="x7h" bitsize="32" type="int" group="qemu-debug"/>
+ <reg name="t2h" bitsize="32" type="int" group="qemu-debug"/>
+ <reg name="x8h" bitsize="32" type="int" group="qemu-debug"/>
+ <reg name="s0h" bitsize="32" type="int" group="qemu-debug"/>
+ <reg name="x9h" bitsize="32" type="int" group="qemu-debug"/>
+ <reg name="s1h" bitsize="32" type="int" group="qemu-debug"/>
+ <reg name="x10h" bitsize="32" type="int" group="qemu-debug"/>
+ <reg name="a0h" bitsize="32" type="int" group="qemu-debug"/>
+ <reg name="x11h" bitsize="32" type="int" group="qemu-debug"/>
+ <reg name="a1h" bitsize="32" type="int" group="qemu-debug"/>
+ <reg name="x12h" bitsize="32" type="int" group="qemu-debug"/>
+ <reg name="a2h" bitsize="32" type="int" group="qemu-debug"/>
+ <reg name="x13h" bitsize="32" type="int" group="qemu-debug"/>
+ <reg name="a3h" bitsize="32" type="int" group="qemu-debug"/>
+ <reg name="x14h" bitsize="32" type="int" group="qemu-debug"/>
+ <reg name="a4h" bitsize="32" type="int" group="qemu-debug"/>
+ <reg name="x15h" bitsize="32" type="int" group="qemu-debug"/>
+ <reg name="a5h" bitsize="32" type="int" group="qemu-debug"/>
+ <reg name="x16h" bitsize="32" type="int" group="qemu-debug"/>
+ <reg name="a6h" bitsize="32" type="int" group="qemu-debug"/>
+ <reg name="x17h" bitsize="32" type="int" group="qemu-debug"/>
+ <reg name="a7h" bitsize="32" type="int" group="qemu-debug"/>
+ <reg name="x18h" bitsize="32" type="int" group="qemu-debug"/>
+ <reg name="s2h" bitsize="32" type="int" group="qemu-debug"/>
+ <reg name="x19h" bitsize="32" type="int" group="qemu-debug"/>
+ <reg name="s3h" bitsize="32" type="int" group="qemu-debug"/>
+ <reg name="x20h" bitsize="32" type="int" group="qemu-debug"/>
+ <reg name="s4h" bitsize="32" type="int" group="qemu-debug"/>
+ <reg name="x21h" bitsize="32" type="int" group="qemu-debug"/>
+ <reg name="s5h" bitsize="32" type="int" group="qemu-debug"/>
+ <reg name="x22h" bitsize="32" type="int" group="qemu-debug"/>
+ <reg name="s6h" bitsize="32" type="int" group="qemu-debug"/>
+ <reg name="x23h" bitsize="32" type="int" group="qemu-debug"/>
+ <reg name="s7h" bitsize="32" type="int" group="qemu-debug"/>
+ <reg name="x24h" bitsize="32" type="int" group="qemu-debug"/>
+ <reg name="s8h" bitsize="32" type="int" group="qemu-debug"/>
+ <reg name="x25h" bitsize="32" type="int" group="qemu-debug"/>
+ <reg name="s9h" bitsize="32" type="int" group="qemu-debug"/>
+ <reg name="x26h" bitsize="32" type="int" group="qemu-debug"/>
+ <reg name="s10h" bitsize="32" type="int" group="qemu-debug"/>
+ <reg name="x27h" bitsize="32" type="int" group="qemu-debug"/>
+ <reg name="s11h" bitsize="32" type="int" group="qemu-debug"/>
+ <reg name="x28h" bitsize="32" type="int" group="qemu-debug"/>
+ <reg name="t3h" bitsize="32" type="int" group="qemu-debug"/>
+ <reg name="x29h" bitsize="32" type="int" group="qemu-debug"/>
+ <reg name="t4h" bitsize="32" type="int" group="qemu-debug"/>
+ <reg name="x30h" bitsize="32" type="int" group="qemu-debug"/>
+ <reg name="t5h" bitsize="32" type="int" group="qemu-debug"/>
+ <reg name="x31h" bitsize="32" type="int" group="qemu-debug"/>
+ <reg name="t6h" bitsize="32" type="int" group="qemu-debug"/>
+</feature>
diff --git a/gdbstub/gdb-xml/riscv-32bit-fpu-alias.xml b/gdbstub/gdb-xml/riscv-32bit-fpu-alias.xml
new file mode 100644
index 000000000000..3935f72ea289
--- /dev/null
+++ b/gdbstub/gdb-xml/riscv-32bit-fpu-alias.xml
@@ -0,0 +1,40 @@
+<?xml version="1.0"?>
+<!--
+ SPDX-License-Identifier: GPL-2.0-or-later
+-->
+
+<!DOCTYPE feature SYSTEM "gdb-target.dtd">
+<feature name="org.qemu.gdb.riscv.fpu-alias">
+ <reg name="f0" bitsize="32" type="ieee_single" group="qemu-debug"/>
+ <reg name="f1" bitsize="32" type="ieee_single" group="qemu-debug"/>
+ <reg name="f2" bitsize="32" type="ieee_single" group="qemu-debug"/>
+ <reg name="f3" bitsize="32" type="ieee_single" group="qemu-debug"/>
+ <reg name="f4" bitsize="32" type="ieee_single" group="qemu-debug"/>
+ <reg name="f5" bitsize="32" type="ieee_single" group="qemu-debug"/>
+ <reg name="f6" bitsize="32" type="ieee_single" group="qemu-debug"/>
+ <reg name="f7" bitsize="32" type="ieee_single" group="qemu-debug"/>
+ <reg name="f8" bitsize="32" type="ieee_single" group="qemu-debug"/>
+ <reg name="f9" bitsize="32" type="ieee_single" group="qemu-debug"/>
+ <reg name="f10" bitsize="32" type="ieee_single" group="qemu-debug"/>
+ <reg name="f11" bitsize="32" type="ieee_single" group="qemu-debug"/>
+ <reg name="f12" bitsize="32" type="ieee_single" group="qemu-debug"/>
+ <reg name="f13" bitsize="32" type="ieee_single" group="qemu-debug"/>
+ <reg name="f14" bitsize="32" type="ieee_single" group="qemu-debug"/>
+ <reg name="f15" bitsize="32" type="ieee_single" group="qemu-debug"/>
+ <reg name="f16" bitsize="32" type="ieee_single" group="qemu-debug"/>
+ <reg name="f17" bitsize="32" type="ieee_single" group="qemu-debug"/>
+ <reg name="f18" bitsize="32" type="ieee_single" group="qemu-debug"/>
+ <reg name="f19" bitsize="32" type="ieee_single" group="qemu-debug"/>
+ <reg name="f20" bitsize="32" type="ieee_single" group="qemu-debug"/>
+ <reg name="f21" bitsize="32" type="ieee_single" group="qemu-debug"/>
+ <reg name="f22" bitsize="32" type="ieee_single" group="qemu-debug"/>
+ <reg name="f23" bitsize="32" type="ieee_single" group="qemu-debug"/>
+ <reg name="f24" bitsize="32" type="ieee_single" group="qemu-debug"/>
+ <reg name="f25" bitsize="32" type="ieee_single" group="qemu-debug"/>
+ <reg name="f26" bitsize="32" type="ieee_single" group="qemu-debug"/>
+ <reg name="f27" bitsize="32" type="ieee_single" group="qemu-debug"/>
+ <reg name="f28" bitsize="32" type="ieee_single" group="qemu-debug"/>
+ <reg name="f29" bitsize="32" type="ieee_single" group="qemu-debug"/>
+ <reg name="f30" bitsize="32" type="ieee_single" group="qemu-debug"/>
+ <reg name="f31" bitsize="32" type="ieee_single" group="qemu-debug"/>
+</feature>
diff --git a/gdbstub/gdb-xml/riscv-64bit-alias.xml b/gdbstub/gdb-xml/riscv-64bit-alias.xml
new file mode 100644
index 000000000000..28781b230226
--- /dev/null
+++ b/gdbstub/gdb-xml/riscv-64bit-alias.xml
@@ -0,0 +1,105 @@
+<?xml version="1.0"?>
+<!--
+ SPDX-License-Identifier: GPL-2.0-or-later
+-->
+
+<!DOCTYPE feature SYSTEM "gdb-target.dtd">
+<feature name="org.qemu.gdb.riscv.alias">
+ <reg name="x0" bitsize="64" type="int" group="qemu-debug"/>
+ <reg name="x1" bitsize="64" type="int" group="qemu-debug"/>
+ <reg name="x2" bitsize="64" type="int" group="qemu-debug"/>
+ <reg name="x3" bitsize="64" type="int" group="qemu-debug"/>
+ <reg name="x4" bitsize="64" type="int" group="qemu-debug"/>
+ <reg name="x5" bitsize="64" type="int" group="qemu-debug"/>
+ <reg name="x6" bitsize="64" type="int" group="qemu-debug"/>
+ <reg name="x7" bitsize="64" type="int" group="qemu-debug"/>
+ <reg name="x8" bitsize="64" type="int" group="qemu-debug"/>
+ <reg name="x9" bitsize="64" type="int" group="qemu-debug"/>
+ <reg name="x10" bitsize="64" type="int" group="qemu-debug"/>
+ <reg name="x11" bitsize="64" type="int" group="qemu-debug"/>
+ <reg name="x12" bitsize="64" type="int" group="qemu-debug"/>
+ <reg name="x13" bitsize="64" type="int" group="qemu-debug"/>
+ <reg name="x14" bitsize="64" type="int" group="qemu-debug"/>
+ <reg name="x15" bitsize="64" type="int" group="qemu-debug"/>
+ <reg name="x16" bitsize="64" type="int" group="qemu-debug"/>
+ <reg name="x17" bitsize="64" type="int" group="qemu-debug"/>
+ <reg name="x18" bitsize="64" type="int" group="qemu-debug"/>
+ <reg name="x19" bitsize="64" type="int" group="qemu-debug"/>
+ <reg name="x20" bitsize="64" type="int" group="qemu-debug"/>
+ <reg name="x21" bitsize="64" type="int" group="qemu-debug"/>
+ <reg name="x22" bitsize="64" type="int" group="qemu-debug"/>
+ <reg name="x23" bitsize="64" type="int" group="qemu-debug"/>
+ <reg name="x24" bitsize="64" type="int" group="qemu-debug"/>
+ <reg name="x25" bitsize="64" type="int" group="qemu-debug"/>
+ <reg name="x26" bitsize="64" type="int" group="qemu-debug"/>
+ <reg name="x27" bitsize="64" type="int" group="qemu-debug"/>
+ <reg name="x28" bitsize="64" type="int" group="qemu-debug"/>
+ <reg name="x29" bitsize="64" type="int" group="qemu-debug"/>
+ <reg name="x30" bitsize="64" type="int" group="qemu-debug"/>
+ <reg name="x31" bitsize="64" type="int" group="qemu-debug"/>
+ <reg name="s0" bitsize="64" type="int" group="qemu-debug"/>
+ <reg name="x0h" bitsize="64" type="int" group="qemu-debug"/>
+ <reg name="zeroh" bitsize="64" type="int" group="qemu-debug"/>
+ <reg name="x1h" bitsize="64" type="int" group="qemu-debug"/>
+ <reg name="rah" bitsize="64" type="int" group="qemu-debug"/>
+ <reg name="x2h" bitsize="64" type="int" group="qemu-debug"/>
+ <reg name="sph" bitsize="64" type="int" group="qemu-debug"/>
+ <reg name="x3h" bitsize="64" type="int" group="qemu-debug"/>
+ <reg name="gph" bitsize="64" type="int" group="qemu-debug"/>
+ <reg name="x4h" bitsize="64" type="int" group="qemu-debug"/>
+ <reg name="tph" bitsize="64" type="int" group="qemu-debug"/>
+ <reg name="x5h" bitsize="64" type="int" group="qemu-debug"/>
+ <reg name="t0h" bitsize="64" type="int" group="qemu-debug"/>
+ <reg name="x6h" bitsize="64" type="int" group="qemu-debug"/>
+ <reg name="t1h" bitsize="64" type="int" group="qemu-debug"/>
+ <reg name="x7h" bitsize="64" type="int" group="qemu-debug"/>
+ <reg name="t2h" bitsize="64" type="int" group="qemu-debug"/>
+ <reg name="x8h" bitsize="64" type="int" group="qemu-debug"/>
+ <reg name="s0h" bitsize="64" type="int" group="qemu-debug"/>
+ <reg name="x9h" bitsize="64" type="int" group="qemu-debug"/>
+ <reg name="s1h" bitsize="64" type="int" group="qemu-debug"/>
+ <reg name="x10h" bitsize="64" type="int" group="qemu-debug"/>
+ <reg name="a0h" bitsize="64" type="int" group="qemu-debug"/>
+ <reg name="x11h" bitsize="64" type="int" group="qemu-debug"/>
+ <reg name="a1h" bitsize="64" type="int" group="qemu-debug"/>
+ <reg name="x12h" bitsize="64" type="int" group="qemu-debug"/>
+ <reg name="a2h" bitsize="64" type="int" group="qemu-debug"/>
+ <reg name="x13h" bitsize="64" type="int" group="qemu-debug"/>
+ <reg name="a3h" bitsize="64" type="int" group="qemu-debug"/>
+ <reg name="x14h" bitsize="64" type="int" group="qemu-debug"/>
+ <reg name="a4h" bitsize="64" type="int" group="qemu-debug"/>
+ <reg name="x15h" bitsize="64" type="int" group="qemu-debug"/>
+ <reg name="a5h" bitsize="64" type="int" group="qemu-debug"/>
+ <reg name="x16h" bitsize="64" type="int" group="qemu-debug"/>
+ <reg name="a6h" bitsize="64" type="int" group="qemu-debug"/>
+ <reg name="x17h" bitsize="64" type="int" group="qemu-debug"/>
+ <reg name="a7h" bitsize="64" type="int" group="qemu-debug"/>
+ <reg name="x18h" bitsize="64" type="int" group="qemu-debug"/>
+ <reg name="s2h" bitsize="64" type="int" group="qemu-debug"/>
+ <reg name="x19h" bitsize="64" type="int" group="qemu-debug"/>
+ <reg name="s3h" bitsize="64" type="int" group="qemu-debug"/>
+ <reg name="x20h" bitsize="64" type="int" group="qemu-debug"/>
+ <reg name="s4h" bitsize="64" type="int" group="qemu-debug"/>
+ <reg name="x21h" bitsize="64" type="int" group="qemu-debug"/>
+ <reg name="s5h" bitsize="64" type="int" group="qemu-debug"/>
+ <reg name="x22h" bitsize="64" type="int" group="qemu-debug"/>
+ <reg name="s6h" bitsize="64" type="int" group="qemu-debug"/>
+ <reg name="x23h" bitsize="64" type="int" group="qemu-debug"/>
+ <reg name="s7h" bitsize="64" type="int" group="qemu-debug"/>
+ <reg name="x24h" bitsize="64" type="int" group="qemu-debug"/>
+ <reg name="s8h" bitsize="64" type="int" group="qemu-debug"/>
+ <reg name="x25h" bitsize="64" type="int" group="qemu-debug"/>
+ <reg name="s9h" bitsize="64" type="int" group="qemu-debug"/>
+ <reg name="x26h" bitsize="64" type="int" group="qemu-debug"/>
+ <reg name="s10h" bitsize="64" type="int" group="qemu-debug"/>
+ <reg name="x27h" bitsize="64" type="int" group="qemu-debug"/>
+ <reg name="s11h" bitsize="64" type="int" group="qemu-debug"/>
+ <reg name="x28h" bitsize="64" type="int" group="qemu-debug"/>
+ <reg name="t3h" bitsize="64" type="int" group="qemu-debug"/>
+ <reg name="x29h" bitsize="64" type="int" group="qemu-debug"/>
+ <reg name="t4h" bitsize="64" type="int" group="qemu-debug"/>
+ <reg name="x30h" bitsize="64" type="int" group="qemu-debug"/>
+ <reg name="t5h" bitsize="64" type="int" group="qemu-debug"/>
+ <reg name="x31h" bitsize="64" type="int" group="qemu-debug"/>
+ <reg name="t6h" bitsize="64" type="int" group="qemu-debug"/>
+</feature>
diff --git a/gdbstub/gdb-xml/riscv-64bit-fpu-alias.xml b/gdbstub/gdb-xml/riscv-64bit-fpu-alias.xml
new file mode 100644
index 000000000000..13e6b341a0f8
--- /dev/null
+++ b/gdbstub/gdb-xml/riscv-64bit-fpu-alias.xml
@@ -0,0 +1,46 @@
+<?xml version="1.0"?>
+<!--
+ SPDX-License-Identifier: GPL-2.0-or-later
+-->
+
+<!DOCTYPE feature SYSTEM "gdb-target.dtd">
+<feature name="org.qemu.gdb.riscv.fpu-alias">
+
+ <union id="riscv_double">
+ <field name="float" type="ieee_single"/>
+ <field name="double" type="ieee_double"/>
+ </union>
+
+ <reg name="f0" bitsize="64" type="riscv_double" group="qemu-debug"/>
+ <reg name="f1" bitsize="64" type="riscv_double" group="qemu-debug"/>
+ <reg name="f2" bitsize="64" type="riscv_double" group="qemu-debug"/>
+ <reg name="f3" bitsize="64" type="riscv_double" group="qemu-debug"/>
+ <reg name="f4" bitsize="64" type="riscv_double" group="qemu-debug"/>
+ <reg name="f5" bitsize="64" type="riscv_double" group="qemu-debug"/>
+ <reg name="f6" bitsize="64" type="riscv_double" group="qemu-debug"/>
+ <reg name="f7" bitsize="64" type="riscv_double" group="qemu-debug"/>
+ <reg name="f8" bitsize="64" type="riscv_double" group="qemu-debug"/>
+ <reg name="f9" bitsize="64" type="riscv_double" group="qemu-debug"/>
+ <reg name="f10" bitsize="64" type="riscv_double" group="qemu-debug"/>
+ <reg name="f11" bitsize="64" type="riscv_double" group="qemu-debug"/>
+ <reg name="f12" bitsize="64" type="riscv_double" group="qemu-debug"/>
+ <reg name="f13" bitsize="64" type="riscv_double" group="qemu-debug"/>
+ <reg name="f14" bitsize="64" type="riscv_double" group="qemu-debug"/>
+ <reg name="f15" bitsize="64" type="riscv_double" group="qemu-debug"/>
+ <reg name="f16" bitsize="64" type="riscv_double" group="qemu-debug"/>
+ <reg name="f17" bitsize="64" type="riscv_double" group="qemu-debug"/>
+ <reg name="f18" bitsize="64" type="riscv_double" group="qemu-debug"/>
+ <reg name="f19" bitsize="64" type="riscv_double" group="qemu-debug"/>
+ <reg name="f20" bitsize="64" type="riscv_double" group="qemu-debug"/>
+ <reg name="f21" bitsize="64" type="riscv_double" group="qemu-debug"/>
+ <reg name="f22" bitsize="64" type="riscv_double" group="qemu-debug"/>
+ <reg name="f23" bitsize="64" type="riscv_double" group="qemu-debug"/>
+ <reg name="f24" bitsize="64" type="riscv_double" group="qemu-debug"/>
+ <reg name="f25" bitsize="64" type="riscv_double" group="qemu-debug"/>
+ <reg name="f26" bitsize="64" type="riscv_double" group="qemu-debug"/>
+ <reg name="f27" bitsize="64" type="riscv_double" group="qemu-debug"/>
+ <reg name="f28" bitsize="64" type="riscv_double" group="qemu-debug"/>
+ <reg name="f29" bitsize="64" type="riscv_double" group="qemu-debug"/>
+ <reg name="f30" bitsize="64" type="riscv_double" group="qemu-debug"/>
+ <reg name="f31" bitsize="64" type="riscv_double" group="qemu-debug"/>
+</feature>
diff --git a/target/riscv/gdbstub.c b/target/riscv/gdbstub.c
index f279f4ab2461..6694fa86fd84 100644
--- a/target/riscv/gdbstub.c
+++ b/target/riscv/gdbstub.c
@@ -336,16 +336,59 @@ static GDBFeature *ricsv_gen_dynamic_vector_feature(CPUState *cs, int base_reg)
return &cpu->dyn_vreg_feature;
}
+/* x0-x31, s0, then pairs of numeric and ABI high-half aliases. */
+static int riscv_gdb_get_alias(CPUState *cs, GByteArray *buf, int n)
+{
+ RISCVCPU *cpu = RISCV_CPU(cs);
+ uint64_t val;
+
+ if (n < 33) {
+ return riscv_cpu_gdb_read_register(cs, buf, n == 32 ? 8 : n);
+ }
+
+ val = cpu->env.gprh[(n - 33) / 2];
+ if (riscv_cpu_is_32bit(cpu)) {
+ return gdb_get_reg32(buf, val);
+ }
+ return gdb_get_reg64(buf, val);
+}
+
+static int riscv_gdb_set_alias(CPUState *cs, uint8_t *buf, int n)
+{
+ RISCVCPU *cpu = RISCV_CPU(cs);
+ CPURISCVState *env = &cpu->env;
+ const unsigned regsz = riscv_cpu_is_32bit(cpu) ? 4 : 8;
+
+ if (n < 33) {
+ return riscv_cpu_gdb_write_register(cs, buf, n == 32 ? 8 : n);
+ }
+
+ env->gprh[(n - 33) / 2] = ldn(env, buf, regsz);
+ return regsz;
+}
+
void riscv_cpu_register_gdb_regs_for_features(CPUState *cs)
{
RISCVCPU *cpu = RISCV_CPU(cs);
CPURISCVState *env = &cpu->env;
+
+ gdb_register_coprocessor(cs, riscv_gdb_get_alias, riscv_gdb_set_alias,
+ gdb_find_static_feature(riscv_cpu_is_32bit(cpu) ?
+ "riscv-32bit-alias.xml" :
+ "riscv-64bit-alias.xml"));
+
if (env->misa_ext & RVD) {
gdb_register_coprocessor(cs, riscv_gdb_get_fpu, riscv_gdb_set_fpu,
gdb_find_static_feature("riscv-64bit-fpu.xml"));
+ gdb_register_coprocessor(cs, riscv_gdb_get_fpu,
+ riscv_gdb_set_fpu,
+ gdb_find_static_feature("riscv-64bit-fpu-alias.xml"));
} else if (env->misa_ext & RVF) {
gdb_register_coprocessor(cs, riscv_gdb_get_fpu, riscv_gdb_set_fpu,
gdb_find_static_feature("riscv-32bit-fpu.xml"));
+ gdb_register_coprocessor(cs, riscv_gdb_get_fpu,
+ riscv_gdb_set_fpu,
+ gdb_find_static_feature("riscv-32bit-fpu-alias.xml"));
}
if (cpu->cfg.ext_zve32x) {
GDBFeature *feature =
--
2.55.0.543.g5ebe2ebe4ea8
^ permalink raw reply related [flat|nested] 12+ messages in thread
* [PATCH 10/10] monitor/hmp: remove legacy MonitorDef infrastructure
2026-09-11 12:27 [PATCH 00/10] monitor/hmp: replace MonitorDef with GDB registers Marc-André Lureau
` (8 preceding siblings ...)
2026-09-11 12:27 ` [PATCH 09/10] target/riscv: expose register aliases via GDB Marc-André Lureau
@ 2026-09-11 12:27 ` Marc-André Lureau
9 siblings, 0 replies; 12+ messages in thread
From: Marc-André Lureau @ 2026-09-11 12:27 UTC (permalink / raw)
To: qemu-devel
Cc: Dr. David Alan Gilbert, Alex Bennée,
Philippe Mathieu-Daudé, Zhao Liu, Peter Maydell,
Chinmay Rath, Nicholas Piggin, Glenn Miles, Harsh Prateek Bora,
Palmer Dabbelt, Alistair Francis, Weiwei Li,
Daniel Henrique Barboza, Liu Zhiwei, Chao Liu, Max Filippov,
qemu-arm, qemu-ppc, qemu-riscv, Paolo Bonzini, Laurent Vivier,
Mark Cave-Ayland, Artyom Tarasenko, Helge Deller,
Pierrick Bouvier, Warner Losh, Kyle Evans, Marc-André Lureau
Now that all targets expose their system registers via GDB register
descriptions (i386 segment limits, m68k, sparc64) and $pc is handled by
the CPUClass::get_pc fallback, the legacy MonitorDef table and
SysemuCPUOps::monitor_get_register callback are no longer needed.
Remove MonitorDef struct, the per-target monitor_defs arrays (i386,
m68k, sparc64), riscv_monitor_get_register_legacy(), and the
get_monitor_def() fallback in expr_unary(). HMP $register expressions
now use gdb_get_register_list() exclusively.
For RISC-V, the legacy callback provided case-insensitive register name
matching (e.g. $Mstatus) and a special message for vector
registers ("Unable to print the value of vector vreg"). The GDB-based
lookup is case-sensitive (consistent with all other targets) and reports
oversized registers as "unknown register" instead.
Signed-off-by: Marc-André Lureau <marcandre.lureau@redhat.com>
---
include/hw/core/sysemu-cpu-ops.h | 16 -----
include/monitor/hmp.h | 6 --
include/qemu/typedefs.h | 1 -
monitor/hmp.c | 44 +-----------
target/i386/cpu.c | 32 ---------
target/m68k/cpu.c | 22 ------
target/riscv/cpu.c | 1 -
target/riscv/internals.h | 3 -
target/riscv/monitor.c | 140 ---------------------------------------
target/sparc/cpu.c | 19 ------
10 files changed, 2 insertions(+), 282 deletions(-)
diff --git a/include/hw/core/sysemu-cpu-ops.h b/include/hw/core/sysemu-cpu-ops.h
index e56eea18b785..3a85aa47e243 100644
--- a/include/hw/core/sysemu-cpu-ops.h
+++ b/include/hw/core/sysemu-cpu-ops.h
@@ -101,22 +101,6 @@ typedef struct SysemuCPUOps {
*/
bool (*internal_is_big_endian)(CPUState *cpu);
- /**
- * @monitor_get_register: Callback to fill @pval with register @name value.
- * This field is legacy, use @gdb_core_xml_file
- * to dump registers instead.
- * Returns: 0 on success or negative errno on failure.
- */
- int (*monitor_get_register)(CPUState *cs, const char *name, int64_t *pval);
-
-#ifdef CONFIG_HMP
- /**
- * @monitor_defs: Array of MonitorDef entries. This field is legacy,
- * use @gdb_core_xml_file to dump registers instead.
- */
- const MonitorDef *monitor_defs;
-#endif
-
/**
* @legacy_vmsd: Legacy state for migration.
* Do not use in new targets, use #DeviceClass::vmsd instead.
diff --git a/include/monitor/hmp.h b/include/monitor/hmp.h
index ef53e87f7608..950dd931d452 100644
--- a/include/monitor/hmp.h
+++ b/include/monitor/hmp.h
@@ -31,12 +31,6 @@ MonitorHMP *monitor_cur_hmp(void);
g_assert_not_reached(); \
}
-struct MonitorDef {
- const char *name;
- int offset;
- int64_t (*get_value)(MonitorHMP *hmp, const MonitorDef *md, int offset);
-};
-
void monitor_new_hmp(const char *id, const char *chardev_id,
bool use_readline, Error **errp);
diff --git a/include/qemu/typedefs.h b/include/qemu/typedefs.h
index 2344c92182ea..5580e1fc4aba 100644
--- a/include/qemu/typedefs.h
+++ b/include/qemu/typedefs.h
@@ -72,7 +72,6 @@ typedef struct MemoryRegionSection MemoryRegionSection;
typedef struct MigrationIncomingState MigrationIncomingState;
typedef struct MigrationState MigrationState;
typedef struct Monitor Monitor;
-typedef struct MonitorDef MonitorDef;
typedef struct MSIMessage MSIMessage;
typedef struct NetClientState NetClientState;
typedef struct NetFilterState NetFilterState;
diff --git a/monitor/hmp.c b/monitor/hmp.c
index 0a74247ca66a..f9621ce90aaf 100644
--- a/monitor/hmp.c
+++ b/monitor/hmp.c
@@ -24,8 +24,8 @@
#include "qemu/osdep.h"
#include <dirent.h>
+#include "hw/core/cpu.h"
#include "hw/core/qdev.h"
-#include "hw/core/sysemu-cpu-ops.h"
#include "monitor-internal.h"
#include "monitor-hmp-internal.h"
#include "monitor/hmp.h"
@@ -447,8 +447,6 @@ static bool get_register(MonitorHMP *hmp, int64_t *pval, const char *name)
static const char *pch;
static sigjmp_buf expr_env;
-static int get_monitor_def(MonitorHMP *mon, int64_t *pval, const char *name);
-
static G_NORETURN G_GNUC_PRINTF(2, 3)
void expr_error(MonitorHMP *mon, const char *fmt, ...)
{
@@ -530,8 +528,7 @@ static int64_t expr_unary(MonitorHMP *mon)
pch++;
}
*q = 0;
- if (!get_register(mon, ®, buf)
- && get_monitor_def(mon, ®, buf) < 0) {
+ if (!get_register(mon, ®, buf)) {
expr_error(mon, "unknown register");
}
n = reg;
@@ -1723,43 +1720,6 @@ void monitor_register_hmp_info_hrt(const char *name,
g_assert_not_reached();
}
-/*
- * Set @pval to the value in the register identified by @name.
- * return 0 if OK, -1 if not found
- */
-static int get_monitor_def(MonitorHMP *hmp, int64_t *pval, const char *name)
-{
- CPUState *cs = monitor_hmp_get_cpu(hmp);
- const MonitorDef *md = NULL;
- void *ptr;
-
- if (cs == NULL) {
- return -1;
- }
- md = cs->cc->sysemu_ops->monitor_defs;
- if (md == NULL) {
- return -1;
- }
-
- for (; md->name != NULL; md++) {
- if (hmp_compare_cmd(name, md->name)) {
- if (md->get_value) {
- *pval = md->get_value(hmp, md, md->offset);
- } else {
- CPUArchState *env = monitor_hmp_get_cpu_env(hmp);
- ptr = (uint8_t *)env + md->offset;
- *pval = *(int32_t *)ptr;
- }
- return 0;
- }
- }
-
- if (!cs->cc->sysemu_ops->monitor_get_register) {
- return -1;
- }
- return cs->cc->sysemu_ops->monitor_get_register(cs, name, pval);
-}
-
int monitor_hmp_vprintf(MonitorHMP *hmp, const char *fmt, va_list ap)
{
g_autofree char *buf = g_strdup_vprintf(fmt, ap);
diff --git a/target/i386/cpu.c b/target/i386/cpu.c
index b97f144aea5a..3218eae62854 100644
--- a/target/i386/cpu.c
+++ b/target/i386/cpu.c
@@ -42,7 +42,6 @@
#include "exec/watchpoint.h"
#ifndef CONFIG_USER_ONLY
#include "confidential-guest.h"
-#include "monitor/hmp.h"
#include "system/reset.h"
#include "qapi/qapi-commands-machine.h"
#include "system/address-spaces.h"
@@ -10852,34 +10851,6 @@ static const Property x86_cpu_properties[] = {
#ifndef CONFIG_USER_ONLY
-#ifdef CONFIG_HMP
-static int64_t monitor_get_pc(MonitorHMP *hmp, const struct MonitorDef *md,
- int offset)
-{
- CPUArchState *env = monitor_hmp_get_cpu_env(hmp);
- int64_t ret = env->eip + env->segs[R_CS].base;
-
- if (!(env->hflags & HF_CS64_MASK)) {
- ret = (int32_t)ret;
- }
- return ret;
-}
-
-static const MonitorDef x86_monitor_defs[] = {
-#define SEG(name, seg) \
- { name ".limit", offsetof(CPUX86State, segs[seg].limit) },
- SEG("cs", R_CS)
- SEG("ds", R_DS)
- SEG("es", R_ES)
- SEG("ss", R_SS)
- SEG("fs", R_FS)
- SEG("gs", R_GS)
- { "pc", 0, monitor_get_pc, },
- { NULL },
-#undef SEG
-};
-#endif
-
#include "hw/core/sysemu-cpu-ops.h"
static const struct SysemuCPUOps i386_sysemu_ops = {
@@ -10893,9 +10864,6 @@ static const struct SysemuCPUOps i386_sysemu_ops = {
.write_elf64_note = x86_cpu_write_elf64_note,
.write_elf32_qemunote = x86_cpu_write_elf32_qemunote,
.write_elf64_qemunote = x86_cpu_write_elf64_qemunote,
-#ifdef CONFIG_HMP
- .monitor_defs = x86_monitor_defs,
-#endif
.legacy_vmsd = &vmstate_x86_cpu,
};
#endif
diff --git a/target/m68k/cpu.c b/target/m68k/cpu.c
index 9b52ad5fc234..ad7303305848 100644
--- a/target/m68k/cpu.c
+++ b/target/m68k/cpu.c
@@ -25,7 +25,6 @@
#include "disas/capstone.h"
#ifndef CONFIG_USER_ONLY
#include "migration/vmstate.h"
-#include "monitor/hmp.h"
#endif
#include "cpu.h"
@@ -666,32 +665,11 @@ static const VMStateDescription vmstate_m68k_cpu = {
},
};
-#ifdef CONFIG_HMP
-static const MonitorDef m68k_monitor_defs[] = {
- { "ssp", offsetof(CPUM68KState, sp[0]) },
- { "usp", offsetof(CPUM68KState, sp[1]) },
- { "isp", offsetof(CPUM68KState, sp[2]) },
- { "sfc", offsetof(CPUM68KState, sfc) },
- { "dfc", offsetof(CPUM68KState, dfc) },
- { "urp", offsetof(CPUM68KState, mmu.urp) },
- { "srp", offsetof(CPUM68KState, mmu.srp) },
- { "dttr0", offsetof(CPUM68KState, mmu.ttr[M68K_DTTR0]) },
- { "dttr1", offsetof(CPUM68KState, mmu.ttr[M68K_DTTR1]) },
- { "ittr0", offsetof(CPUM68KState, mmu.ttr[M68K_ITTR0]) },
- { "ittr1", offsetof(CPUM68KState, mmu.ttr[M68K_ITTR1]) },
- { "mmusr", offsetof(CPUM68KState, mmu.mmusr) },
- { NULL },
-};
-#endif
-
#include "hw/core/sysemu-cpu-ops.h"
static const struct SysemuCPUOps m68k_sysemu_ops = {
.has_work = m68k_cpu_has_work,
.get_phys_addr_debug = m68k_cpu_get_phys_addr_debug,
-#ifdef CONFIG_HMP
- .monitor_defs = m68k_monitor_defs,
-#endif
};
#endif /* !CONFIG_USER_ONLY */
diff --git a/target/riscv/cpu.c b/target/riscv/cpu.c
index 5fff9d745e9b..9a57873ea5d3 100644
--- a/target/riscv/cpu.c
+++ b/target/riscv/cpu.c
@@ -3015,7 +3015,6 @@ static const struct SysemuCPUOps riscv_sysemu_ops = {
.legacy_vmsd = &vmstate_riscv_cpu,
#ifdef CONFIG_TCG
.translate_for_debug = riscv_cpu_translate_for_debug,
- .monitor_get_register = riscv_monitor_get_register_legacy,
#endif
};
#endif
diff --git a/target/riscv/internals.h b/target/riscv/internals.h
index 5d84e4de960a..09aa2701197e 100644
--- a/target/riscv/internals.h
+++ b/target/riscv/internals.h
@@ -263,7 +263,4 @@ static inline int insn_len(uint16_t first_word)
return (first_word & 3) == 3 ? 4 : 2;
}
-int riscv_monitor_get_register_legacy(CPUState *cs, const char *name,
- int64_t *pval);
-
#endif
diff --git a/target/riscv/monitor.c b/target/riscv/monitor.c
index 7e61ae2a4717..20f3ba57ae57 100644
--- a/target/riscv/monitor.c
+++ b/target/riscv/monitor.c
@@ -19,10 +19,7 @@
*/
#include "qemu/osdep.h"
-#include "qemu/ctype.h"
-#include "qemu/qemu-print.h"
#include "cpu.h"
-#include "target/riscv/tcg/csr.h"
#include "cpu_bits.h"
#include "monitor/monitor.h"
#include "monitor/hmp.h"
@@ -247,140 +244,3 @@ void hmp_info_mem(MonitorHMP *hmp, const QDict *qdict)
mem_info_svxx(hmp, env);
}
#endif /* CONFIG_HMP */
-
-#ifdef CONFIG_TCG
-static bool reg_is_ulong_integer(CPURISCVState *env, const char *name,
- target_ulong *val, bool is_gprh)
-{
- const char * const *reg_names;
- uint64_t *vals;
-
- if (is_gprh) {
- reg_names = riscv_int_regnamesh;
- vals = env->gprh;
- } else {
- reg_names = riscv_int_regnames;
- vals = env->gpr;
- }
-
- for (int i = 0; i < 32; i++) {
- g_auto(GStrv) reg_name = g_strsplit(reg_names[i], "/", 2);
-
- g_assert(reg_name[0]);
- g_assert(reg_name[1]);
-
- if (g_ascii_strcasecmp(reg_name[0], name) == 0 ||
- g_ascii_strcasecmp(reg_name[1], name) == 0) {
- *val = vals[i];
- return true;
- }
- }
-
- return false;
-}
-
-static bool reg_is_u64_fpu(CPURISCVState *env, const char *name, uint64_t *val)
-{
- if (qemu_tolower(name[0]) != 'f') {
- return false;
- }
-
- for (int i = 0; i < 32; i++) {
- g_auto(GStrv) reg_name = g_strsplit(riscv_fpr_regnames[i], "/", 2);
-
- g_assert(reg_name[0]);
- g_assert(reg_name[1]);
-
- if (g_ascii_strcasecmp(reg_name[0], name) == 0 ||
- g_ascii_strcasecmp(reg_name[1], name) == 0) {
- *val = env->fpr[i];
- return true;
- }
- }
-
- return false;
-}
-
-static bool reg_is_vreg(const char *name)
-{
- if (qemu_tolower(name[0]) != 'v' || strlen(name) > 3) {
- return false;
- }
-
- for (int i = 0; i < 32; i++) {
- if (g_ascii_strcasecmp(name, riscv_rvv_regnames[i]) == 0) {
- return true;
- }
- }
-
- return false;
-}
-
-int riscv_monitor_get_register_legacy(CPUState *cs, const char *name,
- int64_t *pval)
-{
- RISCVCPU *hart = RISCV_CPU(cs);
- CPURISCVState *env = cpu_env(cs);
- target_ulong val = 0;
- uint64_t val64 = 0;
- int i;
-
- if (reg_is_ulong_integer(env, name, &val, false) ||
- reg_is_ulong_integer(env, name, &val, true)) {
- *pval = riscv_cpu_is_32bit(hart) ? (int32_t)val : val;
- return 0;
- }
-
- if (reg_is_u64_fpu(env, name, &val64)) {
- *pval = val64;
- return 0;
- }
-
- if (reg_is_vreg(name)) {
- if (!riscv_cpu_cfg(env)->ext_zve32x) {
- return -EINVAL;
- }
-
- qemu_printf("Unable to print the value of vector "
- "vreg '%s' from this API\n", name);
-
- /*
- * We're returning 0 because returning -EINVAL triggers
- * an 'unknown register' message in exp_unary() later,
- * which feels ankward after our own error message.
- */
- *pval = 0;
- return 0;
- }
-
- for (i = 0; i < ARRAY_SIZE(csr_ops); i++) {
- RISCVException res;
- int csrno = i;
-
- /*
- * Early skip when possible since we're going
- * through a lot of NULL entries.
- */
- if (csr_ops[csrno].predicate == NULL) {
- continue;
- }
-
- if (g_ascii_strcasecmp(csr_ops[csrno].name, name) != 0) {
- continue;
- }
-
- res = riscv_csrrw_debug(env, csrno, &val, 0, 0);
-
- /*
- * Rely on the smode, hmode, etc, predicates within csr.c
- * to do the filtering of the registers that are present.
- */
- if (res == RISCV_EXCP_NONE) {
- *pval = riscv_cpu_is_32bit(hart) ? (int32_t)val : val;
- return 0;
- }
- }
-
- return -EINVAL;
-}
-#endif
diff --git a/target/sparc/cpu.c b/target/sparc/cpu.c
index ae9bdca9df82..89dfb091ca87 100644
--- a/target/sparc/cpu.c
+++ b/target/sparc/cpu.c
@@ -995,31 +995,12 @@ static const Property sparc_cpu_properties[] = {
#ifndef CONFIG_USER_ONLY
-#ifdef TARGET_SPARC64
-#include "monitor/hmp.h"
-#ifdef CONFIG_HMP
-static const MonitorDef sparc64_monitor_defs[] = {
- { "asi", offsetof(CPUSPARCState, asi) },
- { "pstate", offsetof(CPUSPARCState, pstate) },
- { "cansave", offsetof(CPUSPARCState, cansave) },
- { "canrestore", offsetof(CPUSPARCState, canrestore) },
- { "otherwin", offsetof(CPUSPARCState, otherwin) },
- { "wstate", offsetof(CPUSPARCState, wstate) },
- { "cleanwin", offsetof(CPUSPARCState, cleanwin) },
- { NULL },
-};
-#endif
-#endif
-
#include "hw/core/sysemu-cpu-ops.h"
static const struct SysemuCPUOps sparc_sysemu_ops = {
.has_work = sparc_cpu_has_work,
.get_phys_addr_debug = sparc_cpu_get_phys_addr_debug,
.legacy_vmsd = &vmstate_sparc_cpu,
-#if defined(TARGET_SPARC64) && defined(CONFIG_HMP)
- .monitor_defs = sparc64_monitor_defs,
-#endif
};
#endif
--
2.55.0.543.g5ebe2ebe4ea8
^ permalink raw reply related [flat|nested] 12+ messages in thread
* Re: [PATCH 02/10] gdbstub: fix next register base after register gaps
2026-09-11 12:27 ` [PATCH 02/10] gdbstub: fix next register base after register gaps Marc-André Lureau
@ 2026-09-11 15:29 ` Alex Bennée
0 siblings, 0 replies; 12+ messages in thread
From: Alex Bennée @ 2026-09-11 15:29 UTC (permalink / raw)
To: Marc-André Lureau
Cc: qemu-devel, Dr. David Alan Gilbert, Philippe Mathieu-Daudé,
Zhao Liu, Peter Maydell, Chinmay Rath, Nicholas Piggin,
Glenn Miles, Harsh Prateek Bora, Palmer Dabbelt, Alistair Francis,
Weiwei Li, Daniel Henrique Barboza, Liu Zhiwei, Chao Liu,
Max Filippov, qemu-arm, qemu-ppc, qemu-riscv, Paolo Bonzini,
Laurent Vivier, Mark Cave-Ayland, Artyom Tarasenko, Helge Deller,
Pierrick Bouvier, Warner Losh, Kyle Evans
Marc-André Lureau <marcandre.lureau@redhat.com> writes:
> Commit b3e88abb200c ("gdbstub: Consider GDBFeature::base_reg in
> gdb_register_coprocessor()") identified that register numbers may
> have gaps. We also need to adjust the next base_reg correctly
> to avoid overlapping registers. Rename the field to be more
> explicit about its usage.
>
> Signed-off-by: Marc-André Lureau <marcandre.lureau@redhat.com>
Acked-by: Alex Bennée <alex.bennee@linaro.org>
> ---
> gdbstub/gdbstub.c | 13 ++++++-------
> include/hw/core/cpu.h | 2 +-
> target/arm/gdbstub.c | 8 +++++---
> target/arm/gdbstub64.c | 10 ++++++----
> target/ppc/gdbstub.c | 2 +-
> target/riscv/gdbstub.c | 9 ++++++---
> target/xtensa/cpu.c | 2 +-
> 7 files changed, 26 insertions(+), 20 deletions(-)
>
> diff --git a/gdbstub/gdbstub.c b/gdbstub/gdbstub.c
> index 0a328b0dd488..0ce871d74929 100644
> --- a/gdbstub/gdbstub.c
> +++ b/gdbstub/gdbstub.c
> @@ -605,13 +605,13 @@ void gdb_init_cpu(CPUState *cpu)
> gdb_register_feature(cpu, 0,
> cc->gdb_read_register, cc->gdb_write_register,
> feature);
> - cpu->gdb_num_regs = cpu->gdb_num_g_regs = feature->num_regs;
> + cpu->gdb_next_base_reg = cpu->gdb_num_g_regs = feature->num_regs;
> } else {
> - cpu->gdb_num_regs = cpu->gdb_num_g_regs = cc->gdb_num_core_regs;
> + cpu->gdb_next_base_reg = cpu->gdb_num_g_regs = cc->gdb_num_core_regs;
> }
>
> trace_gdbxml_init_cpu(object_get_typename(OBJECT(cpu)), cpu->cpu_index,
> - cpu->gdb_num_regs, cpu->gdb_num_g_regs,
> + cpu->gdb_next_base_reg, cpu->gdb_num_g_regs,
> cc->gdb_num_core_regs);
> }
>
> @@ -621,7 +621,7 @@ void gdb_register_coprocessor(CPUState *cpu,
> {
> GDBRegisterState *s;
> guint i;
> - int base_reg = cpu->gdb_num_regs;
> + int base_reg = cpu->gdb_next_base_reg;
>
> for (i = 0; i < cpu->gdb_regs->len; i++) {
> /* Check for duplicates. */
> @@ -639,7 +639,7 @@ void gdb_register_coprocessor(CPUState *cpu,
> gdb_register_feature(cpu, base_reg, get_reg, set_reg, feature);
>
> /* Add to end of list. */
> - cpu->gdb_num_regs += feature->num_regs;
> + cpu->gdb_next_base_reg = base_reg + feature->num_regs;
> }
>
> void gdb_unregister_coprocessor_all(CPUState *cpu)
> @@ -651,7 +651,7 @@ void gdb_unregister_coprocessor_all(CPUState *cpu)
> g_array_free(cpu->gdb_regs, true);
>
> cpu->gdb_regs = NULL;
> - cpu->gdb_num_regs = 0;
> + cpu->gdb_next_base_reg = 0;
> cpu->gdb_num_g_regs = 0;
> }
>
> @@ -2522,4 +2522,3 @@ void gdb_create_default_process(GDBState *s)
> process->attached = false;
> process->target_xml = NULL;
> }
> -
> diff --git a/include/hw/core/cpu.h b/include/hw/core/cpu.h
> index 328e30045ce1..02212f555c2e 100644
> --- a/include/hw/core/cpu.h
> +++ b/include/hw/core/cpu.h
> @@ -521,7 +521,7 @@ struct CPUState {
> struct CPUJumpCache *tb_jmp_cache;
>
> GArray *gdb_regs;
> - int gdb_num_regs;
> + int gdb_next_base_reg;
> int gdb_num_g_regs;
> QTAILQ_ENTRY(CPUState) node;
>
> diff --git a/target/arm/gdbstub.c b/target/arm/gdbstub.c
> index d6e29c4cf467..e5cbe4d951ef 100644
> --- a/target/arm/gdbstub.c
> +++ b/target/arm/gdbstub.c
> @@ -555,19 +555,21 @@ void arm_cpu_register_gdb_regs_for_features(ARMCPU *cpu)
> gdb_register_coprocessor(cs, mve_gdb_get_reg, mve_gdb_set_reg,
> gdb_find_static_feature("arm-m-profile-mve.xml"));
> }
> + GDBFeature *feature =
> + arm_gen_dynamic_sysreg_feature(cs, cs->gdb_next_base_reg);
> gdb_register_coprocessor(cs, arm_gdb_get_sysreg, arm_gdb_set_sysreg,
> - arm_gen_dynamic_sysreg_feature(cs, cs->gdb_num_regs));
> + feature);
>
> #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_feature(cs, cs->gdb_num_regs));
> + arm_gen_dynamic_m_systemreg_feature(cs, cs->gdb_next_base_reg));
> #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_feature(cs, cs->gdb_num_regs));
> + arm_gen_dynamic_m_secextreg_feature(cs, cs->gdb_next_base_reg));
> }
> #endif
> }
> diff --git a/target/arm/gdbstub64.c b/target/arm/gdbstub64.c
> index 0c3e5b30bd6a..cf5b95b54641 100644
> --- a/target/arm/gdbstub64.c
> +++ b/target/arm/gdbstub64.c
> @@ -885,7 +885,8 @@ void aarch64_cpu_register_gdb_regs_for_features(ARMCPU *cpu)
> CPUState *cs = CPU(cpu);
> if (isar_feature_aa64_sve(&cpu->isar) ||
> isar_feature_aa64_sme(&cpu->isar)) {
> - GDBFeature *feature = arm_gen_dynamic_svereg_feature(cs, cs->gdb_num_regs);
> + GDBFeature *feature =
> + arm_gen_dynamic_svereg_feature(cs, cs->gdb_next_base_reg);
> gdb_register_coprocessor(cs, aarch64_gdb_get_sve_reg,
> aarch64_gdb_set_sve_reg, feature);
> } else {
> @@ -896,7 +897,7 @@ void aarch64_cpu_register_gdb_regs_for_features(ARMCPU *cpu)
>
> if (isar_feature_aa64_sme(&cpu->isar)) {
> GDBFeature *sme_feature =
> - arm_gen_dynamic_smereg_feature(cs, cs->gdb_num_regs);
> + arm_gen_dynamic_smereg_feature(cs, cs->gdb_next_base_reg);
> gdb_register_coprocessor(cs, aarch64_gdb_get_sme_reg,
> aarch64_gdb_set_sme_reg, sme_feature);
> if (isar_feature_aa64_sme2(&cpu->isar)) {
> @@ -927,7 +928,8 @@ void aarch64_cpu_register_gdb_regs_for_features(ARMCPU *cpu)
> #endif
>
> /* All AArch64 CPUs have at least TPIDR */
> + GDBFeature *tls_feature =
> + arm_gen_dynamic_tls_feature(cs, cs->gdb_next_base_reg);
> gdb_register_coprocessor(cs, aarch64_gdb_get_tls_reg,
> - aarch64_gdb_set_tls_reg,
> - arm_gen_dynamic_tls_feature(cs, cs->gdb_num_regs));
> + aarch64_gdb_set_tls_reg, tls_feature);
> }
> diff --git a/target/ppc/gdbstub.c b/target/ppc/gdbstub.c
> index 4d622c5cad59..ec25c541c685 100644
> --- a/target/ppc/gdbstub.c
> +++ b/target/ppc/gdbstub.c
> @@ -206,7 +206,7 @@ static void gdb_gen_spr_feature(CPUState *cs)
>
> gdb_feature_builder_init(&builder, &pcc->gdb_spr,
> "org.qemu.power.spr", "power-spr.xml",
> - cs->gdb_num_regs);
> + cs->gdb_next_base_reg);
>
> for (i = 0; i < ARRAY_SIZE(env->spr_cb); i++) {
> ppc_spr_t *spr = &env->spr_cb[i];
> diff --git a/target/riscv/gdbstub.c b/target/riscv/gdbstub.c
> index 9abbf5bcdf0e..f279f4ab2461 100644
> --- a/target/riscv/gdbstub.c
> +++ b/target/riscv/gdbstub.c
> @@ -348,9 +348,10 @@ void riscv_cpu_register_gdb_regs_for_features(CPUState *cs)
> gdb_find_static_feature("riscv-32bit-fpu.xml"));
> }
> if (cpu->cfg.ext_zve32x) {
> + GDBFeature *feature =
> + ricsv_gen_dynamic_vector_feature(cs, cs->gdb_next_base_reg);
> gdb_register_coprocessor(cs, riscv_gdb_get_vector,
> - riscv_gdb_set_vector,
> - ricsv_gen_dynamic_vector_feature(cs, cs->gdb_num_regs));
> + riscv_gdb_set_vector, feature);
> }
>
> #ifdef CONFIG_TCG
> @@ -373,8 +374,10 @@ void riscv_cpu_register_gdb_regs_for_features(CPUState *cs)
> }
>
> if (cpu->cfg.ext_zicsr) {
> + GDBFeature *feature =
> + riscv_gen_dynamic_csr_feature(cs, cs->gdb_next_base_reg);
> gdb_register_coprocessor(cs, riscv_gdb_get_csr, riscv_gdb_set_csr,
> - riscv_gen_dynamic_csr_feature(cs, cs->gdb_num_regs));
> + feature);
> }
> #endif
> }
> diff --git a/target/xtensa/cpu.c b/target/xtensa/cpu.c
> index 7c25b9ab707a..48863a1859d4 100644
> --- a/target/xtensa/cpu.c
> +++ b/target/xtensa/cpu.c
> @@ -263,7 +263,7 @@ static void xtensa_cpu_realizefn(DeviceState *dev, Error **errp)
> return;
> }
>
> - cs->gdb_num_regs = xcc->config->gdb_regmap.num_regs;
> + cs->gdb_next_base_reg = xcc->config->gdb_regmap.num_regs;
>
> qemu_init_vcpu(cs);
--
Alex Bennée
Virtualisation Tech Lead @ Linaro
^ permalink raw reply [flat|nested] 12+ messages in thread
end of thread, other threads:[~2026-09-11 15:30 UTC | newest]
Thread overview: 12+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2026-09-11 12:27 [PATCH 00/10] monitor/hmp: replace MonitorDef with GDB registers Marc-André Lureau
2026-09-11 12:27 ` [PATCH 01/10] hmp: don't crash on invalid register Marc-André Lureau
2026-09-11 12:27 ` [PATCH 02/10] gdbstub: fix next register base after register gaps Marc-André Lureau
2026-09-11 15:29 ` Alex Bennée
2026-09-11 12:27 ` [PATCH 03/10] gdbstub: set feature->base_reg for dynamic features Marc-André Lureau
2026-09-11 12:27 ` [PATCH 04/10] target/i386: expose segment limits via GDB Marc-André Lureau
2026-09-11 12:27 ` [PATCH 05/10] monitor/hmp: add CPUClass::get_pc fallback for HMP $pc Marc-André Lureau
2026-09-11 12:27 ` [PATCH 06/10] target/m68k: expose system registers via GDB Marc-André Lureau
2026-09-11 12:27 ` [PATCH 07/10] target/sparc64: " Marc-André Lureau
2026-09-11 12:27 ` [PATCH 08/10] target/riscv: bypass smstateen check in debugger mode Marc-André Lureau
2026-09-11 12:27 ` [PATCH 09/10] target/riscv: expose register aliases via GDB Marc-André Lureau
2026-09-11 12:27 ` [PATCH 10/10] monitor/hmp: remove legacy MonitorDef infrastructure Marc-André Lureau
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox