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