diff options
author | Alan Hayward <alan.hayward@arm.com> | 2019-03-22 10:31:02 +0000 |
---|---|---|
committer | Alan Hayward <alan.hayward@arm.com> | 2019-03-22 10:31:02 +0000 |
commit | 76bed0fd9493868889929ca9dcd32350c1d864be (patch) | |
tree | e799ee78fc4b6802da976a837deea5a6f44c63a2 /gdb/aarch64-linux-nat.c | |
parent | ee4fbcfa26eb4a2a3666f7c1cc31447c3cffa023 (diff) | |
download | binutils-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.c | 35 |
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. */ |