Skip to content

Commit 34dcc7c

Browse files
committed
AArch64: Add pauth DWARF registers
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.
1 parent 1ef53e6 commit 34dcc7c

File tree

3 files changed

+79
-33
lines changed

3 files changed

+79
-33
lines changed

gdb/ChangeLog

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,17 @@
1+
2019-03-22 Alan Hayward <alan.hayward@arm.com>
2+
Jiong Wang <jiong.wang@arm.com>
3+
4+
* aarch64-tdep.c (aarch64_dwarf_reg_to_regnum): Check for pauth
5+
registers.
6+
(aarch64_pseudo_register_name): Likewise.
7+
(aarch64_pseudo_register_type): Likewise.
8+
(aarch64_pseudo_register_reggroup_p): Likewise.
9+
(aarch64_gdbarch_init): Add pauth registers.
10+
* aarch64-tdep.h (AARCH64_DWARF_PAUTH_RA_STATE): New define.
11+
(AARCH64_DWARF_PAUTH_DMASK): Likewise.
12+
(AARCH64_DWARF_PAUTH_CMASK): Likewise.
13+
(struct gdbarch_tdep): Add regnum for ra_state.
14+
115
2019-03-22 Alan Hayward <alan.hayward@arm.com>
216
Jiong Wang <jiong.wang@arm.com>
317

gdb/aarch64-tdep.c

Lines changed: 61 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -1839,6 +1839,8 @@ aarch64_vnv_type (struct gdbarch *gdbarch)
18391839
static int
18401840
aarch64_dwarf_reg_to_regnum (struct gdbarch *gdbarch, int reg)
18411841
{
1842+
struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch);
1843+
18421844
if (reg >= AARCH64_DWARF_X0 && reg <= AARCH64_DWARF_X0 + 30)
18431845
return AARCH64_X0_REGNUM + reg - AARCH64_DWARF_X0;
18441846

@@ -1860,6 +1862,15 @@ aarch64_dwarf_reg_to_regnum (struct gdbarch *gdbarch, int reg)
18601862
if (reg >= AARCH64_DWARF_SVE_Z0 && reg <= AARCH64_DWARF_SVE_Z0 + 15)
18611863
return AARCH64_SVE_Z0_REGNUM + reg - AARCH64_DWARF_SVE_Z0;
18621864

1865+
if (tdep->has_pauth ())
1866+
{
1867+
if (reg >= AARCH64_DWARF_PAUTH_DMASK && reg <= AARCH64_DWARF_PAUTH_CMASK)
1868+
return tdep->pauth_reg_base + reg - AARCH64_DWARF_PAUTH_DMASK;
1869+
1870+
if (reg == AARCH64_DWARF_PAUTH_RA_STATE)
1871+
return tdep->pauth_ra_state_regnum;
1872+
}
1873+
18631874
return -1;
18641875
}
18651876

@@ -2215,22 +2226,22 @@ aarch64_pseudo_register_name (struct gdbarch *gdbarch, int regnum)
22152226
"b28", "b29", "b30", "b31",
22162227
};
22172228

2218-
regnum -= gdbarch_num_regs (gdbarch);
2229+
int p_regnum = regnum - gdbarch_num_regs (gdbarch);
22192230

2220-
if (regnum >= AARCH64_Q0_REGNUM && regnum < AARCH64_Q0_REGNUM + 32)
2221-
return q_name[regnum - AARCH64_Q0_REGNUM];
2231+
if (p_regnum >= AARCH64_Q0_REGNUM && p_regnum < AARCH64_Q0_REGNUM + 32)
2232+
return q_name[p_regnum - AARCH64_Q0_REGNUM];
22222233

2223-
if (regnum >= AARCH64_D0_REGNUM && regnum < AARCH64_D0_REGNUM + 32)
2224-
return d_name[regnum - AARCH64_D0_REGNUM];
2234+
if (p_regnum >= AARCH64_D0_REGNUM && p_regnum < AARCH64_D0_REGNUM + 32)
2235+
return d_name[p_regnum - AARCH64_D0_REGNUM];
22252236

2226-
if (regnum >= AARCH64_S0_REGNUM && regnum < AARCH64_S0_REGNUM + 32)
2227-
return s_name[regnum - AARCH64_S0_REGNUM];
2237+
if (p_regnum >= AARCH64_S0_REGNUM && p_regnum < AARCH64_S0_REGNUM + 32)
2238+
return s_name[p_regnum - AARCH64_S0_REGNUM];
22282239

2229-
if (regnum >= AARCH64_H0_REGNUM && regnum < AARCH64_H0_REGNUM + 32)
2230-
return h_name[regnum - AARCH64_H0_REGNUM];
2240+
if (p_regnum >= AARCH64_H0_REGNUM && p_regnum < AARCH64_H0_REGNUM + 32)
2241+
return h_name[p_regnum - AARCH64_H0_REGNUM];
22312242

