aboutsummaryrefslogtreecommitdiff
path: root/tests/tcg/aarch64/gdbstub/test-mte.py
blob: 66f9c25f8a46a29d2eefcf66d8f1492c1b458707 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
from __future__ import print_function
#
# Test GDB memory-tag commands that exercise the stubs for the qIsAddressTagged,
# qMemTag, and QMemTag packets. Logical tag-only commands rely on local
# operations, hence don't exercise any stub.
#
# The test consists in breaking just after a atag() call (which sets the
# allocation tag -- see mte-8.c for details) and setting/getting tags in
# different memory locations and ranges starting at the address of the array
# 'a'.
#
# This is launched via tests/guest-debug/run-test.py
#


import gdb
import re
from test_gdbstub import main, report


PATTERN_0 = "Memory tags for address 0x[0-9a-f]+ match \\(0x[0-9a-f]+\\)."
PATTERN_1 = ".*(0x[0-9a-f]+)"


def run_test():
    gdb.execute("break 95", False, True)
    gdb.execute("continue", False, True)
    try:
        # Test if we can check correctly that the allocation tag for
        # array 'a' matches the logical tag after atag() is called.
        co = gdb.execute("memory-tag check a", False, True)
        tags_match = re.findall(PATTERN_0, co, re.MULTILINE)
        if tags_match:
            report(True, f"{tags_match[0]}")
        else:
            report(False, "Logical and allocation tags don't match!")

        # Test allocation tag 'set and print' commands. Commands on logical
        # tags rely on local operation and so don't exercise any stub.

        # Set the allocation tag for the first granule (16 bytes) of
        # address starting at 'a' address to a known value, i.e. 0x04.
        gdb.execute("memory-tag set-allocation-tag a 1 04", False, True)

        # Then set the allocation tag for the second granule to a known
        # value, i.e. 0x06. This tests that contiguous tag granules are
        # set correct and don't run over each other.
        gdb.execute("memory-tag set-allocation-tag a+16 1 06", False, True)

        # Read the known values back and check if they remain the same.

        co = gdb.execute("memory-tag print-allocation-tag a", False, True)
        first_tag = re.match(PATTERN_1, co)[1]

        co = gdb.execute("memory-tag print-allocation-tag a+16", False, True)
        second_tag = re.match(PATTERN_1, co)[1]

        if first_tag == "0x4" and second_tag == "0x6":
            report(True, "Allocation tags are correctly set/printed.")
        else:
            report(False, "Can't set/print allocation tags!")

        # Now test fill pattern by setting a whole page with a pattern.
        gdb.execute("memory-tag set-allocation-tag a 4096 0a0b", False, True)

        # And read back the tags of the last two granules in page so
        # we also test if the pattern is set correctly up to the end of
        # the page.
        co = gdb.execute("memory-tag print-allocation-tag a+4096-32", False, True)
        tag = re.match(PATTERN_1, co)[1]

        co = gdb.execute("memory-tag print-allocation-tag a+4096-16", False, True)
        last_tag = re.match(PATTERN_1, co)[1]

        if tag == "0xa" and last_tag == "0xb":
            report(True, "Fill pattern is ok.")
        else:
            report(False, "Fill pattern failed!")

    except gdb.error:
        # This usually happens because a GDB version that does not
        # support memory tagging was used to run the test.
        report(False, "'memory-tag' command failed!")


main(run_test, expected_arch="aarch64")