gdb/riscv: place unknown csrs into the correct register groups

Unknown riscv CSRs should not be in the 'general' group, but should be
in the system and csr register groups.

To see this in action connect to QEMU, this target advertises two
registers dscratch and mucounteren which are unknown to GDB (these are
legacy CSRs).  Before this commit these registers would show up in the
output of:

  (gdb) info registers
  ....
  dscratch       Could not fetch register "dscratch"; remote failure reply 'E14'
  mucounteren    Could not fetch register "mucounteren"; remote failure reply 'E14'

Ignore the errors, this is just a QEMU annoyance, it advertises these
CSRs, but doesn't actually let GDB read them.  These registers don't
show up in the output of either:

  (gdb) info registers csr
  (gdb) info registers system

After this commit this situation is reveresed, which makes more sense
to me.

gdb/ChangeLog:

	* riscv-tdep.c (riscv_is_unknown_csr): New function,
	implementation moved from riscv_register_reggroup_p.
	(riscv_register_reggroup_p): Update group handling for unknown
	CSRs.

gdb/testsuite/ChangeLog:

	* gdb.arch/riscv-tdesc-regs.exp (get_expected_result): New proc,
	update test to use this.
This commit is contained in:
Andrew Burgess
2020-11-24 18:08:25 +00:00
parent 7ddfb1a891
commit e450204220
4 changed files with 69 additions and 16 deletions

View File

@ -969,6 +969,18 @@ riscv_is_regnum_a_named_csr (int regnum)
}
}
/* Return true if REGNUM is an unknown CSR identified in
riscv_tdesc_unknown_reg for GDBARCH. */
static bool
riscv_is_unknown_csr (struct gdbarch *gdbarch, int regnum)
{
struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch);
return (regnum >= tdep->unknown_csrs_first_regnum
&& regnum < (tdep->unknown_csrs_first_regnum
+ tdep->unknown_csrs_count));
}
/* Implement the register_reggroup_p gdbarch method. Is REGNUM a member
of REGGROUP? */
@ -986,13 +998,21 @@ riscv_register_reggroup_p (struct gdbarch *gdbarch, int regnum,
{
/* Any extra registers from the CSR tdesc_feature (identified in
riscv_tdesc_unknown_reg) are removed from the save/restore groups
as some targets (QEMU) report CSRs which then can't be read. */
struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch);
if ((reggroup == restore_reggroup || reggroup == save_reggroup)
&& regnum >= tdep->unknown_csrs_first_regnum
&& regnum < (tdep->unknown_csrs_first_regnum
+ tdep->unknown_csrs_count))
return 0;
as some targets (QEMU) report CSRs which then can't be read and
having unreadable registers in the save/restore group breaks
things like inferior calls.
The unknown CSRs are also removed from the general group, and
added into both the csr and system group. This is inline with the
known CSRs (see below). */
if (riscv_is_unknown_csr (gdbarch, regnum))
{
if (reggroup == restore_reggroup || reggroup == save_reggroup
|| reggroup == general_reggroup)
return 0;
else if (reggroup == system_reggroup || reggroup == csr_reggroup)
return 1;
}
/* This is some other unknown register from the target description.
In this case we trust whatever the target description says about