Automatic Copyright Year update after running gdb/copyright.py
[deliverable/binutils-gdb.git] / gdb / testsuite / gdb.arch / aarch64-mte.exp
1 # Copyright (C) 2021-2022 Free Software Foundation, Inc.
2
3 # This program is free software; you can redistribute it and/or modify
4 # it under the terms of the GNU General Public License as published by
5 # the Free Software Foundation; either version 3 of the License, or
6 # (at your option) any later version.
7 #
8 # This program is distributed in the hope that it will be useful,
9 # but WITHOUT ANY WARRANTY; without even the implied warranty of
10 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 # GNU General Public License for more details.
12 #
13 # You should have received a copy of the GNU General Public License
14 # along with this program. If not, see <http://www.gnu.org/licenses/>.
15
16 # Test a binary that uses MTE and exercise various MTE-related scenarios.
17
18 global hex
19 global decimal
20
21 # Return TAG in hex format with no leading zeroes.
22 proc get_hex_tag { tag } {
23 return [format "%x" $tag]
24 }
25
26 # Return TAG in the NN format where N is 4 bits of the byte.
27 proc get_tag_nn { tag } {
28 return [format "%02x" $tag]
29 }
30
31 # Return the address of PTR with a tag of TAG.
32 proc get_tagged_ptr { tag ptr } {
33 set addr [get_hexadecimal_valueof $ptr -1]
34 return [get_valueof "/x" \
35 "${addr} & (0xf0ffffffffffffff) | ((unsigned long) ${tag} << 56)" \
36 "0" "fetch pointer ${ptr} with tag ${tag}"]
37 }
38
39 # Return the logical TAG from PTR.
40 proc get_ltag_from_ptr { ptr } {
41 set addr [get_hexadecimal_valueof $ptr -1]
42 return [get_valueof "/x" "${addr} >> 56 & 0xf" -1 \
43 "fetch tag from pointer ${ptr}"]
44 }
45
46 if {![is_aarch64_target]} {
47 verbose "Skipping ${gdb_test_file_name}."
48 return
49 }
50
51 standard_testfile
52 if { [prepare_for_testing "failed to prepare" ${testfile} ${srcfile}] } {
53 return -1
54 }
55
56 if ![runto_main] {
57 untested "could not run to main"
58 return -1
59 }
60
61 # Targets that don't support memory tagging should not execute the
62 # runtime memory tagging tests.
63 if {![supports_memtag]} {
64 unsupported "memory tagging unsupported"
65 return -1
66 }
67
68 gdb_breakpoint "access_memory"
69
70 if [gdb_continue "access_memory"] {
71 return -1
72 }
73
74 # Fetch a known pointer to an area mapped with PROT_MTE.
75 set tagged_ptr_symbol "tagged_ptr"
76 set tagged_ptr_addr [get_hexadecimal_valueof $tagged_ptr_symbol -1]
77
78 if {$tagged_ptr_addr == -1} {
79 unresolved "unexpected pointer or tag value"
80 return -1
81 }
82
83 # Fetch a known pointer to an area not mapped with PROT_MTE.
84 set untagged_ptr_symbol "untagged_ptr"
85 set untagged_ptr_addr [get_hexadecimal_valueof $untagged_ptr_symbol -1]
86
87 if {$untagged_ptr_addr == -1} {
88 unresolved "unexpected pointer or tag value"
89 return -1
90 }
91
92 with_test_prefix "literals" {
93 # Test inspecting an allocation tag from a pointer to a memory area that
94 # is not mapped with PROT_MTE.
95 set msg "Address ${untagged_ptr_addr} not in a region mapped with a memory tagging flag\."
96 gdb_test "memory-tag print-allocation-tag ${untagged_ptr_addr}" $msg \
97 "memory-tag print-allocation-tag with an untagged address"
98
99 gdb_test "memory-tag set-allocation-tag ${untagged_ptr_addr} 1 00" $msg \
100 "memory-tag set-allocation-tag with an untagged address"
101
102 set addr_tagged 0
103 set addr_tagged_valid 0
104
105 # Test setting and showing the logical tags for a literal address.
106 for {set i 0} {$i < 32} {incr i} {
107 with_test_prefix "tag ${i}" {
108 set addr_tagged [get_tagged_ptr $i ${tagged_ptr_addr}]
109 }
110
111 set tag_hexnz [get_hex_tag [expr $i % 16]]
112 gdb_test "memory-tag print-logical-tag ${addr_tagged}" \
113 " = 0x${tag_hexnz}" \
114 "print-logical-tag with tag ${i}"
115
116 set tag_hexnn [get_tag_nn $i]
117 gdb_test "memory-tag with-logical-tag ${addr_tagged} ${tag_hexnn}" \
118 " = \\(void \\*\\) ${addr_tagged}" \
119 "with-logical-tag with tag ${i}"
120 }
121
122 set atag_msg "Allocation tag\\(s\\) updated successfully\."
123 # Test setting and showing the allocation tags.
124 for {set i 0} {$i < 32} {incr i} {
125
126 set tag_hexnn [get_tag_nn $i]
127 gdb_test "memory-tag set-allocation-tag ${tagged_ptr_addr} 1 ${tag_hexnn}" \
128 $atag_msg \
129 "set-allocation-tag with tag ${i}"
130
131 set tag_hexnz [get_hex_tag [expr $i % 16]]
132 gdb_test "memory-tag print-allocation-tag ${tagged_ptr_addr}" " = 0x${tag_hexnz}" \
133 "print-allocation-tag with tag ${i}"
134 }
135
136 # Test tag mismatches.
137 with_test_prefix "tag mismatches" {
138 for {set i 0} {$i < 32} {incr i} {
139
140 # Set the allocation tag to a known value.
141 set tag_hexnn [get_tag_nn $i]
142 gdb_test "memory-tag set-allocation-tag ${tagged_ptr_addr} 1 ${tag_hexnn}" \
143 $atag_msg \
144 "set-allocation-tag with tag ${i}"
145
146 set atag_hexnz [get_hex_tag [expr $i % 16]]
147
148 # Validate that the logical tag matches the allocation tag.
149 with_test_prefix "tag ${i}" {
150 set addr_tagged [get_tagged_ptr $i ${tagged_ptr_addr}]
151 }
152
153 gdb_test "memory-tag check ${addr_tagged}" \
154 "Memory tags for address $hex match \\(0x${atag_hexnz}\\)\." \
155 "check match with tag ${i}"
156
157 # Get a pointer with the logical tag that does not match the
158 # allocation tag.
159 set ltag [expr $i + 1]
160 with_test_prefix "fetch mismatch tag ${i}" {
161 set addr_tagged [get_tagged_ptr $ltag ${tagged_ptr_addr}]
162 }
163
164 # Validate that the logical tag does not match the allocation
165 # tag.
166 set ltag_hexnz [get_hex_tag [expr [expr $i + 1]% 16]]
167 gdb_test "memory-tag check ${addr_tagged}" \
168 "Logical tag \\(0x${ltag_hexnz}\\) does not match the allocation tag \\(0x${atag_hexnz}\\) for address $hex\." \
169 "check mismatch with tag ${i}"
170 }
171 }
172 }
173
174 with_test_prefix "symbolic" {
175 # Test inspecting an allocation tag from a pointer to a memory area that
176 # is not mapped with PROT_MTE.
177 set msg "Address ${untagged_ptr_addr} not in a region mapped with a memory tagging flag\."
178 gdb_test "memory-tag print-allocation-tag ${untagged_ptr_symbol}" $msg \
179 "memory-tag print-allocation-tag with an untagged address"
180
181 gdb_test "memory-tag set-allocation-tag ${untagged_ptr_symbol} 1 00" $msg \
182 "memory-tag set-allocation-tag with an untagged address"
183
184 # Test setting and showing the logical tags for a literal address.
185 for {set i 0} {$i < 32} {incr i} {
186 set addr_tagged 0
187
188 with_test_prefix "tag ${i}" {
189 set addr_tagged [get_tagged_ptr $i ${tagged_ptr_addr}]
190 gdb_test_no_output "set variable ${tagged_ptr_symbol} = ${addr_tagged}" \
191 "update value of symbol ${tagged_ptr_symbol}"
192 }
193
194 set tag_hexnz [get_hex_tag [expr $i % 16]]
195 gdb_test "memory-tag print-logical-tag ${tagged_ptr_symbol}" \
196 " = 0x${tag_hexnz}" \
197 "print-logical-tag with tag ${i}"
198
199 set tag_hexnn [get_tag_nn $i]
200 gdb_test "memory-tag with-logical-tag ${tagged_ptr_symbol} ${tag_hexnn}" \
201 " = \\(void \\*\\) ${addr_tagged}" \
202 "with-logical-tag with tag ${i}"
203 }
204
205 # Reset the tagged ptr to its original value
206 gdb_test_no_output "set variable ${tagged_ptr_symbol} = ${tagged_ptr_addr}" \
207 "reset ${tagged_ptr_symbol} to ${tagged_ptr_addr}"
208
209 set atag_msg "Allocation tag\\(s\\) updated successfully\."
210 # Test setting and showing the allocation tags.
211 for {set i 0} {$i < 32} {incr i} {
212
213 set tag_hexnn [get_tag_nn $i]
214 gdb_test "memory-tag set-allocation-tag ${tagged_ptr_symbol} 1 ${tag_hexnn}" \
215 $atag_msg \
216 "set-allocation-tag with tag ${i}"
217
218 set tag_hexnz [get_hex_tag [expr $i % 16]]
219 gdb_test "memory-tag print-allocation-tag ${tagged_ptr_symbol}" \
220 " = 0x${tag_hexnz}" \
221 "print-allocation-tag with tag ${i}"
222 }
223
224 # Test tag mismatches.
225 with_test_prefix "tag mismatches" {
226 for {set i 0} {$i < 32} {incr i} {
227
228 # Set the allocation tag to a known value (0).
229 set tag_hexnn [get_tag_nn $i]
230 gdb_test "memory-tag set-allocation-tag ${tagged_ptr_symbol} 1 ${tag_hexnn}" \
231 $atag_msg \
232 "set-allocation-tag with tag ${i}"
233
234 set atag_hexnz [get_hex_tag [expr $i % 16]]
235
236 # Validate that the logical tag matches the allocation tag.
237 with_test_prefix "tag ${i}" {
238 set addr_tagged [get_tagged_ptr $i ${tagged_ptr_addr}]
239 }
240
241 with_test_prefix "tag ${i}" {
242 gdb_test_no_output "set variable ${tagged_ptr_symbol} = ${addr_tagged}" \
243 "set ${tagged_ptr_symbol} to a matching logical tag"
244 }
245
246 gdb_test "memory-tag check ${tagged_ptr_symbol}" \
247 "Memory tags for address $hex match \\(0x${atag_hexnz}\\)\." \
248 "check match with tag ${i}"
249
250 # Get a pointer with the logical tag that does not match the
251 # allocation tag.
252 set ltag [expr $i + 1]
253 with_test_prefix "fetch mismatch tag ${i}" {
254 set addr_tagged [get_tagged_ptr $ltag ${tagged_ptr_addr}]
255 }
256
257 with_test_prefix "tag ${i}" {
258 gdb_test_no_output "set variable ${tagged_ptr_symbol} = ${addr_tagged}" \
259 "set ${tagged_ptr_symbol} to a mismatching logical tag"
260 }
261
262 # Validate that the logical tag does not match the allocation
263 # tag.
264 set ltag_hexnz [get_hex_tag [expr [expr $i + 1]% 16]]
265 gdb_test "memory-tag check ${tagged_ptr_symbol}" \
266 "Logical tag \\(0x${ltag_hexnz}\\) does not match the allocation tag \\(0x${atag_hexnz}\\) for address $hex\." \
267 "check mismatch with tag ${i}"
268 }
269 # Reset the tagged ptr to its original value
270 gdb_test_no_output "set variable ${tagged_ptr_symbol} = ${tagged_ptr_addr}" \
271 "reset ${tagged_ptr_symbol} to ${tagged_ptr_addr}"
272 }
273 }
274
275 # Test the memory tagging extensions for the "print" command.
276 with_test_prefix "print command" {
277 set untagged_ptr [get_tagged_ptr 0 ${tagged_ptr_addr}]
278
279 with_test_prefix "fetch ltag" {
280 set ltag [get_ltag_from_ptr ${tagged_ptr_addr}]
281 }
282
283 if {$ltag == -1} {
284 unresolved "unexpected tag value"
285 return -1
286 }
287
288 set atag [expr [expr $ltag + 1] % 16]
289 set atag_hexnn [get_tag_nn $atag]
290
291 gdb_test "memory-tag set-allocation-tag ${tagged_ptr_symbol} 1 ${atag_hexnn}" \
292 $atag_msg \
293 "make atag and ltag different"
294
295 set atag_hexnz [get_hex_tag $atag]
296 gdb_test "p/x ${tagged_ptr_symbol}" \
297 [multi_line \
298 "Logical tag \\(${ltag}\\) does not match the allocation tag \\(0x${atag_hexnz}\\)\." \
299 "\\\$\[0-9\]+ = ${untagged_ptr}"] \
300 "show tag mismatch"
301 }
302
303 # Test the memory tagging extensions for the "x" command.
304 with_test_prefix "x command" {
305
306 # Check if the allocation tags match what we expect.
307 gdb_test "x/gxm ${tagged_ptr_symbol}" \
308 [multi_line \
309 "<Allocation Tag $hex for range \\\[$hex,$hex\\)>" \
310 "$hex:\[ \t\]+$hex"] \
311 "outputs tag information"
312
313 # Also make sure no tag information is output for memory areas without
314 # PROT_MTE mappings.
315 gdb_test "x/gxm ${untagged_ptr_symbol}" \
316 "$hex:\[ \t\]+$hex" \
317 "does not output tag information"
318 }
319
320 # Validate the presence of the MTE registers.
321 foreach reg {"tag_ctl" } {
322 gdb_test "info registers $reg" \
323 "$reg\[ \t\]+$hex\[ \t\]+$decimal" \
324 "register $reg available"
325 }
326
327 # Run until a crash and confirm GDB displays memory tag violation
328 # information.
329 gdb_test "continue" \
330 [multi_line \
331 "Program received signal SIGSEGV, Segmentation fault" \
332 "Memory tag violation while accessing address $hex" \
333 "Allocation tag $hex" \
334 "Logical tag $hex\." \
335 "$hex in access_memory \\(.*\\) at .*" \
336 ".*tagged_ptr\\\[0\\\] = 'a';"] \
337 "display tag violation information"
338
339 # Restart to execute the async tag fault test.
340 with_test_prefix "async" {
341 if ![runto_main] {
342 untested "could not run to main"
343 return -1
344 }
345
346 gdb_breakpoint "access_memory"
347
348 if [gdb_continue "access_memory"] {
349 fail "could not run to tagged memory test function"
350 return -1
351 }
352
353 # Force a tag fault.
354 gdb_test "memory-tag set-allocation-tag tagged_ptr 1 05" \
355 $atag_msg \
356 "make atag and ltag different"
357
358 # Force the tag fault to be async.
359 gdb_test_no_output "set \$tag_ctl=0x7fff5" "set tag_ctl to async"
360
361 # Run until a crash and confirm GDB displays memory tag violation
362 # information for async mode
363 gdb_test "continue" \
364 [multi_line \
365 "Program received signal SIGSEGV, Segmentation fault" \
366 "Memory tag violation" \
367 "Fault address unavailable\." \
368 "$hex in .* \\(.*\\) .*"] \
369 "display tag violation information"
370 }
This page took 0.037962 seconds and 4 git commands to generate.