qemu-devel.nongnu.org archive mirror
 help / color / mirror / Atom feed
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


  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).