Map the pauth registers to DWARF.
Add a new pseudo register ra_state and also map this to DWARF. This register
is hidden from the user - prevent it from being read or written to. It will
be used for the unmangling of addresses.
gdb/ChangeLog:
* aarch64-tdep.c (aarch64_dwarf_reg_to_regnum): Check for pauth
registers.
(aarch64_pseudo_register_name): Likewise.
(aarch64_pseudo_register_type): Likewise.
(aarch64_pseudo_register_reggroup_p): Likewise.
(aarch64_gdbarch_init): Add pauth registers.
* aarch64-tdep.h (AARCH64_DWARF_PAUTH_RA_STATE): New define.
(AARCH64_DWARF_PAUTH_DMASK): Likewise.
(AARCH64_DWARF_PAUTH_CMASK): Likewise.
(struct gdbarch_tdep): Add regnum for ra_state.
+2019-03-22 Alan Hayward <alan.hayward@arm.com>
+ Jiong Wang <jiong.wang@arm.com>
+
+ * aarch64-tdep.c (aarch64_dwarf_reg_to_regnum): Check for pauth
+ registers.
+ (aarch64_pseudo_register_name): Likewise.
+ (aarch64_pseudo_register_type): Likewise.
+ (aarch64_pseudo_register_reggroup_p): Likewise.
+ (aarch64_gdbarch_init): Add pauth registers.
+ * aarch64-tdep.h (AARCH64_DWARF_PAUTH_RA_STATE): New define.
+ (AARCH64_DWARF_PAUTH_DMASK): Likewise.
+ (AARCH64_DWARF_PAUTH_CMASK): Likewise.
+ (struct gdbarch_tdep): Add regnum for ra_state.
+
2019-03-22 Alan Hayward <alan.hayward@arm.com>
Jiong Wang <jiong.wang@arm.com>
2019-03-22 Alan Hayward <alan.hayward@arm.com>
Jiong Wang <jiong.wang@arm.com>
static int
aarch64_dwarf_reg_to_regnum (struct gdbarch *gdbarch, int reg)
{
static int
aarch64_dwarf_reg_to_regnum (struct gdbarch *gdbarch, int reg)
{
+ struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch);
+
if (reg >= AARCH64_DWARF_X0 && reg <= AARCH64_DWARF_X0 + 30)
return AARCH64_X0_REGNUM + reg - AARCH64_DWARF_X0;
if (reg >= AARCH64_DWARF_X0 && reg <= AARCH64_DWARF_X0 + 30)
return AARCH64_X0_REGNUM + reg - AARCH64_DWARF_X0;
if (reg >= AARCH64_DWARF_SVE_Z0 && reg <= AARCH64_DWARF_SVE_Z0 + 15)
return AARCH64_SVE_Z0_REGNUM + reg - AARCH64_DWARF_SVE_Z0;
if (reg >= AARCH64_DWARF_SVE_Z0 && reg <= AARCH64_DWARF_SVE_Z0 + 15)
return AARCH64_SVE_Z0_REGNUM + reg - AARCH64_DWARF_SVE_Z0;
+ if (tdep->has_pauth ())
+ {
+ if (reg >= AARCH64_DWARF_PAUTH_DMASK && reg <= AARCH64_DWARF_PAUTH_CMASK)
+ return tdep->pauth_reg_base + reg - AARCH64_DWARF_PAUTH_DMASK;
+
+ if (reg == AARCH64_DWARF_PAUTH_RA_STATE)
+ return tdep->pauth_ra_state_regnum;
+ }
+
"b28", "b29", "b30", "b31",
};
"b28", "b29", "b30", "b31",
};
- regnum -= gdbarch_num_regs (gdbarch);
+ int p_regnum = regnum - gdbarch_num_regs (gdbarch);
- if (regnum >= AARCH64_Q0_REGNUM && regnum < AARCH64_Q0_REGNUM + 32)
- return q_name[regnum - AARCH64_Q0_REGNUM];
+ if (p_regnum >= AARCH64_Q0_REGNUM && p_regnum < AARCH64_Q0_REGNUM + 32)
+ return q_name[p_regnum - AARCH64_Q0_REGNUM];
- if (regnum >= AARCH64_D0_REGNUM && regnum < AARCH64_D0_REGNUM + 32)
- return d_name[regnum - AARCH64_D0_REGNUM];
+ if (p_regnum >= AARCH64_D0_REGNUM && p_regnum < AARCH64_D0_REGNUM + 32)
+ return d_name[p_regnum - AARCH64_D0_REGNUM];
- if (regnum >= AARCH64_S0_REGNUM && regnum < AARCH64_S0_REGNUM + 32)
- return s_name[regnum - AARCH64_S0_REGNUM];
+ if (p_regnum >= AARCH64_S0_REGNUM && p_regnum < AARCH64_S0_REGNUM + 32)
+ return s_name[p_regnum - AARCH64_S0_REGNUM];
- if (regnum >= AARCH64_H0_REGNUM && regnum < AARCH64_H0_REGNUM + 32)
- return h_name[regnum - AARCH64_H0_REGNUM];
+ if (p_regnum >= AARCH64_H0_REGNUM && p_regnum < AARCH64_H0_REGNUM + 32)
+ return h_name[p_regnum - AARCH64_H0_REGNUM];
- if (regnum >= AARCH64_B0_REGNUM && regnum < AARCH64_B0_REGNUM + 32)
- return b_name[regnum - AARCH64_B0_REGNUM];
+ if (p_regnum >= AARCH64_B0_REGNUM && p_regnum < AARCH64_B0_REGNUM + 32)
+ return b_name[p_regnum - AARCH64_B0_REGNUM];
"v28", "v29", "v30", "v31",
};
"v28", "v29", "v30", "v31",
};
- if (regnum >= AARCH64_SVE_V0_REGNUM
- && regnum < AARCH64_SVE_V0_REGNUM + AARCH64_V_REGS_NUM)
- return sve_v_name[regnum - AARCH64_SVE_V0_REGNUM];
+ if (p_regnum >= AARCH64_SVE_V0_REGNUM
+ && p_regnum < AARCH64_SVE_V0_REGNUM + AARCH64_V_REGS_NUM)
+ return sve_v_name[p_regnum - AARCH64_SVE_V0_REGNUM];
+ /* RA_STATE is used for unwinding only. Do not assign it a name - this
+ prevents it from being read by methods such as
+ mi_cmd_trace_frame_collected. */
+ if (tdep->has_pauth () && regnum == tdep->pauth_ra_state_regnum)
+ return "";
+
internal_error (__FILE__, __LINE__,
_("aarch64_pseudo_register_name: bad register number %d"),
internal_error (__FILE__, __LINE__,
_("aarch64_pseudo_register_name: bad register number %d"),
}
/* Implement the "pseudo_register_type" tdesc_arch_data method. */
}
/* Implement the "pseudo_register_type" tdesc_arch_data method. */
{
struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch);
{
struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch);
- regnum -= gdbarch_num_regs (gdbarch);
+ int p_regnum = regnum - gdbarch_num_regs (gdbarch);
- if (regnum >= AARCH64_Q0_REGNUM && regnum < AARCH64_Q0_REGNUM + 32)
+ if (p_regnum >= AARCH64_Q0_REGNUM && p_regnum < AARCH64_Q0_REGNUM + 32)
return aarch64_vnq_type (gdbarch);
return aarch64_vnq_type (gdbarch);
- if (regnum >= AARCH64_D0_REGNUM && regnum < AARCH64_D0_REGNUM + 32)
+ if (p_regnum >= AARCH64_D0_REGNUM && p_regnum < AARCH64_D0_REGNUM + 32)
return aarch64_vnd_type (gdbarch);
return aarch64_vnd_type (gdbarch);
- if (regnum >= AARCH64_S0_REGNUM && regnum < AARCH64_S0_REGNUM + 32)
+ if (p_regnum >= AARCH64_S0_REGNUM && p_regnum < AARCH64_S0_REGNUM + 32)
return aarch64_vns_type (gdbarch);
return aarch64_vns_type (gdbarch);
- if (regnum >= AARCH64_H0_REGNUM && regnum < AARCH64_H0_REGNUM + 32)
+ if (p_regnum >= AARCH64_H0_REGNUM && p_regnum < AARCH64_H0_REGNUM + 32)
return aarch64_vnh_type (gdbarch);
return aarch64_vnh_type (gdbarch);
- if (regnum >= AARCH64_B0_REGNUM && regnum < AARCH64_B0_REGNUM + 32)
+ if (p_regnum >= AARCH64_B0_REGNUM && p_regnum < AARCH64_B0_REGNUM + 32)
return aarch64_vnb_type (gdbarch);
return aarch64_vnb_type (gdbarch);
- if (tdep->has_sve () && regnum >= AARCH64_SVE_V0_REGNUM
- && regnum < AARCH64_SVE_V0_REGNUM + AARCH64_V_REGS_NUM)
+ if (tdep->has_sve () && p_regnum >= AARCH64_SVE_V0_REGNUM
+ && p_regnum < AARCH64_SVE_V0_REGNUM + AARCH64_V_REGS_NUM)
return aarch64_vnv_type (gdbarch);
return aarch64_vnv_type (gdbarch);
+ if (tdep->has_pauth () && regnum == tdep->pauth_ra_state_regnum)
+ return builtin_type (gdbarch)->builtin_uint64;
+
internal_error (__FILE__, __LINE__,
_("aarch64_pseudo_register_type: bad register number %d"),
internal_error (__FILE__, __LINE__,
_("aarch64_pseudo_register_type: bad register number %d"),
}
/* Implement the "pseudo_register_reggroup_p" tdesc_arch_data method. */
}
/* Implement the "pseudo_register_reggroup_p" tdesc_arch_data method. */
{
struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch);
{
struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch);
- regnum -= gdbarch_num_regs (gdbarch);
+ int p_regnum = regnum - gdbarch_num_regs (gdbarch);
- if (regnum >= AARCH64_Q0_REGNUM && regnum < AARCH64_Q0_REGNUM + 32)
+ if (p_regnum >= AARCH64_Q0_REGNUM && p_regnum < AARCH64_Q0_REGNUM + 32)
return group == all_reggroup || group == vector_reggroup;
return group == all_reggroup || group == vector_reggroup;
- else if (regnum >= AARCH64_D0_REGNUM && regnum < AARCH64_D0_REGNUM + 32)
+ else if (p_regnum >= AARCH64_D0_REGNUM && p_regnum < AARCH64_D0_REGNUM + 32)
return (group == all_reggroup || group == vector_reggroup
|| group == float_reggroup);
return (group == all_reggroup || group == vector_reggroup
|| group == float_reggroup);
- else if (regnum >= AARCH64_S0_REGNUM && regnum < AARCH64_S0_REGNUM + 32)
+ else if (p_regnum >= AARCH64_S0_REGNUM && p_regnum < AARCH64_S0_REGNUM + 32)
return (group == all_reggroup || group == vector_reggroup
|| group == float_reggroup);
return (group == all_reggroup || group == vector_reggroup
|| group == float_reggroup);
- else if (regnum >= AARCH64_H0_REGNUM && regnum < AARCH64_H0_REGNUM + 32)
+ else if (p_regnum >= AARCH64_H0_REGNUM && p_regnum < AARCH64_H0_REGNUM + 32)
return group == all_reggroup || group == vector_reggroup;
return group == all_reggroup || group == vector_reggroup;
- else if (regnum >= AARCH64_B0_REGNUM && regnum < AARCH64_B0_REGNUM + 32)
+ else if (p_regnum >= AARCH64_B0_REGNUM && p_regnum < AARCH64_B0_REGNUM + 32)
return group == all_reggroup || group == vector_reggroup;
return group == all_reggroup || group == vector_reggroup;
- else if (tdep->has_sve () && regnum >= AARCH64_SVE_V0_REGNUM
- && regnum < AARCH64_SVE_V0_REGNUM + AARCH64_V_REGS_NUM)
+ else if (tdep->has_sve () && p_regnum >= AARCH64_SVE_V0_REGNUM
+ && p_regnum < AARCH64_SVE_V0_REGNUM + AARCH64_V_REGS_NUM)
return group == all_reggroup || group == vector_reggroup;
return group == all_reggroup || group == vector_reggroup;
+ /* RA_STATE is used for unwinding only. Do not assign it to any groups. */
+ if (tdep->has_pauth () && regnum == tdep->pauth_ra_state_regnum)
+ return 0;
return group == all_reggroup;
}
return group == all_reggroup;
}
int num_regs = 0;
int num_pseudo_regs = 0;
int first_pauth_regnum = -1;
int num_regs = 0;
int num_pseudo_regs = 0;
int first_pauth_regnum = -1;
+ int pauth_ra_state_offset = -1;
/* Ensure we always have a target description. */
if (!tdesc_has_registers (tdesc))
/* Ensure we always have a target description. */
if (!tdesc_has_registers (tdesc))
if (feature_pauth != NULL)
{
first_pauth_regnum = num_regs;
if (feature_pauth != NULL)
{
first_pauth_regnum = num_regs;
+ pauth_ra_state_offset = num_pseudo_regs;
/* Validate the descriptor provides the mandatory PAUTH registers and
allocate their numbers. */
for (i = 0; i < ARRAY_SIZE (aarch64_pauth_register_names); i++)
/* Validate the descriptor provides the mandatory PAUTH registers and
allocate their numbers. */
for (i = 0; i < ARRAY_SIZE (aarch64_pauth_register_names); i++)
aarch64_pauth_register_names[i]);
num_regs += i;
aarch64_pauth_register_names[i]);
num_regs += i;
+ num_pseudo_regs += 1; /* Count RA_STATE pseudo register. */
tdep->jb_elt_size = 8;
tdep->vq = aarch64_get_tdesc_vq (tdesc);
tdep->pauth_reg_base = first_pauth_regnum;
tdep->jb_elt_size = 8;
tdep->vq = aarch64_get_tdesc_vq (tdesc);
tdep->pauth_reg_base = first_pauth_regnum;
+ tdep->pauth_ra_state_regnum = (feature_pauth == NULL) ? -1
+ : pauth_ra_state_offset + num_regs;
+
set_gdbarch_push_dummy_call (gdbarch, aarch64_push_dummy_call);
set_gdbarch_frame_align (gdbarch, aarch64_frame_align);
set_gdbarch_push_dummy_call (gdbarch, aarch64_push_dummy_call);
set_gdbarch_frame_align (gdbarch, aarch64_frame_align);
/* AArch64 Dwarf register numbering. */
#define AARCH64_DWARF_X0 0
#define AARCH64_DWARF_SP 31
/* AArch64 Dwarf register numbering. */
#define AARCH64_DWARF_X0 0
#define AARCH64_DWARF_SP 31
+#define AARCH64_DWARF_PAUTH_RA_STATE 34
+#define AARCH64_DWARF_PAUTH_DMASK 35
+#define AARCH64_DWARF_PAUTH_CMASK 36
#define AARCH64_DWARF_V0 64
#define AARCH64_DWARF_SVE_VG 46
#define AARCH64_DWARF_SVE_FFR 47
#define AARCH64_DWARF_V0 64
#define AARCH64_DWARF_SVE_VG 46
#define AARCH64_DWARF_SVE_FFR 47
+ int pauth_ra_state_regnum;
/* Returns true if the target supports pauth. */
bool has_pauth () const
/* Returns true if the target supports pauth. */
bool has_pauth () const