Our gdbstub implementation of the org.gnu.gdb.aarch64.sve feature
doesn't account for SME correctly. We always report the Zn vector
registers with a width based on the maximum SVE vector register size,
even though SME's maximum size could be larger.
This is particularly bad in the case of a CPU with SME but not SVE,
because there the SVE vector width will be zero. If we report the Zn
registers in the XML as having a zero width then gdb falls over with
an internal error:
(gdb) target remote :1234
Remote debugging using :1234
/build/gdb-1WjiBe/gdb-15.0.50.20240403/gdb/aarch64-tdep.c:3066: internal-error: aarch64_pseudo_register_type: bad register number 160
A problem internal to GDB has been detected,
further debugging may prove unreliable.
Report the Zn registers with their correct size. This matches how we
already handle the 'vg' pseudoregister in org.gnu.gdb.aarch64.sve: we
call sve_vqm1_for_el(), which returns the vector size accounting for
SME, not the pure SVE vector size.
Cc: qemu-stable@nongnu.org
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
---
We should make sure we have agreement on the gdb side about
the interpretation of this bit of the protocol. See this
gdb mailing list email:
https://sourceware.org/pipermail/gdb/2026-January/052056.html
---
target/arm/gdbstub64.c | 12 ++++++------
1 file changed, 6 insertions(+), 6 deletions(-)
diff --git a/target/arm/gdbstub64.c b/target/arm/gdbstub64.c
index c584e5b4e6..b71666c3a1 100644
--- a/target/arm/gdbstub64.c
+++ b/target/arm/gdbstub64.c
@@ -158,7 +158,7 @@ int aarch64_gdb_get_sve_reg(CPUState *cs, GByteArray *buf, int reg)
case 0 ... 31:
{
int vq, len = 0;
- for (vq = 0; vq < cpu->sve_max_vq; vq++) {
+ for (vq = 0; vq < arm_max_vq(cpu); vq++) {
len += gdb_get_reg128(buf,
env->vfp.zregs[reg].d[vq * 2 + 1],
env->vfp.zregs[reg].d[vq * 2]);
@@ -174,7 +174,7 @@ int aarch64_gdb_get_sve_reg(CPUState *cs, GByteArray *buf, int reg)
{
int preg = reg - 34;
int vq, len = 0;
- for (vq = 0; vq < cpu->sve_max_vq; vq = vq + 4) {
+ for (vq = 0; vq < arm_max_vq(cpu); vq = vq + 4) {
len += gdb_get_reg64(buf, env->vfp.pregs[preg].p[vq / 4]);
}
return len;
@@ -208,7 +208,7 @@ int aarch64_gdb_set_sve_reg(CPUState *cs, uint8_t *buf, int reg)
case 0 ... 31:
{
int vq, len = 0;
- for (vq = 0; vq < cpu->sve_max_vq; vq++) {
+ for (vq = 0; vq < arm_max_vq(cpu); vq++) {
if (target_big_endian()) {
env->vfp.zregs[reg].d[vq * 2 + 1] = ldq_p(buf);
buf += 8;
@@ -233,7 +233,7 @@ int aarch64_gdb_set_sve_reg(CPUState *cs, uint8_t *buf, int reg)
{
int preg = reg - 34;
int vq, len = 0;
- for (vq = 0; vq < cpu->sve_max_vq; vq = vq + 4) {
+ for (vq = 0; vq < arm_max_vq(cpu); vq = vq + 4) {
env->vfp.pregs[preg].p[vq / 4] = ldq_p(buf);
buf += 8;
len += 8;
@@ -540,8 +540,8 @@ static void output_vector_union_type(GDBFeatureBuilder *builder, int reg_width,
GDBFeature *arm_gen_dynamic_svereg_feature(CPUState *cs, int base_reg)
{
ARMCPU *cpu = ARM_CPU(cs);
- int reg_width = cpu->sve_max_vq * 128;
- int pred_width = cpu->sve_max_vq * 16;
+ int reg_width = arm_max_vq(cpu) * 128;
+ int pred_width = arm_max_vq(cpu) * 16;
GDBFeatureBuilder builder;
char *name;
int reg = 0;
--
2.43.0
Peter Maydell <peter.maydell@linaro.org> writes: > Our gdbstub implementation of the org.gnu.gdb.aarch64.sve feature > doesn't account for SME correctly. We always report the Zn vector > registers with a width based on the maximum SVE vector register size, > even though SME's maximum size could be larger. > > This is particularly bad in the case of a CPU with SME but not SVE, > because there the SVE vector width will be zero. If we report the Zn > registers in the XML as having a zero width then gdb falls over with > an internal error: > > (gdb) target remote :1234 > Remote debugging using :1234 > /build/gdb-1WjiBe/gdb-15.0.50.20240403/gdb/aarch64-tdep.c:3066: internal-error: aarch64_pseudo_register_type: bad register number 160 > A problem internal to GDB has been detected, > further debugging may prove unreliable. > > Report the Zn registers with their correct size. This matches how we > already handle the 'vg' pseudoregister in org.gnu.gdb.aarch64.sve: we > call sve_vqm1_for_el(), which returns the vector size accounting for > SME, not the pure SVE vector size. > > Cc: qemu-stable@nongnu.org > Signed-off-by: Peter Maydell <peter.maydell@linaro.org> Reviewed-by: Alex Bennée <alex.bennee@linaro.org> -- Alex Bennée Virtualisation Tech Lead @ Linaro
On 29/1/26 12:34, Peter Maydell wrote: > Our gdbstub implementation of the org.gnu.gdb.aarch64.sve feature > doesn't account for SME correctly. We always report the Zn vector > registers with a width based on the maximum SVE vector register size, > even though SME's maximum size could be larger. > > This is particularly bad in the case of a CPU with SME but not SVE, > because there the SVE vector width will be zero. If we report the Zn > registers in the XML as having a zero width then gdb falls over with > an internal error: > > (gdb) target remote :1234 > Remote debugging using :1234 > /build/gdb-1WjiBe/gdb-15.0.50.20240403/gdb/aarch64-tdep.c:3066: internal-error: aarch64_pseudo_register_type: bad register number 160 > A problem internal to GDB has been detected, > further debugging may prove unreliable. > > Report the Zn registers with their correct size. This matches how we > already handle the 'vg' pseudoregister in org.gnu.gdb.aarch64.sve: we > call sve_vqm1_for_el(), which returns the vector size accounting for > SME, not the pure SVE vector size. > > Cc: qemu-stable@nongnu.org > Signed-off-by: Peter Maydell <peter.maydell@linaro.org> > --- > We should make sure we have agreement on the gdb side about > the interpretation of this bit of the protocol. See this > gdb mailing list email: > https://sourceware.org/pipermail/gdb/2026-January/052056.html > --- > target/arm/gdbstub64.c | 12 ++++++------ > 1 file changed, 6 insertions(+), 6 deletions(-) Reviewed-by: Philippe Mathieu-Daudé <philmd@linaro.org>
© 2016 - 2026 Red Hat, Inc.