1from __future__ import print_function 2# 3# Test GDB memory-tag commands that exercise the stubs for the qIsAddressTagged, 4# qMemTag, and QMemTag packets. Logical tag-only commands rely on local 5# operations, hence don't exercise any stub. 6# 7# The test consists in breaking just after a atag() call (which sets the 8# allocation tag -- see mte-8.c for details) and setting/getting tags in 9# different memory locations and ranges starting at the address of the array 10# 'a'. 11# 12# This is launched via tests/guest-debug/run-test.py 13# 14 15 16import gdb 17import re 18from test_gdbstub import main, report 19 20 21PATTERN_0 = "Memory tags for address 0x[0-9a-f]+ match \(0x[0-9a-f]+\)." 22PATTERN_1 = ".*(0x[0-9a-f]+)" 23 24 25def run_test(): 26 gdb.execute("break 95", False, True) 27 gdb.execute("continue", False, True) 28 try: 29 # Test if we can check correctly that the allocation tag for 30 # array 'a' matches the logical tag after atag() is called. 31 co = gdb.execute("memory-tag check a", False, True) 32 tags_match = re.findall(PATTERN_0, co, re.MULTILINE) 33 if tags_match: 34 report(True, f"{tags_match[0]}") 35 else: 36 report(False, "Logical and allocation tags don't match!") 37 38 # Test allocation tag 'set and print' commands. Commands on logical 39 # tags rely on local operation and so don't exercise any stub. 40 41 # Set the allocation tag for the first granule (16 bytes) of 42 # address starting at 'a' address to a known value, i.e. 0x04. 43 gdb.execute("memory-tag set-allocation-tag a 1 04", False, True) 44 45 # Then set the allocation tag for the second granule to a known 46 # value, i.e. 0x06. This tests that contiguous tag granules are 47 # set correct and don't run over each other. 48 gdb.execute("memory-tag set-allocation-tag a+16 1 06", False, True) 49 50 # Read the known values back and check if they remain the same. 51 52 co = gdb.execute("memory-tag print-allocation-tag a", False, True) 53 first_tag = re.match(PATTERN_1, co)[1] 54 55 co = gdb.execute("memory-tag print-allocation-tag a+16", False, True) 56 second_tag = re.match(PATTERN_1, co)[1] 57 58 if first_tag == "0x4" and second_tag == "0x6": 59 report(True, "Allocation tags are correctly set/printed.") 60 else: 61 report(False, "Can't set/print allocation tags!") 62 63 # Now test fill pattern by setting a whole page with a pattern. 64 gdb.execute("memory-tag set-allocation-tag a 4096 0a0b", False, True) 65 66 # And read back the tags of the last two granules in page so 67 # we also test if the pattern is set correctly up to the end of 68 # the page. 69 co = gdb.execute("memory-tag print-allocation-tag a+4096-32", False, True) 70 tag = re.match(PATTERN_1, co)[1] 71 72 co = gdb.execute("memory-tag print-allocation-tag a+4096-16", False, True) 73 last_tag = re.match(PATTERN_1, co)[1] 74 75 if tag == "0xa" and last_tag == "0xb": 76 report(True, "Fill pattern is ok.") 77 else: 78 report(False, "Fill pattern failed!") 79 80 except gdb.error: 81 # This usually happens because a GDB version that does not 82 # support memory tagging was used to run the test. 83 report(False, "'memory-tag' command failed!") 84 85 86main(run_test, expected_arch="aarch64") 87