aboutsummaryrefslogtreecommitdiff
path: root/gdb/aarch64-linux-nat.c
diff options
context:
space:
mode:
Diffstat (limited to 'gdb/aarch64-linux-nat.c')
-rw-r--r--gdb/aarch64-linux-nat.c54
1 files changed, 52 insertions, 2 deletions
diff --git a/gdb/aarch64-linux-nat.c b/gdb/aarch64-linux-nat.c
index 1e4f937..1e7db29 100644
--- a/gdb/aarch64-linux-nat.c
+++ b/gdb/aarch64-linux-nat.c
@@ -384,19 +384,62 @@ store_fpregs_to_thread (const struct regcache *regcache)
}
}
+/* Fill GDB's register array with the sve register values
+ from the current thread. */
+
+static void
+fetch_sveregs_from_thread (struct regcache *regcache)
+{
+ std::unique_ptr<gdb_byte[]> base
+ = aarch64_sve_get_sveregs (ptid_get_lwp (regcache->ptid ()));
+ aarch64_sve_regs_copy_to_reg_buf (regcache, base.get ());
+}
+
+/* Store to the current thread the valid sve register
+ values in the GDB's register array. */
+
+static void
+store_sveregs_to_thread (struct regcache *regcache)
+{
+ int ret;
+ struct iovec iovec;
+ int tid = ptid_get_lwp (regcache->ptid ());
+
+ /* Obtain a dump of SVE registers from ptrace. */
+ std::unique_ptr<gdb_byte[]> base = aarch64_sve_get_sveregs (tid);
+
+ /* Overwrite with regcache state. */
+ aarch64_sve_regs_copy_from_reg_buf (regcache, base.get ());
+
+ /* Write back to the kernel. */
+ iovec.iov_base = base.get ();
+ iovec.iov_len = ((struct user_sve_header *) base.get ())->size;
+ ret = ptrace (PTRACE_SETREGSET, tid, NT_ARM_SVE, &iovec);
+
+ if (ret < 0)
+ perror_with_name (_("Unable to store sve registers"));
+}
+
/* Implement the "fetch_registers" target_ops method. */
void
aarch64_linux_nat_target::fetch_registers (struct regcache *regcache,
int regno)
{
+ struct gdbarch_tdep *tdep = gdbarch_tdep (regcache->arch ());
+
if (regno == -1)
{
fetch_gregs_from_thread (regcache);
- fetch_fpregs_from_thread (regcache);
+ if (tdep->has_sve ())
+ fetch_sveregs_from_thread (regcache);
+ else
+ fetch_fpregs_from_thread (regcache);
}
else if (regno < AARCH64_V0_REGNUM)
fetch_gregs_from_thread (regcache);
+ else if (tdep->has_sve ())
+ fetch_sveregs_from_thread (regcache);
else
fetch_fpregs_from_thread (regcache);
}
@@ -407,13 +450,20 @@ void
aarch64_linux_nat_target::store_registers (struct regcache *regcache,
int regno)
{
+ struct gdbarch_tdep *tdep = gdbarch_tdep (regcache->arch ());
+
if (regno == -1)
{
store_gregs_to_thread (regcache);
- store_fpregs_to_thread (regcache);
+ if (tdep->has_sve ())
+ store_sveregs_to_thread (regcache);
+ else
+ store_fpregs_to_thread (regcache);
}
else if (regno < AARCH64_V0_REGNUM)
store_gregs_to_thread (regcache);
+ else if (tdep->has_sve ())
+ store_sveregs_to_thread (regcache);
else
store_fpregs_to_thread (regcache);
}