2232-
if (regnum >= AARCH64_B0_REGNUM && regnum < AARCH64_B0_REGNUM + 32)
2233-
return b_name[regnum - AARCH64_B0_REGNUM];
2243+
if (p_regnum >= AARCH64_B0_REGNUM && p_regnum < AARCH64_B0_REGNUM + 32)
2244+
return b_name[p_regnum - AARCH64_B0_REGNUM];
22342245

22352246
if (tdep->has_sve ())
22362247
{
@@ -2246,14 +2257,20 @@ aarch64_pseudo_register_name (struct gdbarch *gdbarch, int regnum)
22462257
"v28", "v29", "v30", "v31",
22472258
};
22482259

2249-
if (regnum >= AARCH64_SVE_V0_REGNUM
2250-
&& regnum < AARCH64_SVE_V0_REGNUM + AARCH64_V_REGS_NUM)
2251-
return sve_v_name[regnum - AARCH64_SVE_V0_REGNUM];
2260+
if (p_regnum >= AARCH64_SVE_V0_REGNUM
2261+
&& p_regnum < AARCH64_SVE_V0_REGNUM + AARCH64_V_REGS_NUM)
2262+
return sve_v_name[p_regnum - AARCH64_SVE_V0_REGNUM];
22522263
}
22532264

2265+
/* RA_STATE is used for unwinding only. Do not assign it a name - this
2266+
prevents it from being read by methods such as
2267+
mi_cmd_trace_frame_collected. */
2268+
if (tdep->has_pauth () && regnum == tdep->pauth_ra_state_regnum)
2269+
return "";
2270+
22542271
internal_error (__FILE__, __LINE__,
22552272
_("aarch64_pseudo_register_name: bad register number %d"),
2256-
regnum);
2273+
p_regnum);
22572274
}
22582275

22592276
/* Implement the "pseudo_register_type" tdesc_arch_data method. */
@@ -2263,30 +2280,33 @@ aarch64_pseudo_register_type (struct gdbarch *gdbarch, int regnum)
22632280
{
22642281
struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch);
22652282

2266-
regnum -= gdbarch_num_regs (gdbarch);
2283+
int p_regnum = regnum - gdbarch_num_regs (gdbarch);
22672284

2268-
if (regnum >= AARCH64_Q0_REGNUM && regnum < AARCH64_Q0_REGNUM + 32)
2285+
if (p_regnum >= AARCH64_Q0_REGNUM && p_regnum < AARCH64_Q0_REGNUM + 32)
22692286
return aarch64_vnq_type (gdbarch);
22702287

2271-
if (regnum >= AARCH64_D0_REGNUM && regnum < AARCH64_D0_REGNUM + 32)
2288+
if (p_regnum >= AARCH64_D0_REGNUM && p_regnum < AARCH64_D0_REGNUM + 32)
22722289
return aarch64_vnd_type (gdbarch);
22732290

2274-
if (regnum >= AARCH64_S0_REGNUM && regnum < AARCH64_S0_REGNUM + 32)
2291+
if (p_regnum >= AARCH64_S0_REGNUM && p_regnum < AARCH64_S0_REGNUM + 32)
22752292
return aarch64_vns_type (gdbarch);
22762293

2277-
if (regnum >= AARCH64_H0_REGNUM && regnum < AARCH64_H0_REGNUM + 32)
2294+
if (p_regnum >= AARCH64_H0_REGNUM && p_regnum < AARCH64_H0_REGNUM + 32)
22782295
return aarch64_vnh_type (gdbarch);
22792296

2280-
if (regnum >= AARCH64_B0_REGNUM && regnum < AARCH64_B0_REGNUM + 32)
2297+
if (p_regnum >= AARCH64_B0_REGNUM && p_regnum < AARCH64_B0_REGNUM + 32)
22812298
return aarch64_vnb_type (gdbarch);
22822299

2283-
if (tdep->has_sve () && regnum >= AARCH64_SVE_V0_REGNUM
2284-
&& regnum < AARCH64_SVE_V0_REGNUM + AARCH64_V_REGS_NUM)
2300+
if (tdep->has_sve () && p_regnum >= AARCH64_SVE_V0_REGNUM
2301+
&& p_regnum < AARCH64_SVE_V0_REGNUM + AARCH64_V_REGS_NUM)
22852302
return aarch64_vnv_type (gdbarch);
22862303

2304+
if (tdep->has_pauth () && regnum == tdep->pauth_ra_state_regnum)
2305+
return builtin_type (gdbarch)->builtin_uint64;
2306+
22872307
internal_error (__FILE__, __LINE__,
22882308
_("aarch64_pseudo_register_type: bad register number %d"),
2289-
regnum);
2309+
p_regnum);
22902310
}
22912311

