aboutsummaryrefslogtreecommitdiff
path: root/target/arm/gdbstub64.c
diff options
context:
space:
mode:
Diffstat (limited to 'target/arm/gdbstub64.c')
-rw-r--r--target/arm/gdbstub64.c35
1 files changed, 28 insertions, 7 deletions
diff --git a/target/arm/gdbstub64.c b/target/arm/gdbstub64.c
index 64ee9b3..08e2858 100644
--- a/target/arm/gdbstub64.c
+++ b/target/arm/gdbstub64.c
@@ -115,8 +115,22 @@ int aarch64_gdb_set_fpu_reg(CPUState *cs, uint8_t *buf, int reg)
/* 128 bit FP register */
{
uint64_t *q = aa64_vfp_qreg(env, reg);
- q[0] = ldq_le_p(buf);
- q[1] = ldq_le_p(buf + 8);
+
+ /*
+ * On the wire these are target-endian 128 bit values.
+ * In the CPU state these are host-order uint64_t values
+ * with the least-significant one first. This means they're
+ * the other way around for target_big_endian() (which is
+ * only true for us for aarch64_be-linux-user).
+ */
+ if (target_big_endian()) {
+ q[1] = ldq_p(buf);
+ q[0] = ldq_p(buf + 8);
+ } else{
+ q[0] = ldq_p(buf);
+ q[1] = ldq_p(buf + 8);
+ }
+
return 16;
}
case 32:
@@ -192,10 +206,17 @@ int aarch64_gdb_set_sve_reg(CPUState *cs, uint8_t *buf, int reg)
case 0 ... 31:
{
int vq, len = 0;
- uint64_t *p = (uint64_t *) buf;
for (vq = 0; vq < cpu->sve_max_vq; vq++) {
- env->vfp.zregs[reg].d[vq * 2 + 1] = *p++;
- env->vfp.zregs[reg].d[vq * 2] = *p++;
+ if (target_big_endian()) {
+ env->vfp.zregs[reg].d[vq * 2 + 1] = ldq_p(buf);
+ buf += 8;
+ env->vfp.zregs[reg].d[vq * 2] = ldq_p(buf);
+ } else{
+ env->vfp.zregs[reg].d[vq * 2] = ldq_p(buf);
+ buf += 8;
+ env->vfp.zregs[reg].d[vq * 2 + 1] = ldq_p(buf);
+ }
+ buf += 8;
len += 16;
}
return len;
@@ -210,9 +231,9 @@ int aarch64_gdb_set_sve_reg(CPUState *cs, uint8_t *buf, int reg)
{
int preg = reg - 34;
int vq, len = 0;
- uint64_t *p = (uint64_t *) buf;
for (vq = 0; vq < cpu->sve_max_vq; vq = vq + 4) {
- env->vfp.pregs[preg].p[vq / 4] = *p++;
+ env->vfp.pregs[preg].p[vq / 4] = ldq_p(buf);
+ buf += 8;
len += 8;
}
return len;