Automatic Copyright Year update after running gdb/copyright.py
[deliverable/binutils-gdb.git] / gdb / testsuite / gdb.arch / aarch64-mte.exp
CommitLineData
88b9d363 1# Copyright (C) 2021-2022 Free Software Foundation, Inc.
bf0aecce
LM
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
18global hex
19global decimal
20
21# Return TAG in hex format with no leading zeroes.
22proc 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.
27proc get_tag_nn { tag } {
28 return [format "%02x" $tag]
29}
30
31# Return the address of PTR with a tag of TAG.
32proc 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.
40proc 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
46if {![is_aarch64_target]} {
47 verbose "Skipping ${gdb_test_file_name}."
48 return
49}
50
51standard_testfile
52if { [prepare_for_testing "failed to prepare" ${testfile} ${srcfile}] } {
53 return -1
54}
55
56if ![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.
63if {![supports_memtag]} {
64 unsupported "memory tagging unsupported"
65 return -1
66}
67
68gdb_breakpoint "access_memory"
69
70if [gdb_continue "access_memory"] {
71 return -1
72}
73
74# Fetch a known pointer to an area mapped with PROT_MTE.
75set tagged_ptr_symbol "tagged_ptr"
76set tagged_ptr_addr [get_hexadecimal_valueof $tagged_ptr_symbol -1]
77
78if {$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.
84set untagged_ptr_symbol "untagged_ptr"
85set untagged_ptr_addr [get_hexadecimal_valueof $untagged_ptr_symbol -1]
86
87if {$untagged_ptr_addr == -1} {
88 unresolved "unexpected pointer or tag value"
89 return -1
90}
91
92with_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
174with_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.
276with_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.
304with_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.
321foreach 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.
329gdb_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.
340with_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.111086 seconds and 4 git commands to generate.