From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: by sourceware.org (Postfix, from userid 1726) id D70A53857C61; Sun, 2 Oct 2022 16:27:40 +0000 (GMT) DKIM-Filter: OpenDKIM Filter v2.11.0 sourceware.org D70A53857C61 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=sourceware.org; s=default; t=1664728060; bh=5JFXOHiRxgbd+eGwaUETVN6sOYm19VZjHGtENdK2HVs=; h=From:To:Subject:Date:From; b=Of1OSeUSuTXuQrwEkMz4Usgo8qrK1UKSxMHjF0snOZ8y+mPZTIprvz9DVfk/VPov8 QIERJeFIseiRh5K3KJdKCFqA6IryA6ogNJfRgzSv8dWyqFwb8Voeusc+P+Bves+Z+R 5U+ZS7JwO1V61NN6McpkrBuZyIXKeA8++nAwl0aY= Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable From: Andrew Burgess To: gdb-cvs@sourceware.org Subject: [binutils-gdb] gdb/riscv: fix failure in gdb.base/completion.exp X-Act-Checkin: binutils-gdb X-Git-Author: Andrew Burgess X-Git-Refname: refs/heads/master X-Git-Oldrev: e7b1ba07bc9dc28819c9a2523f5e5cdb43e13ca2 X-Git-Newrev: bd93abe8d5513ceecc10a91452a85c803cac895b Message-Id: <20221002162740.D70A53857C61@sourceware.org> Date: Sun, 2 Oct 2022 16:27:40 +0000 (GMT) List-Id: https://sourceware.org/git/gitweb.cgi?p=3Dbinutils-gdb.git;h=3Dbd93abe8d551= 3ceecc10a91452a85c803cac895b commit bd93abe8d5513ceecc10a91452a85c803cac895b Author: Andrew Burgess Date: Sun Aug 28 20:40:28 2022 +0100 gdb/riscv: fix failure in gdb.base/completion.exp =20 I noticed a test failure in gdb.base/completion.exp for RISC-V on a native Linux target, this is the failure: =20 (gdb) FAIL: gdb.base/completion.exp: complete 'info registers ' =20 The problem is caused by a mismatch in the output of 'maint print registers' and the completion list for 'info registers'. The 'info registers' completion list contains less registers than expected. Additionally, the list of registers extracted from the 'maint print registers' list was wrong too, in some cases the test was grabbing the register number, rather than a register name, =20 Both of these problems have the same root cause, riscv_register_name returns nullptr for some registers when it should return an empty string. =20 The gdbarch_register_name API is not clearly documented anywhere, and at first glance it would appear that the function can return either nullptr, or an empty string to indicate that a register is not available on the current target. Indeed, there are plenty of places in GDB where we compare the output of gdbarch_register_name to both nullptr and '\0' in order to see if a register is supported or not, and there are plenty of targets that return empty string in some cases, and nullptr in others. =20 However, the 'info registers' completion code (reg_or_group_completer) clearly depends on user_reg_map_regnum_to_name only returning nullptr when the passed in regnum is greater than the maximum possible register number (i.e. after all physical registers, pseudo-registers, and user-registers), this means that gdbarch_register_name should not be returning nullptr. =20 I did consider "fixing" user_reg_map_regnum_to_name, if gdbarch_register_name returns nullptr, I could convert to an empty string at this point, but that felt like a real hack, so I discarded that plan. =20 The next possibility I considered was "fixing" reg_or_group_completer to not rely on nullptr to indicate the end marker. Or rather, I could have reg_or_group_completer use gdbarch_num_cooked_regs, we know that we should check at least that many register numbers. Then, once we're passed that limit, we keep checking until we hit a nullptr. This would absolutely work, and didn't actually feel that bad, but, it still felt a little weird that gdbarch_register_name could return nullptr OR the empty string to mean the same thing, so I wondered if the "right" solution was to have gdbarch_register_name not return nullptr. With this in mind I tried an experiment: =20 I added a self-test that, for each architecture, calls gdbarch_register_name for every register number up to the gdbarch_num_cooked_regs limit, and checks that the name is not nullptr. =20 Only a handful of architectures failed this test, RISC-V being one of them. =20 This seems to suggest that most architectures agree that the correct API for gdbarch_register_name is to return an empty string for registers that are not supported on the current target, and that returning nullptr is really a mistake. =20 In this commit I will update the RISC-V target so that GDB no longer returns nullptr from riscv_register_name, instead we return the empty string. =20 In subsequent commits I will add the selftest that I mention above, and will fix the targets that fail the selftest. =20 With this change the gdb.base/completion.exp test now passes. Diff: --- gdb/riscv-tdep.c | 25 ++++++++++++------------- 1 file changed, 12 insertions(+), 13 deletions(-) diff --git a/gdb/riscv-tdep.c b/gdb/riscv-tdep.c index e419b97693d..7bddf535804 100644 --- a/gdb/riscv-tdep.c +++ b/gdb/riscv-tdep.c @@ -882,8 +882,9 @@ riscv_register_name (struct gdbarch *gdbarch, int regnu= m) then this is an unknown register. If we do get a name back then we look up the registers preferred name below. */ const char *name =3D tdesc_register_name (gdbarch, regnum); - if (name =3D=3D NULL || name[0] =3D=3D '\0') - return NULL; + gdb_assert (name !=3D nullptr); + if (name[0] =3D=3D '\0') + return name; =20 /* We want GDB to use the ABI names for registers even if the target gives us a target description with the architectural name. For @@ -893,13 +894,13 @@ riscv_register_name (struct gdbarch *gdbarch, int reg= num) return riscv_xreg_feature.register_name (regnum); =20 /* Like with the x-regs we prefer the abi names for the floating point - registers. */ + registers. If the target doesn't have floating point registers then + the tdesc_register_name call above should have returned an empty + string. */ if (regnum >=3D RISCV_FIRST_FP_REGNUM && regnum <=3D RISCV_LAST_FP_REGNU= M) { - if (riscv_has_fp_regs (gdbarch)) - return riscv_freg_feature.register_name (regnum); - else - return NULL; + gdb_assert (riscv_has_fp_regs (gdbarch)); + return riscv_freg_feature.register_name (regnum); } =20 /* Some targets (QEMU) are reporting these three registers twice, once @@ -911,12 +912,10 @@ riscv_register_name (struct gdbarch *gdbarch, int reg= num) duplicate copies of these registers (in riscv_tdesc_unknown_reg) and then hide the registers here by giving them no name. */ riscv_gdbarch_tdep *tdep =3D gdbarch_tdep (gdbarch); - if (tdep->duplicate_fflags_regnum =3D=3D regnum) - return NULL; - if (tdep->duplicate_frm_regnum =3D=3D regnum) - return NULL; - if (tdep->duplicate_fcsr_regnum =3D=3D regnum) - return NULL; + if (tdep->duplicate_fflags_regnum =3D=3D regnum + || tdep->duplicate_frm_regnum =3D=3D regnum + || tdep->duplicate_fcsr_regnum =3D=3D regnum) + return ""; =20 /* The remaining registers are different. For all other registers on the machine we prefer to see the names that the target description