diff options
Diffstat (limited to 'gdb/aarch64-linux-nat.c')
-rw-r--r-- | gdb/aarch64-linux-nat.c | 54 |
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); } |