22922312
/* Implement the "pseudo_register_reggroup_p" tdesc_arch_data method. */
@@ -2297,23 +2317,26 @@ aarch64_pseudo_register_reggroup_p (struct gdbarch *gdbarch, int regnum,
22972317
{
22982318
struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch);
22992319

2300-
regnum -= gdbarch_num_regs (gdbarch);
2320+
int p_regnum = regnum - gdbarch_num_regs (gdbarch);
23012321

2302-
if (regnum >= AARCH64_Q0_REGNUM && regnum < AARCH64_Q0_REGNUM + 32)
2322+
if (p_regnum >= AARCH64_Q0_REGNUM && p_regnum < AARCH64_Q0_REGNUM + 32)
23032323
return group == all_reggroup || group == vector_reggroup;
2304-
else if (regnum >= AARCH64_D0_REGNUM && regnum < AARCH64_D0_REGNUM + 32)
2324+
else if (p_regnum >= AARCH64_D0_REGNUM && p_regnum < AARCH64_D0_REGNUM + 32)
23052325
return (group == all_reggroup || group == vector_reggroup
23062326
|| group == float_reggroup);
2307-
else if (regnum >= AARCH64_S0_REGNUM && regnum < AARCH64_S0_REGNUM + 32)
2327+
else if (p_regnum >= AARCH64_S0_REGNUM && p_regnum < AARCH64_S0_REGNUM + 32)
23082328
return (group == all_reggroup || group == vector_reggroup
23092329
|| group == float_reggroup);
2310-
else if (regnum >= AARCH64_H0_REGNUM && regnum < AARCH64_H0_REGNUM + 32)
2330+
else if (p_regnum >= AARCH64_H0_REGNUM && p_regnum < AARCH64_H0_REGNUM + 32)
23112331
return group == all_reggroup || group == vector_reggroup;
2312-
else if (regnum >= AARCH64_B0_REGNUM && regnum < AARCH64_B0_REGNUM + 32)
2332+
else if (p_regnum >= AARCH64_B0_REGNUM && p_regnum < AARCH64_B0_REGNUM + 32)
23132333
return group == all_reggroup || group == vector_reggroup;
2314-
else if (tdep->has_sve () && regnum >= AARCH64_SVE_V0_REGNUM
2315-
&& regnum < AARCH64_SVE_V0_REGNUM + AARCH64_V_REGS_NUM)
2334+
else if (tdep->has_sve () && p_regnum >= AARCH64_SVE_V0_REGNUM
2335+
&& p_regnum < AARCH64_SVE_V0_REGNUM + AARCH64_V_REGS_NUM)
23162336
return group == all_reggroup || group == vector_reggroup;
2337+
/* RA_STATE is used for unwinding only. Do not assign it to any groups. */
2338+
if (tdep->has_pauth () && regnum == tdep->pauth_ra_state_regnum)
2339+
return 0;
23172340

23182341
return group == all_reggroup;
23192342
}
@@ -2983,6 +3006,7 @@ aarch64_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches)
29833006
int num_regs = 0;
29843007
int num_pseudo_regs = 0;
29853008
int first_pauth_regnum = -1;
3009+
int pauth_ra_state_offset = -1;
29863010

29873011
/* Ensure we always have a target description. */
29883012
if (!tdesc_has_registers (tdesc))
@@ -3051,7 +3075,7 @@ aarch64_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches)
30513075
if (feature_pauth != NULL)
30523076
{
30533077
first_pauth_regnum = num_regs;
3054-
3078+
pauth_ra_state_offset = num_pseudo_regs;
30553079
/* Validate the descriptor provides the mandatory PAUTH registers and
30563080
allocate their numbers. */
30573081
for (i = 0; i < ARRAY_SIZE (aarch64_pauth_register_names); i++)
@@ -3060,6 +3084,7 @@ aarch64_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches)
30603084
aarch64_pauth_register_names[i]);
30613085

30623086
num_regs += i;
3087+
num_pseudo_regs += 1; /* Count RA_STATE pseudo register. */
30633088
}
30643089

30653090
if (!valid_p)
@@ -3096,6 +3121,9 @@ aarch64_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches)
30963121
tdep->jb_elt_size = 8;
30973122
tdep->vq = aarch64_get_tdesc_vq (tdesc);
30983123
tdep->pauth_reg_base = first_pauth_regnum;
3124+
tdep->pauth_ra_state_regnum = (feature_pauth == NULL) ? -1
3125+
: pauth_ra_state_offset + num_regs;
3126+
30993127

31003128
set_gdbarch_push_dummy_call (gdbarch, aarch64_push_dummy_call);
31013129
set_gdbarch_frame_align (gdbarch, aarch64_frame_align);

gdb/aarch64-tdep.h

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,9 @@ struct regset;
3131
/* AArch64 Dwarf register numbering. */
3232
#define AARCH64_DWARF_X0 0
3333
#define AARCH64_DWARF_SP 31
34+
#define AARCH64_DWARF_PAUTH_RA_STATE 34
35+
#define AARCH64_DWARF_PAUTH_DMASK 35
36+
#define AARCH64_DWARF_PAUTH_CMASK 36
3437
#define AARCH64_DWARF_V0 64
3538
#define AARCH64_DWARF_SVE_VG 46
3639
#define AARCH64_DWARF_SVE_FFR 47
@@ -89,6 +92,7 @@ struct gdbarch_tdep
8992
}
9093

9194
int pauth_reg_base;
95+
int pauth_ra_state_regnum;
9296

9397
/* Returns true if the target supports pauth. */
9498
bool has_pauth () const

0 commit comments

Comments
 (0)