1import gdbremote_testcase 2from lldbsuite.test.decorators import * 3from lldbsuite.test.lldbtest import * 4from lldbsuite.test import lldbutil 5 6""" 7Check that lldb-server correctly processes qMemTags and QMemTags packets. 8 9In the tests below E03 means the packet wasn't formed correctly 10and E01 means it was but we had some other error acting upon it. 11 12We do not test reading or writing over a page boundary 13within the same mapping. That logic is handled in the kernel 14so it's just a single ptrace call for lldb-server. 15""" 16 17class TestGdbRemoteMemoryTagging(gdbremote_testcase.GdbRemoteTestCaseBase): 18 19 def check_memtags_response(self, packet_name, body, expected): 20 self.test_sequence.add_log_lines(["read packet: ${}:{}#00".format(packet_name, body), 21 "send packet: ${}#00".format(expected), 22 ], 23 True) 24 self.expect_gdbremote_sequence() 25 26 def check_tag_read(self, body, expected): 27 self.check_memtags_response("qMemTags", body, expected) 28 29 def prep_memtags_test(self): 30 self.build() 31 self.set_inferior_startup_launch() 32 procs = self.prep_debug_monitor_and_inferior() 33 34 # We don't use isAArch64MTE here because we cannot do runCmd in an 35 # lldb-server test. Instead we run the example and skip if it fails 36 # to allocate an MTE buffer. 37 38 # Run the process 39 self.test_sequence.add_log_lines( 40 [ 41 # Start running after initial stop 42 "read packet: $c#63", 43 # Match the address of the MTE page 44 {"type": "output_match", 45 "regex": self.maybe_strict_output_regex(r"buffer: (.+) page_size: (.+)\r\n"), 46 "capture": {1: "buffer", 2: "page_size"}}, 47 # Now stop the inferior 48 "read packet: {}".format(chr(3)), 49 # And wait for the stop notification 50 {"direction": "send", "regex": r"^\$T[0-9a-fA-F]{2}thread:[0-9a-fA-F]+;"}], 51 True) 52 53 # Run the packet stream 54 context = self.expect_gdbremote_sequence() 55 self.assertIsNotNone(context) 56 57 buf_address = context.get("buffer") 58 self.assertIsNotNone(buf_address) 59 page_size = context.get("page_size") 60 self.assertIsNotNone(page_size) 61 62 # nil means we couldn't set up a tagged page because the 63 # target doesn't support it. 64 if buf_address == "(nil)": 65 self.skipTest("Target must support MTE.") 66 67 buf_address = int(buf_address, 16) 68 page_size = int(page_size, 16) 69 70 return buf_address, page_size 71 72 @skipUnlessArch("aarch64") 73 @skipUnlessPlatform(["linux"]) 74 @skipUnlessAArch64MTELinuxCompiler 75 def test_qMemTags_packets(self): 76 """ Test that qMemTags packets are parsed correctly and/or rejected. """ 77 buf_address, page_size = self.prep_memtags_test() 78 79 # Sanity check that address is correct 80 self.check_tag_read("{:x},20:1".format(buf_address), "m0001") 81 82 # Invalid packets 83 84 # No content 85 self.check_tag_read("", "E03") 86 # Only address 87 self.check_tag_read("{:x}".format(buf_address), "E03") 88 # Only address and length 89 self.check_tag_read("{:x},20".format(buf_address), "E03") 90 # Empty address 91 self.check_tag_read(",20:1", "E03") 92 # Invalid addresses 93 self.check_tag_read("aardvark,20:1", "E03") 94 self.check_tag_read("-100,20:1", "E03") 95 self.check_tag_read("cafe?,20:1", "E03") 96 # Empty length 97 self.check_tag_read("{:x},:1".format(buf_address), "E03") 98 # Invalid lengths 99 self.check_tag_read("{:x},food:1".format(buf_address), "E03") 100 self.check_tag_read("{:x},-1:1".format(buf_address), "E03") 101 self.check_tag_read("{:x},12??:1".format(buf_address), "E03") 102 # Empty type 103 self.check_tag_read("{:x},10:".format(buf_address), "E03") 104 # Types we don't support 105 self.check_tag_read("{:x},10:FF".format(buf_address), "E01") 106 # Types can also be negative, -1 in this case. 107 # So this is E01 for not supported, instead of E03 for invalid formatting. 108 self.check_tag_read("{:x},10:FFFFFFFF".format(buf_address), "E01") 109 # (even if the length of the read is zero) 110 self.check_tag_read("{:x},0:FF".format(buf_address), "E01") 111 # Invalid type format 112 self.check_tag_read("{:x},10:cat".format(buf_address), "E03") 113 self.check_tag_read("{:x},10:?11".format(buf_address), "E03") 114 # Type is signed but in packet as raw bytes, no +/-. 115 self.check_tag_read("{:x},10:-1".format(buf_address), "E03") 116 self.check_tag_read("{:x},10:+20".format(buf_address), "E03") 117 # We do use a uint64_t for unpacking but that's just an implementation 118 # detail. Any value > 32 bit is invalid. 119 self.check_tag_read("{:x},10:123412341".format(buf_address), "E03") 120 121 # Valid packets 122 123 # Reading nothing is allowed 124 self.check_tag_read("{:x},0:1".format(buf_address), "m") 125 # A range that's already aligned 126 self.check_tag_read("{:x},20:1".format(buf_address), "m0001") 127 # lldb-server should re-align the range 128 # Here we read from 1/2 way through a granule, into the next. Expands to 2 granules 129 self.check_tag_read("{:x},10:1".format(buf_address+64-8), "m0304") 130 # Read up to the end of an MTE page. 131 # We know that the last tag should be 0xF since page size will always be a 132 # multiple of 256 bytes, which is 16 granules and we have 16 tags to use. 133 self.check_tag_read("{:x},10:1".format(buf_address+page_size-16), "m0f") 134 # Here we read off of the end of the MTE range so ptrace gives us one tag, 135 # then fails on the second call. To lldb-server this means the response 136 # should just be an error, not a partial read. 137 self.check_tag_read("{:x},20:1".format(buf_address+page_size-16), "E01") 138 139 def check_tag_write(self, body, expected): 140 self.check_memtags_response("QMemTags", body, expected) 141 142 @skipUnlessArch("aarch64") 143 @skipUnlessPlatform(["linux"]) 144 @skipUnlessAArch64MTELinuxCompiler 145 def test_QMemTags_packets(self): 146 """ Test that QMemTags packets are parsed correctly and/or rejected. """ 147 buf_address, page_size = self.prep_memtags_test() 148 149 # Sanity check that address is correct 150 self.check_tag_write("{:x},10:1:0e".format(buf_address), "OK") 151 self.check_tag_read("{:x},10:1".format(buf_address), "m0e") 152 153 # No content 154 self.check_tag_write("", "E03") 155 # Only address 156 self.check_tag_write("{:x}".format(buf_address), "E03") 157 # Only address and length 158 self.check_tag_write("{:x},20".format(buf_address), "E03") 159 # Missing data 160 self.check_tag_write("{:x},20:1".format(buf_address), "E03") 161 # Zero length write must still include seperator after type 162 self.check_tag_write("{:x},0:1".format(buf_address), "E03") 163 # Empty address 164 self.check_tag_write(",10:1:01", "E03") 165 # Invalid addresses 166 self.check_tag_write("aardvark,10:1:01", "E03") 167 self.check_tag_write("-100,10:1:01", "E03") 168 self.check_tag_write("cafe?,10:1:01", "E03") 169 # Empty length 170 self.check_tag_write("{:x},:1:01".format(buf_address), "E03") 171 # Invalid lengths 172 self.check_tag_write("{:x},food:1:01".format(buf_address), "E03") 173 self.check_tag_write("{:x},-1:1:01".format(buf_address), "E03") 174 self.check_tag_write("{:x},12??:1:01".format(buf_address), "E03") 175 # Empty type 176 self.check_tag_write("{:x},10::01".format(buf_address), "E03") 177 # Types we don't support 178 self.check_tag_write("{:x},10:FF:01".format(buf_address), "E01") 179 # (even if the length of the write is zero) 180 self.check_tag_write("{:x},0:FF:".format(buf_address), "E01") 181 # Invalid type format 182 self.check_tag_write("{:x},0:cat:".format(buf_address), "E03") 183 self.check_tag_write("{:x},0:?11:".format(buf_address), "E03") 184 # Leading +/- not allowed 185 self.check_tag_write("{:x},10:-1:".format(buf_address), "E03") 186 self.check_tag_write("{:x},10:+20:".format(buf_address), "E03") 187 # We use a uint64_t when parsing, but dont expect anything > 32 bits 188 self.check_tag_write("{:x},10:123412341:".format(buf_address), "E03") 189 # Invalid tag data 190 self.check_tag_write("{:x},10:1:??".format(buf_address), "E03") 191 self.check_tag_write("{:x},10:1:45?".format(buf_address), "E03") 192 # (must be 2 chars per byte) 193 self.check_tag_write("{:x},10:1:123".format(buf_address), "E03") 194 # Tag out of range 195 self.check_tag_write("{:x},10:1:23".format(buf_address), "E01") 196 # Non-zero length write must include some tag data 197 self.check_tag_write("{:x},10:1:".format(buf_address), "E01") 198 199 # Valid packets 200 201 # Zero length write doesn't need any tag data (but should include the :) 202 self.check_tag_write("{:x},0:1:".format(buf_address), "OK") 203 # Zero length unaligned is the same 204 self.check_tag_write("{:x},0:1:".format(buf_address+8), "OK") 205 # Ranges can be aligned already 206 self.check_tag_write("{:x},20:1:0405".format(buf_address), "OK") 207 self.check_tag_read("{:x},20:1".format(buf_address), "m0405") 208 # Unaliged ranges will be aligned by the server 209 self.check_tag_write("{:x},10:1:0607".format(buf_address+8), "OK") 210 self.check_tag_read("{:x},20:1".format(buf_address), "m0607") 211 # Tags will be repeated as needed to cover the range 212 self.check_tag_write("{:x},30:1:09".format(buf_address), "OK") 213 self.check_tag_read("{:x},30:1".format(buf_address), "m090909") 214 # One more repeating tags for good measure, part repetition this time 215 # (for full tests see the MemoryTagManagerAArch64MTE unittests) 216 self.check_tag_write("{:x},30:1:0a0b".format(buf_address), "OK") 217 self.check_tag_read("{:x},30:1".format(buf_address), "m0a0b0a") 218 # We can write up to the end of the MTE page 219 last_granule = buf_address + page_size - 16; 220 self.check_tag_write("{:x},10:1:0c".format(last_granule), "OK") 221 self.check_tag_read("{:x},10:1".format(last_granule), "m0c") 222 # Writing over the end of the page is an error 223 self.check_tag_write("{:x},20:1:0d".format(last_granule), "E01") 224 # The last tag in the page was written thought, and we do not 225 # attempt to restore its original value. 226 self.check_tag_read("{:x},10:1".format(last_granule), "m0d") 227