aboutsummaryrefslogtreecommitdiff
path: root/gdb/aarch64-linux-nat.c
diff options
context:
space:
mode:
authorAlan Hayward <alan.hayward@arm.com>2019-03-22 10:31:02 +0000
committerAlan Hayward <alan.hayward@arm.com>2019-03-22 10:31:02 +0000
commit76bed0fd9493868889929ca9dcd32350c1d864be (patch)
treee799ee78fc4b6802da976a837deea5a6f44c63a2 /gdb/aarch64-linux-nat.c
parentee4fbcfa26eb4a2a3666f7c1cc31447c3cffa023 (diff)
downloadbinutils-76bed0fd9493868889929ca9dcd32350c1d864be.zip
binutils-76bed0fd9493868889929ca9dcd32350c1d864be.tar.gz
binutils-76bed0fd9493868889929ca9dcd32350c1d864be.tar.bz2
AArch64: Read pauth registers
Initialise the pauth registers when creating a target description, and store the regnum of the first pauth register. Use ptrace to read the registers in the pauth feature. Do not allow the registers to be written. gdb/ChangeLog: * aarch64-linux-nat.c (fetch_pauth_masks_from_thread): New function. (aarch64_linux_nat_target::fetch_registers): Read pauth registers. * aarch64-tdep.c (aarch64_cannot_store_register): New function. (aarch64_gdbarch_init): Add puth registers. * aarch64-tdep.h (struct gdbarch_tdep): Add pauth features. * arch/aarch64.h (AARCH64_PAUTH_DMASK_REGNUM): New define. (AARCH64_PAUTH_CMASK_REGNUM): Likewise.
Diffstat (limited to 'gdb/aarch64-linux-nat.c')
-rw-r--r--gdb/aarch64-linux-nat.c35
1 files changed, 35 insertions, 0 deletions
diff --git a/gdb/aarch64-linux-nat.c b/gdb/aarch64-linux-nat.c
index 9572055..86c7e87 100644
--- a/gdb/aarch64-linux-nat.c
+++ b/gdb/aarch64-linux-nat.c
@@ -423,6 +423,31 @@ store_sveregs_to_thread (struct regcache *regcache)
perror_with_name (_("Unable to store sve registers"));
}
+/* Fill GDB's register array with the pointer authentication mask values from
+ the current thread. */
+
+static void
+fetch_pauth_masks_from_thread (struct regcache *regcache)
+{
+ struct gdbarch_tdep *tdep = gdbarch_tdep (regcache->arch ());
+ int ret;
+ struct iovec iovec;
+ uint64_t pauth_regset[2] = {0, 0};
+ int tid = regcache->ptid ().lwp ();
+
+ iovec.iov_base = &pauth_regset;
+ iovec.iov_len = sizeof (pauth_regset);
+
+ ret = ptrace (PTRACE_GETREGSET, tid, NT_ARM_PAC_MASK, &iovec);
+ if (ret != 0)
+ perror_with_name (_("unable to fetch pauth registers."));
+
+ regcache->raw_supply (AARCH64_PAUTH_DMASK_REGNUM (tdep->pauth_reg_base),
+ &pauth_regset[0]);
+ regcache->raw_supply (AARCH64_PAUTH_CMASK_REGNUM (tdep->pauth_reg_base),
+ &pauth_regset[1]);
+}
+
/* Implement the "fetch_registers" target_ops method. */
void
@@ -438,6 +463,9 @@ aarch64_linux_nat_target::fetch_registers (struct regcache *regcache,
fetch_sveregs_from_thread (regcache);
else
fetch_fpregs_from_thread (regcache);
+
+ if (tdep->has_pauth ())
+ fetch_pauth_masks_from_thread (regcache);
}
else if (regno < AARCH64_V0_REGNUM)
fetch_gregs_from_thread (regcache);
@@ -445,6 +473,13 @@ aarch64_linux_nat_target::fetch_registers (struct regcache *regcache,
fetch_sveregs_from_thread (regcache);
else
fetch_fpregs_from_thread (regcache);
+
+ if (tdep->has_pauth ())
+ {
+ if (regno == AARCH64_PAUTH_DMASK_REGNUM (tdep->pauth_reg_base)
+ || regno == AARCH64_PAUTH_CMASK_REGNUM (tdep->pauth_reg_base))
+ fetch_pauth_masks_from_thread (regcache);
+ }
}
/* Implement the "store_registers" target_ops method. */