aboutsummaryrefslogtreecommitdiff
path: root/target
diff options
context:
space:
mode:
authorPeter Maydell <peter.maydell@linaro.org>2020-05-07 14:47:55 +0100
committerPeter Maydell <peter.maydell@linaro.org>2020-05-14 15:03:08 +0100
commitc888f7e0fdcc09c86004330ab5cad62bf98cc71c (patch)
tree13e517c10433aeed092c6977c7dea558e02d3573 /target
parent035b448b84f3557206abc44d786c5d3db2638f7d (diff)
target/arm: Use correct GDB XML for M-profile cores
GDB's remote protocol requires M-profile cores to use the feature name 'org.gnu.gdb.arm.m-profile' instead of the 'org.gnu.gdb.arm.core' feature used for A- and R-profile cores. We weren't doing this, which meant GDB treated our M-profile cores like A-profile ones. This mostly doesn't matter, but for instance means that it doesn't correctly handle backtraces where an M-profile exception frame is involved. Ship a copy of GDB's arm-m-profile.xml and use it on the M-profile cores. The integer registers have the same offsets as the arm-core.xml, but register 25 is the M-profile XPSR rather than the A-profile CPSR, so we need to update arm_cpu_gdb_read_register() and arm_cpu_gdb_write_register() to handle XSPR reads and writes. Fixes: https://bugs.launchpad.net/qemu/+bug/1877136 Signed-off-by: Peter Maydell <peter.maydell@linaro.org> Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org> Message-id: 20200507134755.13997-1-peter.maydell@linaro.org
Diffstat (limited to 'target')
-rw-r--r--target/arm/cpu_tcg.c1
-rw-r--r--target/arm/gdbstub.c22
2 files changed, 19 insertions, 4 deletions
diff --git a/target/arm/cpu_tcg.c b/target/arm/cpu_tcg.c
index 591baef535..00b0e08f33 100644
--- a/target/arm/cpu_tcg.c
+++ b/target/arm/cpu_tcg.c
@@ -605,6 +605,7 @@ static void arm_v7m_class_init(ObjectClass *oc, void *data)
#endif
cc->cpu_exec_interrupt = arm_v7m_cpu_exec_interrupt;
+ cc->gdb_core_xml_file = "arm-m-profile.xml";
}
static const ARMCPUInfo arm_tcg_cpus[] = {
diff --git a/target/arm/gdbstub.c b/target/arm/gdbstub.c
index 063551df23..ecfa88f8e6 100644
--- a/target/arm/gdbstub.c
+++ b/target/arm/gdbstub.c
@@ -57,8 +57,12 @@ int arm_cpu_gdb_read_register(CPUState *cs, GByteArray *mem_buf, int n)
}
return gdb_get_reg32(mem_buf, 0);
case 25:
- /* CPSR */
- return gdb_get_reg32(mem_buf, cpsr_read(env));
+ /* CPSR, or XPSR for M-profile */
+ if (arm_feature(env, ARM_FEATURE_M)) {
+ return gdb_get_reg32(mem_buf, xpsr_read(env));
+ } else {
+ return gdb_get_reg32(mem_buf, cpsr_read(env));
+ }
}
/* Unknown register. */
return 0;
@@ -98,8 +102,18 @@ int arm_cpu_gdb_write_register(CPUState *cs, uint8_t *mem_buf, int n)
}
return 4;
case 25:
- /* CPSR */
- cpsr_write(env, tmp, 0xffffffff, CPSRWriteByGDBStub);
+ /* CPSR, or XPSR for M-profile */
+ if (arm_feature(env, ARM_FEATURE_M)) {
+ /*
+ * Don't allow writing to XPSR.Exception as it can cause
+ * a transition into or out of handler mode (it's not
+ * writeable via the MSR insn so this is a reasonable
+ * restriction). Other fields are safe to update.
+ */
+ xpsr_write(env, tmp, ~XPSR_EXCP);
+ } else {
+ cpsr_write(env, tmp, 0xffffffff, CPSRWriteByGDBStub);
+ }
return 4;
}
/* Unknown register. */