• R/O
  • HTTP
  • SSH
  • HTTPS

Commit

Tags
No Tags

Frequently used words (click to add to your profile)

javac++androidlinuxc#windowsobjective-ccocoa誰得qtpythonphprubygameguibathyscaphec計画中(planning stage)翻訳omegatframeworktwitterdomtestvb.netdirectxゲームエンジンbtronarduinopreviewer

GNU Binutils with patches for OS216


Commit MetaInfo

Revision2e52d038246520ee8f8d8344da18303154a421a6 (tree)
Time2020-06-26 02:07:32
AuthorAndrew Burgess <andrew.burgess@embe...>
CommiterAndrew Burgess

Log Message

gdb/riscv: Record information about unknown tdesc registers

Making use of the previous commit, record information about unknown
registers in the target description, and use this to resolve two
issues.

1. Some targets (QEMU) are reporting three register fflags, frm, and

fcsr, twice, once in the FPU feature, and once in the CSR feature.
GDB does create two registers with identical names, but this
is (sort of) fine, we only ever use the first one, and as both
registers access the same target state things basically work OK.
The only real problem is that the register names show up twice in
'info registers all' output.
In this commit we spot the duplicates of these registers and then
return NULL when asked for the name of these registers. This
causes GDB to hide these registers from the user, fixing this
problem.

2. Some targets (QEMU) advertise CSRs that GDB then can't read. The

problem is these targets also say these CSRs are part of the
save/restore register groups.
This means that before an inferior call GDB tries to save all of
these CSRs, and a failure to read one causes the inferior call to
be abandoned.
We already work around this issue to some degree, known CSRs are
removed from the save/restore groups, despite what the target might
    1. However, any unknown CSRs are (currently) not removed in this
      way.
After this commit we keep a log of the register numbers for all
unknown CSRs, then when asked about the register groups, we
override the group information for unknown CSRs, removing them from
the save and restore groups.

gdb/ChangeLog:

* riscv-tdep.c (riscv_register_name): Return NULL for duplicate
fflags, frm, and fcsr registers.
(riscv_register_reggroup_p): Remove unknown CSRs from save and
restore groups.
(riscv_tdesc_unknown_reg): New function.
(riscv_gdbarch_init): Pass riscv_tdesc_unknown_reg to
tdesc_use_registers.
* riscv-tdep.h (struct gdbarch_tdep): Add
unknown_csrs_first_regnum, unknown_csrs_count,
duplicate_fflags_regnum, duplicate_frm_regnum, and
duplicate_fcsr_regnum fields.

gdb/testsuite/ChangeLog:

* gdb.arch/riscv-tdesc-regs.exp: Extend test case.

Change Summary

Incremental Difference

