From: Luis Machado luis.machado@arm.com
This change makes the code more straightforward, since we can expect the order of the X registers to match that of the C registers. That way we don't have to deal with ordering issues.
It also simplifies the access to the dynamic C register numbers through the gdbarch tdep data structure.
gdb/ChangeLog:
YYYY-MM-DD Luis Machado luis.machado@arm.com
* aarch64-linux-nat.c (fetch_cregs_from_thread): Invert pcc/csp order. * aarch64-linux-tdep.c (aarch64_linux_sigframe_init): Likewise. * aarch64-tdep.c (aarch64_c_register_names): Likewise. (aarch64_analyze_prologue): Remove code to handle csp/pcc ordering issues. (aarch64_prologue_prev_register): Use new tdep fields. (aarch64_dwarf2_prev_register): Use new tdep fields and handle lr/clr. (aarch64_dwarf2_frame_init_reg): Use new tdep fields. (aarch64_gdbarch_init): Initialize the new tdep fields. * aarch64-tdep.h (gdbarch_tdep) <cap_reg_clr, cap_reg_csp> <cap_reg_pcc, cap_reg_rcsp>: New fields * features/aarch64-capability.c: Regenerate. * features/aarch64-capability.xml: Invert pcc/csp.
gdbserver/ChangeLog:
YYYY-MM-DD Luis Machado luis.machado@arm.com
* linux-aarch64-low.cc (aarch64_store_cregset): Invert pcc/csp.
YYYY-MM-DD Luis Machado luis.machado@arm.com --- gdb/aarch64-linux-nat.c | 2 +- gdb/aarch64-linux-tdep.c | 10 +--- gdb/aarch64-tdep.c | 86 ++++++++++++++--------------- gdb/aarch64-tdep.h | 8 +++ gdb/features/aarch64-capability.c | 2 +- gdb/features/aarch64-capability.xml | 2 +- gdbserver/linux-aarch64-low.cc | 2 +- 7 files changed, 58 insertions(+), 54 deletions(-)
diff --git a/gdb/aarch64-linux-nat.c b/gdb/aarch64-linux-nat.c index dc006de7f0..d1859c89da 100644 --- a/gdb/aarch64-linux-nat.c +++ b/gdb/aarch64-linux-nat.c @@ -489,8 +489,8 @@ fetch_cregs_from_thread (struct regcache *regcache) regcache->raw_supply (regno, &cregset.cregs[i]);
/* Fetch the other registers. */ - regcache->raw_supply (regno++, &cregset.pcc); regcache->raw_supply (regno++, &cregset.csp); + regcache->raw_supply (regno++, &cregset.pcc); regcache->raw_supply (regno++, &cregset.ddc); regcache->raw_supply (regno++, &cregset.ctpidr); regcache->raw_supply (regno++, &cregset.rcsp); diff --git a/gdb/aarch64-linux-tdep.c b/gdb/aarch64-linux-tdep.c index 398b429341..9c4d27610c 100644 --- a/gdb/aarch64-linux-tdep.c +++ b/gdb/aarch64-linux-tdep.c @@ -313,10 +313,6 @@ aarch64_linux_sigframe_init (const struct tramp_frame *self, offset + i * reg_size); }
- int pcc_regnum = tdep->cap_reg_base + 31; - int csp_regnum = tdep->cap_reg_base + 32; - int rcsp_regnum = tdep->cap_reg_base + 35; - if (aarch64_debug) { debug_printf ("aarch64: Reading PCC, CSP and RCSP registers " @@ -324,11 +320,11 @@ aarch64_linux_sigframe_init (const struct tramp_frame *self, paddress (gdbarch, offset + 31 * reg_size)); }
- trad_frame_set_reg_addr (this_cache, csp_regnum, + trad_frame_set_reg_addr (this_cache, tdep->cap_reg_csp, offset + 31 * reg_size); - trad_frame_set_reg_addr (this_cache, rcsp_regnum, + trad_frame_set_reg_addr (this_cache, tdep->cap_reg_rcsp, offset + 32 * reg_size); - trad_frame_set_reg_addr (this_cache, pcc_regnum, + trad_frame_set_reg_addr (this_cache, tdep->cap_reg_pcc, offset + 33 * reg_size);
section += size; diff --git a/gdb/aarch64-tdep.c b/gdb/aarch64-tdep.c index 16c85e3946..c8ca8ac736 100644 --- a/gdb/aarch64-tdep.c +++ b/gdb/aarch64-tdep.c @@ -272,8 +272,8 @@ static const char *const aarch64_c_register_names[] = "c0", "c1", "c2", "c3", "c4", "c5", "c6", "c7", "c8", "c9", "c10", "c11", "c12", "c13", "c14", "c15", "c16", "c17", "c18", "c19", "c20", "c21", "c22", "c23", - "c24", "c25", "c26", "c27", "c28", "c29", "c30", "pcc", - "csp", "ddc", "ctpidr", "rcsp", "rddc", "rctpidr", "cid", + "c24", "c25", "c26", "c27", "c28", "c29", "c30", "csp", + "pcc", "ddc", "ctpidr", "rcsp", "rddc", "rctpidr", "cid", "tag_map", "cctlr" };
@@ -865,8 +865,6 @@ aarch64_analyze_prologue (struct gdbarch *gdbarch, if (gdbarch_tdep (gdbarch)->has_capability ()) { struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch); - int pcc_regnum = tdep->cap_reg_base + 31; - int csp_regnum = tdep->cap_reg_base + 32;
/* Also save the C registers. */ for (i = 0; i < AARCH64_X_REGISTER_COUNT; i++) @@ -879,15 +877,7 @@ aarch64_analyze_prologue (struct gdbarch *gdbarch, debug_printf ("aarch64: %s Register C%d found at offset %s\n", __func__, i, core_addr_to_string_nz (offset));
- /* FIXME-Morello: We should really invert CSP/PCC to make them - match the order of the X registers. Then we wouldn't need - this conditional block. */ - if (i == AARCH64_SP_REGNUM) - cache->saved_regs[csp_regnum].addr = offset; - else if (i == AARCH64_PC_REGNUM) - cache->saved_regs[pcc_regnum].addr = offset; - else - cache->saved_regs[tdep->cap_reg_base + i].addr = offset; + cache->saved_regs[tdep->cap_reg_base + i].addr = offset; } } } @@ -1402,16 +1392,12 @@ aarch64_prologue_prev_register (struct frame_info *this_frame,
struct gdbarch_tdep *tdep = gdbarch_tdep (get_frame_arch (this_frame));
- int pcc_regnum = -1; - if (tdep->has_capability ()) - pcc_regnum = tdep->cap_reg_base + 31; - /* If we are asked to unwind the PC, then we need to return the LR instead. The prologue may save PC, but it will point into this frame's prologue, not the next frame's resume location.
We do the same for PCC and CLR. */ - if (prev_regnum == AARCH64_PC_REGNUM || prev_regnum == pcc_regnum) + if (prev_regnum == AARCH64_PC_REGNUM || prev_regnum == tdep->cap_reg_pcc) { CORE_ADDR lr; struct gdbarch *gdbarch = get_frame_arch (this_frame); @@ -1422,7 +1408,7 @@ aarch64_prologue_prev_register (struct frame_info *this_frame, if (prev_regnum == AARCH64_PC_REGNUM) lr_regnum = AARCH64_LR_REGNUM; else - lr_regnum = tdep->cap_reg_base + 30; + lr_regnum = tdep->cap_reg_clr;
struct value *lr_value = frame_unwind_register_value (this_frame, lr_regnum); @@ -1444,7 +1430,7 @@ aarch64_prologue_prev_register (struct frame_info *this_frame, = frame_unwind_got_constant (this_frame, prev_regnum, lr);
/* Copy the capability tag over, if it exists. */ - if (prev_regnum == pcc_regnum && value_tagged (lr_value)) + if (prev_regnum == tdep->cap_reg_pcc && value_tagged (lr_value)) { set_value_tagged (lr_value_adjusted, 1); set_value_tag (lr_value_adjusted, value_tag (lr_value)); @@ -1468,11 +1454,8 @@ aarch64_prologue_prev_register (struct frame_info *this_frame, | | | |<- SP +----------+ */ - int csp_regnum = -1; - if (tdep->has_capability ()) - csp_regnum = tdep->cap_reg_base + 32;
- if (prev_regnum == AARCH64_SP_REGNUM || prev_regnum == csp_regnum) + if (prev_regnum == AARCH64_SP_REGNUM || prev_regnum == tdep->cap_reg_csp) return frame_unwind_got_constant (this_frame, prev_regnum, cache->prev_sp);
@@ -1614,18 +1597,38 @@ aarch64_dwarf2_prev_register (struct frame_info *this_frame, { struct gdbarch *gdbarch = get_frame_arch (this_frame); struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch); - CORE_ADDR lr;
- int pcc_regnum = -1; - if (tdep->has_capability ()) - pcc_regnum = tdep->cap_reg_base + 31; - - if (regnum == AARCH64_PC_REGNUM || regnum == pcc_regnum) + if (regnum == AARCH64_PC_REGNUM || regnum == tdep->cap_reg_pcc) { - lr = frame_unwind_register_unsigned (this_frame, AARCH64_LR_REGNUM); + /* Fetch LR or CLR depending on the ABI. */ + int lr_regnum; + if (regnum == AARCH64_PC_REGNUM) + lr_regnum = AARCH64_LR_REGNUM; + else + lr_regnum = tdep->cap_reg_clr; + + struct value *lr_value = frame_unwind_register_value (this_frame, + lr_regnum); + + /* Extract only the bottom 8 bytes of CLR. This truncates the capability + to 8 bytes. For LR, this gets us the whole register. */ + CORE_ADDR lr = extract_unsigned_integer (value_contents_all (lr_value), 8, + gdbarch_byte_order (gdbarch)); + lr = aarch64_frame_unmask_lr (tdep, this_frame, lr); lr = gdbarch_addr_bits_remove (gdbarch, lr); - return frame_unwind_got_constant (this_frame, regnum, lr); + + struct value *lr_value_adjusted + = frame_unwind_got_constant (this_frame, regnum, lr); + + /* Copy the capability tag over, if it exists. */ + if (regnum == tdep->cap_reg_pcc && value_tagged (lr_value)) + { + set_value_tagged (lr_value_adjusted, 1); + set_value_tag (lr_value_adjusted, value_tag (lr_value)); + } + + return lr_value_adjusted; }
internal_error (__FILE__, __LINE__, _("Unexpected register %d"), regnum); @@ -1642,23 +1645,15 @@ aarch64_dwarf2_frame_init_reg (struct gdbarch *gdbarch, int regnum, struct frame_info *this_frame) { struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch); - int pcc_regnum = -1; - int csp_regnum = -1; - - if (tdep->has_capability ()) - { - pcc_regnum = tdep->cap_reg_base + 31; - csp_regnum = tdep->cap_reg_base + 32; - }
- if (regnum == AARCH64_PC_REGNUM || regnum == pcc_regnum) + if (regnum == AARCH64_PC_REGNUM || regnum == tdep->cap_reg_pcc) { reg->how = DWARF2_FRAME_REG_FN; reg->loc.fn = aarch64_dwarf2_prev_register; return; }
- if (regnum == AARCH64_SP_REGNUM || regnum == csp_regnum) + if (regnum == AARCH64_SP_REGNUM || regnum == tdep->cap_reg_csp) { reg->how = DWARF2_FRAME_REG_CFA; return; @@ -2593,7 +2588,7 @@ aarch64_dwarf_reg_to_regnum (struct gdbarch *gdbarch, int reg) return tdep->cap_reg_base + (reg - AARCH64_DWARF_C0);
if (reg == AARCH64_DWARF_CSP) - return tdep->cap_reg_base + 32; + return tdep->cap_reg_csp; }
return -1; @@ -4220,8 +4215,13 @@ aarch64_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches) tdep->pauth_ra_state_regnum = (feature_pauth == NULL) ? -1 : pauth_ra_state_offset + num_regs;
+ /* Initialize the capability register numbers. */ tdep->cap_reg_base = first_cap_regnum; tdep->cap_reg_last = last_cap_regnum; + tdep->cap_reg_clr = (first_cap_regnum == -1)? -1 : first_cap_regnum + 30; + tdep->cap_reg_csp = (first_cap_regnum == -1)? -1 : first_cap_regnum + 31; + tdep->cap_reg_pcc = (first_cap_regnum == -1)? -1 : first_cap_regnum + 32; + tdep->cap_reg_rcsp = (first_cap_regnum == -1)? -1 : first_cap_regnum + 35;
set_gdbarch_push_dummy_call (gdbarch, aarch64_push_dummy_call); set_gdbarch_frame_align (gdbarch, aarch64_frame_align); diff --git a/gdb/aarch64-tdep.h b/gdb/aarch64-tdep.h index a9d89c0d8b..f87322dffb 100644 --- a/gdb/aarch64-tdep.h +++ b/gdb/aarch64-tdep.h @@ -128,6 +128,14 @@ struct gdbarch_tdep int cap_reg_base; /* Last register from the capability set. */ int cap_reg_last; + /* CLR register number. */ + int cap_reg_clr; + /* CSP register numbers. */ + int cap_reg_csp; + /* PCC register number. */ + int cap_reg_pcc; + /* RCSP register number. */ + int cap_reg_rcsp;
/* Returns true if the target supports capabilities. */ bool has_capability () const diff --git a/gdb/features/aarch64-capability.c b/gdb/features/aarch64-capability.c index dfd78615ac..b6180e64b6 100644 --- a/gdb/features/aarch64-capability.c +++ b/gdb/features/aarch64-capability.c @@ -41,8 +41,8 @@ create_feature_aarch64_capability (struct target_desc *result, long regnum) tdesc_create_reg (feature, "c28", regnum++, 1, "general", 128, "uintcap"); tdesc_create_reg (feature, "c29", regnum++, 1, "general", 128, "uintcap"); tdesc_create_reg (feature, "c30", regnum++, 1, "general", 128, "uintcap"); - tdesc_create_reg (feature, "pcc", regnum++, 1, "general", 128, "uintcap"); tdesc_create_reg (feature, "csp", regnum++, 1, "general", 128, "uintcap"); + tdesc_create_reg (feature, "pcc", regnum++, 1, "general", 128, "uintcap"); tdesc_create_reg (feature, "ddc", regnum++, 1, "system", 128, "uintcap"); tdesc_create_reg (feature, "ctpidr", regnum++, 1, "system", 128, "uintcap"); tdesc_create_reg (feature, "rcsp", regnum++, 1, "system", 128, "uintcap"); diff --git a/gdb/features/aarch64-capability.xml b/gdb/features/aarch64-capability.xml index 33110cdbd8..ebe8aea733 100644 --- a/gdb/features/aarch64-capability.xml +++ b/gdb/features/aarch64-capability.xml @@ -38,8 +38,8 @@ <reg name="c28" bitsize="128" type="uintcap" group="general"/> <reg name="c29" bitsize="128" type="uintcap" group="general"/> <reg name="c30" bitsize="128" type="uintcap" group="general"/> - <reg name="pcc" bitsize="128" type="uintcap" group="general"/> <reg name="csp" bitsize="128" type="uintcap" group="general"/> + <reg name="pcc" bitsize="128" type="uintcap" group="general"/> <reg name="ddc" bitsize="128" type="uintcap" group="system"/> <reg name="ctpidr" bitsize="128" type="uintcap" group="system"/> <reg name="rcsp" bitsize="128" type="uintcap" group="general"/> diff --git a/gdbserver/linux-aarch64-low.cc b/gdbserver/linux-aarch64-low.cc index 940399d381..d034e783cb 100644 --- a/gdbserver/linux-aarch64-low.cc +++ b/gdbserver/linux-aarch64-low.cc @@ -279,8 +279,8 @@ aarch64_store_cregset (struct regcache *regcache, const void *buf) supply_register (regcache, regno, &cregset->cregs[i]);
/* Fetch the other registers. */ - supply_register (regcache, regno++, &cregset->pcc); supply_register (regcache, regno++, &cregset->csp); + supply_register (regcache, regno++, &cregset->pcc); supply_register (regcache, regno++, &cregset->ddc); supply_register (regcache, regno++, &cregset->ctpidr); supply_register (regcache, regno++, &cregset->rcsp);