1340ca46bSGustavo Romerofrom __future__ import print_function
2340ca46bSGustavo Romero#
3340ca46bSGustavo Romero# Test GDB memory-tag commands that exercise the stubs for the qIsAddressTagged,
4340ca46bSGustavo Romero# qMemTag, and QMemTag packets. Logical tag-only commands rely on local
5340ca46bSGustavo Romero# operations, hence don't exercise any stub.
6340ca46bSGustavo Romero#
7340ca46bSGustavo Romero# The test consists in breaking just after a atag() call (which sets the
8340ca46bSGustavo Romero# allocation tag -- see mte-8.c for details) and setting/getting tags in
9340ca46bSGustavo Romero# different memory locations and ranges starting at the address of the array
10340ca46bSGustavo Romero# 'a'.
11340ca46bSGustavo Romero#
12340ca46bSGustavo Romero# This is launched via tests/guest-debug/run-test.py
13340ca46bSGustavo Romero#
14340ca46bSGustavo Romero
15340ca46bSGustavo Romero
16340ca46bSGustavo Romeroimport gdb
17340ca46bSGustavo Romeroimport re
18340ca46bSGustavo Romerofrom test_gdbstub import main, report
19340ca46bSGustavo Romero
20340ca46bSGustavo Romero
21*c135d5eaSRichard HendersonPATTERN_0 = "Memory tags for address 0x[0-9a-f]+ match \\(0x[0-9a-f]+\\)."
22340ca46bSGustavo RomeroPATTERN_1 = ".*(0x[0-9a-f]+)"
23340ca46bSGustavo Romero
24340ca46bSGustavo Romero
25340ca46bSGustavo Romerodef run_test():
26340ca46bSGustavo Romero    gdb.execute("break 95", False, True)
27340ca46bSGustavo Romero    gdb.execute("continue", False, True)
28340ca46bSGustavo Romero    try:
29340ca46bSGustavo Romero        # Test if we can check correctly that the allocation tag for
30340ca46bSGustavo Romero        # array 'a' matches the logical tag after atag() is called.
31340ca46bSGustavo Romero        co = gdb.execute("memory-tag check a", False, True)
32340ca46bSGustavo Romero        tags_match = re.findall(PATTERN_0, co, re.MULTILINE)
33340ca46bSGustavo Romero        if tags_match:
34340ca46bSGustavo Romero            report(True, f"{tags_match[0]}")
35340ca46bSGustavo Romero        else:
36340ca46bSGustavo Romero            report(False, "Logical and allocation tags don't match!")
37340ca46bSGustavo Romero
38340ca46bSGustavo Romero        # Test allocation tag 'set and print' commands. Commands on logical
39340ca46bSGustavo Romero        # tags rely on local operation and so don't exercise any stub.
40340ca46bSGustavo Romero
41340ca46bSGustavo Romero        # Set the allocation tag for the first granule (16 bytes) of
42340ca46bSGustavo Romero        # address starting at 'a' address to a known value, i.e. 0x04.
43340ca46bSGustavo Romero        gdb.execute("memory-tag set-allocation-tag a 1 04", False, True)
44340ca46bSGustavo Romero
45340ca46bSGustavo Romero        # Then set the allocation tag for the second granule to a known
46340ca46bSGustavo Romero        # value, i.e. 0x06. This tests that contiguous tag granules are
47340ca46bSGustavo Romero        # set correct and don't run over each other.
48340ca46bSGustavo Romero        gdb.execute("memory-tag set-allocation-tag a+16 1 06", False, True)
49340ca46bSGustavo Romero
50340ca46bSGustavo Romero        # Read the known values back and check if they remain the same.
51340ca46bSGustavo Romero
52340ca46bSGustavo Romero        co = gdb.execute("memory-tag print-allocation-tag a", False, True)
53340ca46bSGustavo Romero        first_tag = re.match(PATTERN_1, co)[1]
54340ca46bSGustavo Romero
55340ca46bSGustavo Romero        co = gdb.execute("memory-tag print-allocation-tag a+16", False, True)
56340ca46bSGustavo Romero        second_tag = re.match(PATTERN_1, co)[1]
57340ca46bSGustavo Romero
58340ca46bSGustavo Romero        if first_tag == "0x4" and second_tag == "0x6":
59340ca46bSGustavo Romero            report(True, "Allocation tags are correctly set/printed.")
60340ca46bSGustavo Romero        else:
61340ca46bSGustavo Romero            report(False, "Can't set/print allocation tags!")
62340ca46bSGustavo Romero
63340ca46bSGustavo Romero        # Now test fill pattern by setting a whole page with a pattern.
64340ca46bSGustavo Romero        gdb.execute("memory-tag set-allocation-tag a 4096 0a0b", False, True)
65340ca46bSGustavo Romero
66340ca46bSGustavo Romero        # And read back the tags of the last two granules in page so
67340ca46bSGustavo Romero        # we also test if the pattern is set correctly up to the end of
68340ca46bSGustavo Romero        # the page.
69340ca46bSGustavo Romero        co = gdb.execute("memory-tag print-allocation-tag a+4096-32", False, True)
70340ca46bSGustavo Romero        tag = re.match(PATTERN_1, co)[1]
71340ca46bSGustavo Romero
72340ca46bSGustavo Romero        co = gdb.execute("memory-tag print-allocation-tag a+4096-16", False, True)
73340ca46bSGustavo Romero        last_tag = re.match(PATTERN_1, co)[1]
74340ca46bSGustavo Romero
75340ca46bSGustavo Romero        if tag == "0xa" and last_tag == "0xb":
76340ca46bSGustavo Romero            report(True, "Fill pattern is ok.")
77340ca46bSGustavo Romero        else:
78340ca46bSGustavo Romero            report(False, "Fill pattern failed!")
79340ca46bSGustavo Romero
80340ca46bSGustavo Romero    except gdb.error:
81340ca46bSGustavo Romero        # This usually happens because a GDB version that does not
82340ca46bSGustavo Romero        # support memory tagging was used to run the test.
83340ca46bSGustavo Romero        report(False, "'memory-tag' command failed!")
84340ca46bSGustavo Romero
85340ca46bSGustavo Romero
86340ca46bSGustavo Romeromain(run_test, expected_arch="aarch64")
87