From: "Alex Bennée" <alex.bennee@linaro.org>
To: Luis Machado <luis.machado@arm.com>
Cc: "Nicholas Piggin" <npiggin@gmail.com>,
qemu-devel@nongnu.org, "Akihiko Odaki" <akihiko.odaki@daynix.com>,
"Luis Machado" <luis.machado@linaro.org>,
"Ilya Leoshkevich" <iii@linux.ibm.com>,
qemu-s390x@nongnu.org,
"Daniel Henrique Barboza" <danielhb413@gmail.com>,
qemu-ppc@nongnu.org, "Philippe Mathieu-Daudé" <philmd@linaro.org>,
"Cédric Le Goater" <clg@kaod.org>,
"Richard Henderson" <richard.henderson@linaro.org>,
"David Hildenbrand" <david@redhat.com>,
"gdb@gnu.org" <gdb@gnu.org>
Subject: Re: [PULL 06/23] tests/tcg: add an explicit gdbstub register tester
Date: Thu, 16 Nov 2023 14:59:07 +0000 [thread overview]
Message-ID: <87y1exu4lg.fsf@draig.linaro.org> (raw)
In-Reply-To: <37df0557-faf0-4667-925f-fcc7deac4f52@arm.com> (Luis Machado's message of "Thu, 16 Nov 2023 09:56:40 +0000")
Luis Machado <luis.machado@arm.com> writes:
> On 11/15/23 20:56, Alex Bennée via Gdb wrote:
>> "Nicholas Piggin" <npiggin@gmail.com> writes:
>>
>>> On Wed Nov 8, 2023 at 12:23 AM AEST, Alex Bennée wrote:
>>>> We already do a couple of "info registers" for specific tests but this
>>>> is a more comprehensive multiarch test. It also has some output
>>>> helpful for debugging the gdbstub by showing which XML features are
>>>> advertised and what the underlying register numbers are.
>>>>
>>>> My initial motivation was to see if there are any duplicate register
>>>> names exposed via the gdbstub while I was reviewing the proposed
>>>> register interface for TCG plugins.
>>>>
>>>> Mismatches between the xml and remote-desc are reported for debugging
>>>> but do not fail the test.
>>>>
>>>> We also skip the tests for the following arches for now until we can
>>>> investigate and fix any issues:
>>>>
>>>> - s390x (fails to read v0l->v15l, not seen in remote-registers)
>>>> - ppc64 (fails to read vs0h->vs31h, not seen in remote-registers)
>>>
>>> binutils-gdb.git/gdb/rs6000-tdep.c has:
>>>
>>> static const char *
>>> rs6000_register_name (struct gdbarch *gdbarch, int regno)
>>> {
>>> ppc_gdbarch_tdep *tdep = (ppc_gdbarch_tdep *) gdbarch_tdep (gdbarch);
>>>
>>> /* The upper half "registers" have names in the XML description,
>>> but we present only the low GPRs and the full 64-bit registers
>>> to the user. */
>>> if (tdep->ppc_ev0_upper_regnum >= 0
>>> && tdep->ppc_ev0_upper_regnum <= regno
>>> && regno < tdep->ppc_ev0_upper_regnum + ppc_num_gprs)
>>> return "";
>>>
>>> /* Hide the upper halves of the vs0~vs31 registers. */
>>> if (tdep->ppc_vsr0_regnum >= 0
>>> && tdep->ppc_vsr0_upper_regnum <= regno
>>> && regno < tdep->ppc_vsr0_upper_regnum + ppc_num_gprs)
>>> return "";
>>>
>>> (s390 looks similar for V0-V15 lower).
>>>
>>> I guess it is because the upper half is not a real register but an
>>> extension of an existing FP register to make a vector register. I
>>> just don't know how that should be resolved with QEMU.
>>>
>>> Should we put an exception in the test case for these? Or is there
>>> something we should be doing differently with the XML regs?
>>
>> Yeah I suspect this is just inconsistency between targets on gdb. My
>> naive assumption was XML should match the displayed registers but it
>> seems there is additional filtering going on.
>>
>> It seems in this case the registers are still there and have regnums (so
>> I assume the stub could be asked for them) but the names have been
>> squashed. I guess we could detect that and accept it?
>>
>>>
>>> i386 gdb does similar:
>>>
>>> static const char *
>>> i386_register_name (struct gdbarch *gdbarch, int regnum)
>>> {
>>> /* Hide the upper YMM registers. */
>>> if (i386_ymmh_regnum_p (gdbarch, regnum))
>>> return "";
>>>
>>> /* Hide the upper YMM16-31 registers. */
>>> if (i386_ymmh_avx512_regnum_p (gdbarch, regnum))
>>> return "";
>>>
>>> /* Hide the upper ZMM registers. */
>>> if (i386_zmmh_regnum_p (gdbarch, regnum))
>>> return "";
>>>
>>> return tdesc_register_name (gdbarch, regnum);
>>> }
>>>
>>> So, I'm not sure how they don't fail this test. Does QEMU just
>>> not have YMM/ZMM in XML regmap?
>>
>> No I think we only send the core one with XMM regs and there are no
>> additional registers sent via gdb_register_coprocessor.
>>
>>>
>>> Thanks,
>>> Nick
>
> FTR, luis.machado@linaro.org doesn't exist anymore.
>
> As for the XML, it serves as an architecture hint/description of what features and registers
> are available.
>
> GDB will process that and will potentially include additional pseudo-registers (so QEMU doesn't
> need to do so, unless it is some pseudo-register not accounted by gdb).
>
> The rest of the features/registers gdb doesn't care about, it will just add them to the end of the
> list, and will assign whatever number is next. GDB will be able to read/write them, but nothing more
> than that.
So with a bit of fiddling I can do:
modified tests/tcg/multiarch/gdbstub/registers.py
@@ -44,7 +44,6 @@ def fetch_xml_regmap():
total_regs = 0
reg_map = {}
- frame = gdb.selected_frame()
tree = ET.fromstring(xml)
for f in tree.findall("feature"):
@@ -61,12 +60,8 @@ def fetch_xml_regmap():
for r in regs:
name = r.attrib["name"]
regnum = int(r.attrib["regnum"])
- try:
- value = frame.read_register(name)
- except ValueError:
- report(False, f"failed to read reg: {name}")
- entry = { "name": name, "initial": value, "regnum": regnum }
+ entry = { "name": name, "regnum": regnum }
if name in reg_map:
report(False, f"duplicate register {entry} vs {reg_map[name]}")
@@ -80,6 +75,15 @@ def fetch_xml_regmap():
return reg_map
+def get_register_by_regnum(reg_map, regnum):
+ """
+ Helper to find a register from the map via its XML regnum
+ """
+ for regname, entry in reg_map.items():
+ if entry['regnum'] == regnum:
+ return entry
+ return None
+
def crosscheck_remote_xml(reg_map):
"""
Cross-check the list of remote-registers with the XML info.
@@ -90,6 +94,7 @@ def crosscheck_remote_xml(reg_map):
total_regs = len(reg_map.keys())
total_r_regs = 0
+ total_r_elided_regs = 0
for r in r_regs:
fields = r.split()
@@ -100,6 +105,15 @@ def crosscheck_remote_xml(reg_map):
r_name = fields[0]
r_regnum = int(fields[6])
+ # Some registers are "hidden" so don't have a name
+ # although they still should have a register number
+ if r_name == "''":
+ total_r_elided_regs += 1
+ x_reg = get_register_by_regnum(reg_map, r_regnum)
+ if x_reg is not None:
+ x_reg["hidden"] = True
+ continue
+
# check in the XML
try:
x_reg = reg_map[r_name]
@@ -118,13 +132,38 @@ def crosscheck_remote_xml(reg_map):
# registers on a 32 bit machine. Also print what is missing to
# help with debug.
if total_regs != total_r_regs:
- print(f"xml-tdesc has ({total_regs}) registers")
- print(f"remote-registers has ({total_r_regs}) registers")
+ print(f"xml-tdesc has {total_regs} registers")
+ print(f"remote-registers has {total_r_regs} registers")
+ print(f"of which {total_r_elided_regs} are hidden")
for x_key in reg_map.keys():
x_reg = reg_map[x_key]
- if "seen" not in x_reg:
- print(f"{x_reg} wasn't seen in remote-registers")
+ if "hidden" in x_reg:
+ print(f"{x_reg} elided by gdb")
+ elif "seen" not in x_reg:
+ report(False, f"{x_reg} wasn't seen in remote-registers")
+
+def initial_register_read(reg_map):
+ """
+ Do an initial read of all registers that we know gdb cares about
+ (so ignore the elided ones).
+ """
+ frame = gdb.selected_frame()
+
+ for e in reg_map.values():
+ name = e["name"]
+ regnum = e["regnum"]
+
+ try:
+ if "hidden" in e:
+ value = frame.read_register(regnum)
+ else:
+ value = frame.read_register(name)
+
+ e["initial"] = value
+ except ValueError:
+ report(False, f"failed to read reg: {name}")
+
def complete_and_diff(reg_map):
"""
@@ -144,18 +183,19 @@ def complete_and_diff(reg_map):
changed = 0
for e in reg_map.values():
- name = e["name"]
- old_val = e["initial"]
+ if "hidden" not in e:
+ name = e["name"]
+ old_val = e["initial"]
- try:
- new_val = frame.read_register(name)
- except:
- report(False, f"failed to read {name} at end of run")
- continue
+ try:
+ new_val = frame.read_register(name)
+ except ValueError:
+ report(False, f"failed to read {name} at end of run")
+ continue
- if new_val != old_val:
- print(f"{name} changes from {old_val} to {new_val}")
- changed += 1
+ if new_val != old_val:
+ print(f"{name} changes from {old_val} to {new_val}")
+ changed += 1
# as long as something changed we can be confident its working
report(changed > 0, f"{changed} registers were changed")
@@ -168,6 +208,7 @@ def run_test():
if reg_map is not None:
crosscheck_remote_xml(reg_map)
+ initial_register_read(reg_map)
complete_and_diff(reg_map)
I'll wrap that into my next set of patches.
--
Alex Bennée
Virtualisation Tech Lead @ Linaro
next prev parent reply other threads:[~2023-11-16 15:00 UTC|newest]
Thread overview: 31+ messages / expand[flat|nested] mbox.gz Atom feed top
2023-11-07 14:23 [PULL 00/23] Final test, gdbstub, plugin and gitdm updates for 8.2 Alex Bennée
2023-11-07 14:23 ` [PULL 01/23] default-configs: Add TARGET_XML_FILES definition Alex Bennée
2023-11-07 14:23 ` [PULL 02/23] gdb-xml: fix duplicate register in arm-neon.xml Alex Bennée
2023-11-07 14:23 ` [PULL 03/23] target/arm: mark the 32bit alias of PAR when LPAE enabled Alex Bennée
2023-11-07 14:23 ` [PULL 04/23] target/arm: hide all versions of DBGD[RS]AR from gdbstub Alex Bennée
2023-11-07 14:23 ` [PULL 05/23] target/arm: hide aliased MIDR " Alex Bennée
2023-11-07 14:23 ` [PULL 06/23] tests/tcg: add an explicit gdbstub register tester Alex Bennée
2023-11-13 11:23 ` Nicholas Piggin
2023-11-15 20:56 ` Alex Bennée
2023-11-16 9:56 ` Luis Machado
2023-11-16 14:59 ` Alex Bennée [this message]
2023-11-07 14:23 ` [PULL 07/23] tests/avocado: update the tcg_plugins test Alex Bennée
2023-11-07 14:23 ` [PULL 08/23] gdbstub: Add num_regs member to GDBFeature Alex Bennée
2023-11-07 14:23 ` [PULL 09/23] gdbstub: Introduce gdb_find_static_feature() Alex Bennée
2023-11-07 14:23 ` [PULL 10/23] gdbstub: Introduce GDBFeatureBuilder Alex Bennée
2023-11-07 14:23 ` [PULL 11/23] cpu: Call plugin hooks only when ready Alex Bennée
2023-11-07 14:23 ` [PULL 12/23] configure: tell meson and contrib_plugins about DLLTOOL Alex Bennée
2023-11-07 14:23 ` [PULL 13/23] plugins: add dllexport and dllimport to api funcs Alex Bennée
2023-11-07 14:23 ` [PULL 14/23] plugins: make test/example plugins work on windows Alex Bennée
2023-11-07 14:23 ` [PULL 15/23] plugins: disable lockstep plugin " Alex Bennée
2023-11-07 14:23 ` [PULL 16/23] gitlab: add dlltool to Windows CI Alex Bennée
2023-11-07 14:23 ` [PULL 17/23] plugins: allow plugins to be enabled on windows Alex Bennée
2023-11-07 14:23 ` [PULL 18/23] contrib/gitdm: Add Rivos Inc to the domain map Alex Bennée
2023-11-07 14:23 ` [PULL 19/23] contrib/gitdm: add domain-map for Cestc Alex Bennée
2023-11-07 14:23 ` [PULL 20/23] contrib/gitdm: map HiSilicon to Huawei Alex Bennée
2023-11-07 14:23 ` [PULL 21/23] contrib/gitdm: add Daynix to domain-map Alex Bennée
2023-11-07 14:23 ` [PULL 22/23] mailmap: fixup some more corrupted author fields Alex Bennée
2023-11-07 14:23 ` [PULL 23/23] Revert "tests/tcg/nios2: Re-enable linux-user tests" Alex Bennée
2023-11-08 12:36 ` [PULL 00/23] Final test, gdbstub, plugin and gitdm updates for 8.2 Stefan Hajnoczi
2023-11-08 14:56 ` Alex Bennée
2023-11-08 15:54 ` Alex Bennée
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=87y1exu4lg.fsf@draig.linaro.org \
--to=alex.bennee@linaro.org \
--cc=akihiko.odaki@daynix.com \
--cc=clg@kaod.org \
--cc=danielhb413@gmail.com \
--cc=david@redhat.com \
--cc=gdb@gnu.org \
--cc=iii@linux.ibm.com \
--cc=luis.machado@arm.com \
--cc=luis.machado@linaro.org \
--cc=npiggin@gmail.com \
--cc=philmd@linaro.org \
--cc=qemu-devel@nongnu.org \
--cc=qemu-ppc@nongnu.org \
--cc=qemu-s390x@nongnu.org \
--cc=richard.henderson@linaro.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).