--- a/gdb/ChangeLog
+++ b/gdb/ChangeLog
@@ -1,5 +1,19 @@
11 2020-06-25 Andrew Burgess <andrew.burgess@embecosm.com>
22
3+ * riscv-tdep.c (riscv_register_name): Return NULL for duplicate
4+ fflags, frm, and fcsr registers.
5+ (riscv_register_reggroup_p): Remove unknown CSRs from save and
6+ restore groups.
7+ (riscv_tdesc_unknown_reg): New function.
8+ (riscv_gdbarch_init): Pass riscv_tdesc_unknown_reg to
9+ tdesc_use_registers.
10+ * riscv-tdep.h (struct gdbarch_tdep): Add
11+ unknown_csrs_first_regnum, unknown_csrs_count,
12+ duplicate_fflags_regnum, duplicate_frm_regnum, and
13+ duplicate_fcsr_regnum fields.
14+
15+2020-06-25 Andrew Burgess <andrew.burgess@embecosm.com>
16+
317 * target-descriptions.c (tdesc_use_registers): Add new parameter a
418 callback, use the callback (when not null) to help number unknown
519 registers.
--- a/gdb/riscv-tdep.c
+++ b/gdb/riscv-tdep.c
@@ -617,6 +617,22 @@ riscv_register_name (struct gdbarch *gdbarch, int regnum)
617617 return NULL;
618618 }
619619
620+ /* Some targets (QEMU) are reporting these three registers twice, once
621+ in the FPU feature, and once in the CSR feature. Both of these read
622+ the same underlying state inside the target, but naming the register
623+ twice in the target description results in GDB having two registers
624+ with the same name, only one of which can ever be accessed, but both
625+ will show up in 'info register all'. Unless, we identify the
626+ duplicate copies of these registers (in riscv_tdesc_unknown_reg) and
627+ then hide the registers here by giving them no name. */
628+ struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch);
629+ if (tdep->duplicate_fflags_regnum == regnum)
630+ return NULL;
631+ if (tdep->duplicate_frm_regnum == regnum)
632+ return NULL;
633+ if (tdep->duplicate_fcsr_regnum == regnum)
634+ return NULL;
635+
620636 /* The remaining registers are different. For all other registers on the
621637 machine we prefer to see the names that the target description
622638 provides. This is particularly important for CSRs which might be
@@ -968,6 +984,19 @@ riscv_register_reggroup_p (struct gdbarch *gdbarch, int regnum,
968984
969985 if (regnum > RISCV_LAST_REGNUM)
970986 {
987+ /* Any extra registers from the CSR tdesc_feature (identified in
988+ riscv_tdesc_unknown_reg) are removed from the save/restore groups
989+ as some targets (QEMU) report CSRs which then can't be read. */
990+ struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch);
991+ if ((reggroup == restore_reggroup || reggroup == save_reggroup)
992+ && regnum >= tdep->unknown_csrs_first_regnum
993+ && regnum < (tdep->unknown_csrs_first_regnum
994+ + tdep->unknown_csrs_count))
995+ return 0;
996+
997+ /* This is some other unknown register from the target description.
998+ In this case we trust whatever the target description says about
999+ which groups this register should be in. */
9711000 int ret = tdesc_register_in_reggroup_p (gdbarch, regnum, reggroup);
9721001 if (ret != -1)
9731002 return ret;
@@ -3166,6 +3195,85 @@ riscv_gcc_target_options (struct gdbarch *gdbarch)
31663195 return target_options;
31673196 }
31683197
3198+/* Call back from tdesc_use_registers, called for each unknown register
3199+ found in the target description.
3200+
3201+ See target-description.h (typedef tdesc_unknown_register_ftype) for a
3202+ discussion of the arguments and return values. */
3203+
3204+static int
3205+riscv_tdesc_unknown_reg (struct gdbarch *gdbarch, tdesc_feature *feature,
3206+ const char *reg_name, int possible_regnum)
3207+{
3208+ /* At one point in time GDB had an incorrect default target description
3209+ that duplicated the fflags, frm, and fcsr registers in both the FPU
3210+ and CSR register sets.
3211+
3212+ Some targets (QEMU) copied these target descriptions into their source
3213+ tree, and so we're currently stuck working with some targets that
3214+ declare the same registers twice.
3215+
3216+ There's not much we can do about this any more. Assuming the target
3217+ will direct a request for either register number to the correct
3218+ underlying hardware register then it doesn't matter which one GDB
3219+ uses, so long as we (GDB) are consistent (so that we don't end up with
3220+ invalid cache misses).
3221+
3222+ As we always scan the FPU registers first, then the CSRs, if the
3223+ target has included the offending registers in both sets then we will
3224+ always see the FPU copies here, as the CSR versions will replace them
3225+ in the register list.
3226+
3227+ To prevent these duplicates showing up in any of the register list,
3228+ record their register numbers here. */
3229+ if (strcmp (tdesc_feature_name (feature), riscv_freg_feature.name) == 0)
3230+ {
3231+ struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch);
3232+ int *regnum_ptr = nullptr;
3233+
3234+ if (strcmp (reg_name, "fflags") == 0)
3235+ regnum_ptr = &tdep->duplicate_fflags_regnum;
3236+ else if (strcmp (reg_name, "frm") == 0)
3237+ regnum_ptr = &tdep->duplicate_frm_regnum;
3238+ else if (strcmp (reg_name, "fcsr") == 0)
3239+ regnum_ptr = &tdep->duplicate_fcsr_regnum;
3240+
3241+ if (regnum_ptr != nullptr)
3242+ {
3243+ /* This means the register appears more than twice in the target
3244+ description. Just let GDB add this as another register.
3245+ We'll have duplicates in the register name list, but there's
3246+ not much more we can do. */
3247+ if (*regnum_ptr != -1)
3248+ return -1;
3249+
3250+ /* Record the number assigned to this register, then return the
3251+ number (so it actually gets assigned to this register). */
3252+ *regnum_ptr = possible_regnum;
3253+ return possible_regnum;
3254+ }
3255+ }
3256+
3257+ /* Any unknown registers in the CSR feature are recorded within a single
3258+ block so we can easily identify these registers when making choices
3259+ about register groups in riscv_register_reggroup_p. */
3260+ if (strcmp (tdesc_feature_name (feature), riscv_csr_feature.name) == 0)
3261+ {
3262+ struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch);
3263+ if (tdep->unknown_csrs_first_regnum == -1)
3264+ tdep->unknown_csrs_first_regnum = possible_regnum;
3265+ gdb_assert (tdep->unknown_csrs_first_regnum
3266+ + tdep->unknown_csrs_count == possible_regnum);
3267+ tdep->unknown_csrs_count++;
3268+ return possible_regnum;
3269+ }
3270+
3271+ /* Some other unknown register. Don't assign this a number now, it will
3272+ be assigned a number automatically later by the target description
3273+ handling code. */
3274+ return -1;
3275+}
3276+
31693277 /* Implement the gnu_triplet_regexp method. A single compiler supports both
31703278 32-bit and 64-bit code, and may be named riscv32 or riscv64 or (not
31713279 recommended) riscv. */
@@ -3403,7 +3511,7 @@ riscv_gdbarch_init (struct gdbarch_info info,
34033511 set_gdbarch_print_registers_info (gdbarch, riscv_print_registers_info);
34043512
34053513 /* Finalise the target description registers. */
3406- tdesc_use_registers (gdbarch, tdesc, tdesc_data);
3514+ tdesc_use_registers (gdbarch, tdesc, tdesc_data, riscv_tdesc_unknown_reg);
34073515
34083516 /* Override the register type callback setup by the target description
34093517 mechanism. This allows us to provide special type for floating point
--- a/gdb/riscv-tdep.h
+++ b/gdb/riscv-tdep.h
@@ -79,6 +79,21 @@ struct gdbarch_tdep
7979
8080 /* ISA-specific data types. */
8181 struct type *riscv_fpreg_d_type = nullptr;
82+
83+ /* Use for tracking unknown CSRs in the target description.
84+ UNKNOWN_CSRS_FIRST_REGNUM is the number assigned to the first unknown
85+ CSR. All other unknown CSRs will be assigned sequential numbers after
86+ this, with UNKNOWN_CSRS_COUNT being the total number of unknown CSRs. */
87+ int unknown_csrs_first_regnum = -1;
88+ int unknown_csrs_count = 0;
89+
90+ /* Some targets (QEMU) are reporting three registers twice in the target
91+ description they send. These three register numbers, when not set to
92+ -1, are for the duplicate copies of these registers. */
93+ int duplicate_fflags_regnum = -1;
94+ int duplicate_frm_regnum = -1;
95+ int duplicate_fcsr_regnum = -1;
96+
8297 };
8398
8499
--- a/gdb/testsuite/ChangeLog
+++ b/gdb/testsuite/ChangeLog
@@ -1,5 +1,9 @@
11 2020-06-25 Andrew Burgess <andrew.burgess@embecosm.com>
22
3+ * gdb.arch/riscv-tdesc-regs.exp: Extend test case.
4+
5+2020-06-25 Andrew Burgess <andrew.burgess@embecosm.com>
6+
37 * gdb.arch/riscv-tdesc-loading-01.xml: New file.
48 * gdb.arch/riscv-tdesc-loading-02.xml: New file.
59 * gdb.arch/riscv-tdesc-loading-03.xml: New file.
--- a/gdb/testsuite/gdb.arch/riscv-tdesc-regs.exp
+++ b/gdb/testsuite/gdb.arch/riscv-tdesc-regs.exp
@@ -100,13 +100,14 @@ foreach rgroup {all save restore} {
100100 }
101101 }
102102
103- foreach reg {dscratch} {
103+ foreach reg {fflags frm fcsr unknown_csr dscratch} {
104104 if { [info exists reg_counts($reg) ] } {
105105 set count $reg_counts($reg)
106106 } else {
107107 set count 0
108108 }
109- if {$reg == "dscratch" && $rgroup != "all"} {
109+ if {($reg == "unknown_csr" || $reg == "dscratch") \
110+ && $rgroup != "all"} {
110111 gdb_assert {$count == 0} \
111112 "register $reg not seen in reggroup $rgroup"
112113 } else {