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