mirror of
https://sourceware.org/git/binutils-gdb.git
synced 2025-01-19 14:34:07 +08:00
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.
This commit is contained in:
parent
ee4fbcfa26
commit
76bed0fd94
@ -1,3 +1,15 @@
|
||||
2019-03-22 Alan Hayward <alan.hayward@arm.com>
|
||||
Jiong Wang <jiong.wang@arm.com>
|
||||
|
||||
* 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.
|
||||
|
||||
2019-03-22 Alan Hayward <alan.hayward@arm.com>
|
||||
Jiong Wang <jiong.wang@arm.com>
|
||||
|
||||
|
@ -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. */
|
||||
|
@ -175,6 +175,14 @@ static const char *const aarch64_sve_register_names[] =
|
||||
"ffr", "vg"
|
||||
};
|
||||
|
||||
static const char *const aarch64_pauth_register_names[] =
|
||||
{
|
||||
/* Authentication mask for data pointer. */
|
||||
"pauth_dmask",
|
||||
/* Authentication mask for code pointer. */
|
||||
"pauth_cmask"
|
||||
};
|
||||
|
||||
/* AArch64 prologue cache structure. */
|
||||
struct aarch64_prologue_cache
|
||||
{
|
||||
@ -2936,6 +2944,21 @@ aarch64_add_reggroups (struct gdbarch *gdbarch)
|
||||
reggroup_add (gdbarch, restore_reggroup);
|
||||
}
|
||||
|
||||
/* Implement the "cannot_store_register" gdbarch method. */
|
||||
|
||||
static int
|
||||
aarch64_cannot_store_register (struct gdbarch *gdbarch, int regnum)
|
||||
{
|
||||
struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch);
|
||||
|
||||
if (!tdep->has_pauth ())
|
||||
return 0;
|
||||
|
||||
/* Pointer authentication registers are read-only. */
|
||||
return (regnum == AARCH64_PAUTH_DMASK_REGNUM (tdep->pauth_reg_base)
|
||||
|| regnum == AARCH64_PAUTH_CMASK_REGNUM (tdep->pauth_reg_base));
|
||||
}
|
||||
|
||||
/* Initialize the current architecture based on INFO. If possible,
|
||||
re-use an architecture from ARCHES, which is a list of
|
||||
architectures already created during this debugging session.
|
||||
@ -2956,8 +2979,10 @@ aarch64_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches)
|
||||
const struct tdesc_feature *feature_core;
|
||||
const struct tdesc_feature *feature_fpu;
|
||||
const struct tdesc_feature *feature_sve;
|
||||
const struct tdesc_feature *feature_pauth;
|
||||
int num_regs = 0;
|
||||
int num_pseudo_regs = 0;
|
||||
int first_pauth_regnum = -1;
|
||||
|
||||
/* Ensure we always have a target description. */
|
||||
if (!tdesc_has_registers (tdesc))
|
||||
@ -2967,6 +2992,7 @@ aarch64_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches)
|
||||
feature_core = tdesc_find_feature (tdesc, "org.gnu.gdb.aarch64.core");
|
||||
feature_fpu = tdesc_find_feature (tdesc, "org.gnu.gdb.aarch64.fpu");
|
||||
feature_sve = tdesc_find_feature (tdesc, "org.gnu.gdb.aarch64.sve");
|
||||
feature_pauth = tdesc_find_feature (tdesc, "org.gnu.gdb.aarch64.pauth");
|
||||
|
||||
if (feature_core == NULL)
|
||||
return NULL;
|
||||
@ -3021,6 +3047,21 @@ aarch64_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches)
|
||||
num_pseudo_regs += 32; /* add the Bn scalar register pseudos */
|
||||
}
|
||||
|
||||
/* Add the pauth registers. */
|
||||
if (feature_pauth != NULL)
|
||||
{
|
||||
first_pauth_regnum = num_regs;
|
||||
|
||||
/* Validate the descriptor provides the mandatory PAUTH registers and
|
||||
allocate their numbers. */
|
||||
for (i = 0; i < ARRAY_SIZE (aarch64_pauth_register_names); i++)
|
||||
valid_p &= tdesc_numbered_register (feature_pauth, tdesc_data,
|
||||
first_pauth_regnum + i,
|
||||
aarch64_pauth_register_names[i]);
|
||||
|
||||
num_regs += i;
|
||||
}
|
||||
|
||||
if (!valid_p)
|
||||
{
|
||||
tdesc_data_cleanup (tdesc_data);
|
||||
@ -3054,6 +3095,7 @@ aarch64_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches)
|
||||
tdep->jb_pc = -1; /* Longjump support not enabled by default. */
|
||||
tdep->jb_elt_size = 8;
|
||||
tdep->vq = aarch64_get_tdesc_vq (tdesc);
|
||||
tdep->pauth_reg_base = first_pauth_regnum;
|
||||
|
||||
set_gdbarch_push_dummy_call (gdbarch, aarch64_push_dummy_call);
|
||||
set_gdbarch_frame_align (gdbarch, aarch64_frame_align);
|
||||
@ -3084,6 +3126,7 @@ aarch64_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches)
|
||||
set_tdesc_pseudo_register_type (gdbarch, aarch64_pseudo_register_type);
|
||||
set_tdesc_pseudo_register_reggroup_p (gdbarch,
|
||||
aarch64_pseudo_register_reggroup_p);
|
||||
set_gdbarch_cannot_store_register (gdbarch, aarch64_cannot_store_register);
|
||||
|
||||
/* ABI */
|
||||
set_gdbarch_short_bit (gdbarch, 16);
|
||||
|
@ -87,6 +87,14 @@ struct gdbarch_tdep
|
||||
{
|
||||
return vq != 0;
|
||||
}
|
||||
|
||||
int pauth_reg_base;
|
||||
|
||||
/* Returns true if the target supports pauth. */
|
||||
bool has_pauth () const
|
||||
{
|
||||
return pauth_reg_base != -1;
|
||||
}
|
||||
};
|
||||
|
||||
const target_desc *aarch64_read_description (uint64_t vq, bool pauth_p);
|
||||
|
@ -66,6 +66,9 @@ enum aarch64_regnum
|
||||
#define AARCH64_B0_REGNUM (AARCH64_H0_REGNUM + 32)
|
||||
#define AARCH64_SVE_V0_REGNUM (AARCH64_B0_REGNUM + 32)
|
||||
|
||||
#define AARCH64_PAUTH_DMASK_REGNUM(pauth_reg_base) (pauth_reg_base)
|
||||
#define AARCH64_PAUTH_CMASK_REGNUM(pauth_reg_base) (pauth_reg_base + 1)
|
||||
|
||||
#define AARCH64_X_REGS_NUM 31
|
||||
#define AARCH64_V_REGS_NUM 32
|
||||
#define AARCH64_SVE_Z_REGS_NUM AARCH64_V_REGS_NUM
|
||||
|
Loading…
Reference in New Issue
Block a user