master
py 110 lines 4.22 KB
Raw
1 #
2 # Test GDB memory-tag commands that exercise the stubs for the qIsAddressTagged,
3 # qMemTag, and QMemTag packets, which are used for manipulating allocation tags.
4 # Logical tags-related commands rely on local operations, hence don't exercise
5 # any stub and so are not used in this test.
6 #
7 # The test consists in breaking just after a tag is set in a specific memory
8 # chunk, and then using the GDB 'memory-tagging' subcommands to set/get tags in
9 # different memory locations and ranges in the MTE-enabled memory chunk.
10 #
11 # This is launched via tests/guest-debug/run-test.py
12 #
13
14
15 try:
16 import gdb
17 except ModuleNotFoundError:
18 from sys import exit
19 exit("This script must be launched via tests/guest-debug/run-test.py!")
20 import re
21 from sys import argv
22 from test_gdbstub import arg_parser, main, report
23
24
25 PATTERN_0 = r"Memory tags for address 0x[0-9a-f]+ match \(0x[0-9a-f]+\)."
26 PATTERN_1 = r".*(0x[0-9a-f]+)"
27
28
29 def run_test():
30 p = arg_parser(prog="test-mte.py", description="TCG MTE tests.")
31 p.add_argument("--mode", help="Run test for QEMU system or user mode.",
32 required=True, choices=['system','user'])
33
34 args = p.parse_args(args=argv)
35
36 if args.mode == "system":
37 # Break address: where to break before performing the tests
38 # See mte.S for details about this label.
39 ba = "main_end"
40 # Tagged address: the start of the MTE-enabled memory chunk to be tested
41 # 'tagged_addr' (x1) is a pointer to the MTE-enabled page. See mte.S.
42 ta = "$x1"
43 else: # mode="user"
44 # Line 95 in mte-8.c
45 ba = "95"
46 # 'a' array. See mte-8.c
47 ta = "a"
48
49 gdb.execute(f"break {ba}", False, True)
50 gdb.execute("continue", False, True)
51
52 try:
53 # Test if we can check correctly that the allocation tag for the address
54 # in {ta} matches the logical tag in {ta}.
55 co = gdb.execute(f"memory-tag check {ta}", False, True)
56 tags_match = re.findall(PATTERN_0, co, re.MULTILINE)
57 if tags_match:
58 report(True, f"{tags_match[0]}")
59 else:
60 report(False, "Logical and allocation tags don't match!")
61
62 # Test allocation tag 'set and print' commands. Commands on logical
63 # tags rely on local operation and so don't exercise any stub.
64
65 # Set the allocation tag for the first granule (16 bytes) of
66 # address starting at {ta} address to a known value, i.e. 0x04.
67 gdb.execute(f"memory-tag set-allocation-tag {ta} 1 04", False, True)
68
69 # Then set the allocation tag for the second granule to a known
70 # value, i.e. 0x06. This tests that contiguous tag granules are
71 # set correctly and don't run over each other.
72 gdb.execute(f"memory-tag set-allocation-tag {ta}+16 1 06", False, True)
73
74 # Read the known values back and check if they remain the same.
75
76 co = gdb.execute(f"memory-tag print-allocation-tag {ta}", False, True)
77 first_tag = re.match(PATTERN_1, co)[1]
78
79 co = gdb.execute(f"memory-tag print-allocation-tag {ta}+16", False, True)
80 second_tag = re.match(PATTERN_1, co)[1]
81
82 if first_tag == "0x4" and second_tag == "0x6":
83 report(True, "Allocation tags are correctly set/printed.")
84 else:
85 report(False, "Can't set/print allocation tags!")
86
87 # Now test fill pattern by setting a whole page with a pattern.
88 gdb.execute(f"memory-tag set-allocation-tag {ta} 4096 0a0b", False, True)
89
90 # And read back the tags of the last two granules in page so
91 # we also test if the pattern is set correctly up to the end of
92 # the page.
93 co = gdb.execute(f"memory-tag print-allocation-tag {ta}+4096-32", False, True)
94 tag = re.match(PATTERN_1, co)[1]
95
96 co = gdb.execute(f"memory-tag print-allocation-tag {ta}+4096-16", False, True)
97 last_tag = re.match(PATTERN_1, co)[1]
98
99 if tag == "0xa" and last_tag == "0xb":
100 report(True, "Fill pattern is ok.")
101 else:
102 report(False, "Fill pattern failed!")
103
104 except gdb.error:
105 # This usually happens because a GDB version that does not support
106 # memory tagging was used to run the test.
107 report(False, "'memory-tag' command failed!")
108
109
110 main(run_test, expected_arch="aarch64")