Re: ld plugin bfd_make_readable leak
[binutils-gdb.git] / gdb / testsuite / gdb.base / examine-backward.exp
blobfe3d13e8d1006bd08ba8455dfee08261867765e2
1 # Copyright 2015-2024 Free Software Foundation, Inc.
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.
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.
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/>.
16 # This testsuite is to test examining memory backward by specifying a negative
17 # number in the 'x' command.
19 standard_testfile
20 if { [prepare_for_testing "failed to prepare for examine-backward" \
21         ${testfile} ${srcfile}] } {
22     return -1
25 if ![runto_main] {
26     return -1
29 proc get_first_mapped_address {} {
30     global gdb_prompt
32     set addr "0"
33     gdb_test_multiple "info proc mappings" "info proc mappings" {
34         -re "objfile\[\r\n\t \]+(0x\[0-9a-fA-F\]+).*\[\r\n\]*$gdb_prompt $" {
35             set addr $expect_out(1,string)
36         }
37         -re "$gdb_prompt $" {
38             unsupported "current target does not support 'info proc mappings'"
39         }
40     }
41     return ${addr}
44 with_test_prefix "invalid format" {
45     gdb_test "x/- 10xb main" "Invalid number \"10xb\"\." \
46         "a whitespace after a leading hyphen"
47     gdb_test "x/--10xb main" "Invalid number \"10xb\"\." \
48         "double hyphen"
49     gdb_test "x/-a10xb main" "Invalid number \"10xb\"\." \
50         "an alphabet after a leading hyphen"
51     gdb_test_no_output "x/-0i main" "zero with backward disassemble"
52     gdb_test_no_output "x/-0sh main" "zero with backward examine string"
55 with_test_prefix "memory page boundary" {
56     set boundary [get_first_mapped_address]
57     if {![is_address_zero_readable] && $boundary != 0} {
58         gdb_test_no_output "set print elements 0"
59         gdb_test_sequence "x/3s ${boundary}" "take 3 strings forward" {
60             "0x"
61             "0x"
62             "0x"
63         }
64         gdb_test_sequence "x/-4s" "take 4 strings backward" {
65             "Cannot access memory at address 0x"
66             "0x"
67             "0x"
68             "0x"
69         }
70         gdb_test_sequence "x/3s ${boundary}" "take 3 strings forward again" {
71             "0x"
72             "0x"
73             "0x"
74         }
75         gdb_test_sequence "x/-3s" "take 3 strings backward" {
76             "Cannot access memory at address 0x"
77             "0x"
78             "0x"
79             "0x"
80         }
81     }
84 with_test_prefix "address zero boundary" {
85     global gdb_prompt
87     set address_zero "0x0"
88     set byte "\t0x\[0-9a-f\]+"
90     set test "examine 3 bytes forward from ${address_zero}"
91     gdb_test_multiple "x/3xb ${address_zero}" "$test" {
92         -re "0x\[0-9a-f\]*0.*:${byte}${byte}${byte}\[\r\n\]*$gdb_prompt $" {
93             pass $test
94         }
95         -re "0x\[0-9a-f\]*0.*:\tCannot access memory at address 0x\[0-9a-f\]*0\[\r\n\]*$gdb_prompt $" {
96             # If we failed to read address 0 then this is fine, so
97             # long as we're not expecting to be able to read from
98             # address 0.
99             if {![is_address_zero_readable]} {
100                 # The next test assumes that the last address examined
101                 # would be 0x2.  As we just failed to read address 0x0
102                 # things are going to go wrong unless we now tell GDB
103                 # to examine address 0x2.  We assume here that if we
104                 # can't read 0x0 we can't read 0x2 either.
105                 gdb_test "x/3xb 0x2" "Cannot access memory at address 0x\[0-9a-f\]*2" \
106                     "set last examined address to 0x2"
107                 pass $test
108             } else {
109                 fail $test
110             }
111         }
112     }
114     set test "examine 6 bytes backward"
115     gdb_test_multiple "x/-6x" "$test" {
116         -re "0x\[0-9a-f\]+fd.*:${byte}${byte}${byte}${byte}${byte}${byte}.*\[\r\n\]*$gdb_prompt $" {
117             pass $test
118         }
119         -re "0x\[0-9a-f\]+fd.*:\tCannot access memory at address 0x\[0-9a-f\]+fd.*\[\r\n\]*$gdb_prompt $" {
120             # We may, or may not have managed to read from address 0x0
121             # in the previous test, however, being able to read 0x0 is
122             # no guarantee that we can read from the other end of the
123             # address space.  If we get an error about trying to read
124             # from the expected address then we count that as a pass,
125             # GDB did try to read the correct location, and this test
126             # is (mostly) about does GDB calculate the correct address
127             # when wrapping around.
128             pass $test
129         }
130     }
132     set test "examine 3 bytes backward from ${address_zero}"
133     gdb_test_multiple "x/-3x ${address_zero}" "$test" {
134         -re "0x\[0-9a-f\]+fd.*:${byte}${byte}${byte}.*\[\r\n\]*$gdb_prompt $" {
135             pass $test
136         }
137         -re "0x\[0-9a-f\]+fd.*:\tCannot access memory at address 0x\[0-9a-f\]+fd.*\[\r\n\]*$gdb_prompt $" {
138             # See previous test for why this is a pass.
139             pass $test
140         }
141     }
144 gdb_test_no_output "set charset ASCII"
146 with_test_prefix "char-width=1, print-max=20" {
147     gdb_test_no_output "set print elements 20"
148     gdb_test_sequence "x/6s TestStrings" "take 6 strings forward" {
149         "\"ABCDEFGHIJKLMNOPQRST\"\.\.\."
150         "\"UVWXYZ\""
151         "\"\""
152         "\"\""
153         "\"[^\"]+\""
154         "\"01234567890123456789\"\.\.\."
155     }
156     gdb_test "x/-1xb" "0x39" "take 1 char backward"
157     gdb_test_sequence "x/-6s" "take 6 strings backward" {
158         "\"ABCDEFGHIJKLMNOPQRST\"\.\.\."
159         "\"UVWXYZ\""
160         "\"\""
161         "\"\""
162         "\"[^\"]+\""
163         "\"01234567890123456789\"\.\.\."
164     }
165     gdb_test_sequence "x/6s TestStrings" "take 6 strings forward again" {
166         "\"ABCDEFGHIJKLMNOPQRST\"\.\.\."
167         "\"UVWXYZ\""
168         "\"\""
169         "\"\""
170         "\"[^\"]+\""
171         "\"01234567890123456789\"\.\.\."
172     }
173     gdb_test "x/-xb" "0x39" "take 1 char backward again"
174     gdb_test "x/-s" "\"01234567890123456789\"\.\.\." \
175         "take 1 string backward, 1/6"
176     gdb_test "x/-s" "\".+\"" \
177         "take 1 string backward, 2/6"
178     gdb_test "x/-s" "\"\"" \
179         "take 1 string backward, 3/6"
180     gdb_test "x/-s" "\"\"" \
181         "take 1 string backward, 4/6"
182     gdb_test "x/-s" "\"GHIJKLMNOPQRSTUVWXYZ\"" \
183         "take 1 string backward, 5/6"
184     gdb_test "x/-s" "\"ABCDEFGHIJKLMNOPQRST\"\.\.\." \
185         "take 1 string backward, 6/6"
188 with_test_prefix "char-width=2, print-max=20" {
189     gdb_test_no_output "set print elements 20"
190     gdb_test_sequence "x/6sh TestStringsH" "take 6 strings forward" {
191         "u\"ABCDEFGHIJKLMNOPQRST\"\.\.\."
192         "u\"UVWXYZ\""
193         "u\"\""
194         "u\"\""
195         "u\"[^\"]+\""
196         "u\"01234567890123456789\"\.\.\."
197     }
198     gdb_test "x/-1xh" "0x0039" "take 1 char backward"
199     gdb_test_sequence "x/-6sh" "take 6 strings backward" {
200         "u\"ABCDEFGHIJKLMNOPQRST\"\.\.\."
201         "u\"UVWXYZ\""
202         "u\"\""
203         "u\"\""
204         "u\"[^\"]+\""
205         "u\"01234567890123456789\"\.\.\."
206     }
207     gdb_test_sequence "x/6sh TestStringsH" "take 6 strings forward again" {
208         "u\"ABCDEFGHIJKLMNOPQRST\"\.\.\."
209         "u\"UVWXYZ\""
210         "u\"\""
211         "u\"\""
212         "u\"[^\"]+\""
213         "u\"01234567890123456789\"\.\.\."
214     }
215     gdb_test "x/-xh" "0x0039" "take 1 char backward again"
216     gdb_test "x/-sh" "u\"01234567890123456789\"\.\.\." \
217         "take 1 string backward, 1/6"
218     gdb_test "x/-sh" "u\".+\"" \
219         "take 1 string backward, 2/6"
220     gdb_test "x/-sh" "u\"\"" \
221         "take 1 string backward, 3/6"
222     gdb_test "x/-sh" "u\"\"" \
223         "take 1 string backward, 4/6"
224     gdb_test "x/-sh" "u\"GHIJKLMNOPQRSTUVWXYZ\"" \
225         "take 1 string backward, 5/6"
226     gdb_test "x/-sh" "u\"ABCDEFGHIJKLMNOPQRST\"\.\.\." \
227         "take 1 string backward, 6/6"
230 with_test_prefix "char-width=4, print-max=20" {
231     gdb_test_no_output "set print elements 20"
232     gdb_test_sequence "x/6sw TestStringsW" "take 6 strings forward" {
233         "U\"ABCDEFGHIJKLMNOPQRST\"\.\.\."
234         "U\"UVWXYZ\""
235         "U\"\""
236         "U\"\""
237         "U\"[^\"]+\""
238         "U\"01234567890123456789\"\.\.\."
239     }
240     gdb_test "x/-1xw" "0x00000039" "take 1 char backward"
241     gdb_test_sequence "x/-6sw" "take 6 strings backward" {
242         "U\"ABCDEFGHIJKLMNOPQRST\"\.\.\."
243         "U\"UVWXYZ\""
244         "U\"\""
245         "U\"\""
246         "U\"[^\"]+\""
247         "U\"01234567890123456789\"\.\.\."
248     }
249     gdb_test_sequence "x/6sw TestStringsW" "take 6 strings forward again" {
250         "U\"ABCDEFGHIJKLMNOPQRST\"\.\.\."
251         "U\"UVWXYZ\""
252         "U\"\""
253         "U\"\""
254         "U\"[^\"]+\""
255         "U\"01234567890123456789\"\.\.\."
256     }
257     gdb_test "x/-xw" "0x00000039" "take 1 char backward again"
258     gdb_test "x/-sw" "U\"01234567890123456789\"\.\.\." \
259         "take 1 string backward, 1/6"
260     gdb_test "x/-sw" "U\".+\"" \
261         "take 1 string backward, 2/6"
262     gdb_test "x/-sw" "U\"\"" \
263         "take 1 string backward, 3/6"
264     gdb_test "x/-sw" "U\"\"" \
265         "take 1 string backward, 4/6"
266     gdb_test "x/-sw" "U\"GHIJKLMNOPQRSTUVWXYZ\"" \
267         "take 1 string backward, 5/6"
268     gdb_test "x/-sw" "U\"ABCDEFGHIJKLMNOPQRST\"\.\.\." \
269         "take 1 string backward, 6/6"
272 with_test_prefix "char-width=2, print-max=0" {
273     gdb_test_no_output "set print elements 0"
274     gdb_test_sequence "x/6sh TestStringsH" "take 6 strings forward" {
275         "u\"ABCDEFGHIJKLMNOPQRSTUVWXYZ\""
276         "u\"\""
277         "u\"\""
278         "u\"\\\\x307b\\\\x3052\\\\x307b\\\\x3052\""
279         "u\"012345678901234567890123456789\""
280         "u\"!!!!!!\""
281     }
282     gdb_test "x/-4xh" "0x0021\[\t \]+0x0021\[\t \]+0x0021\[\t \]+0x0000" \
283         "take 4 characters backward"
284     gdb_test_sequence "x/-6sh" "take 6 strings backward" {
285         "u\"ABCDEFGHIJKLMNOPQRSTUVWXYZ\""
286         "u\"\""
287         "u\"\""
288         "u\"[^\"]+\""
289         "u\"012345678901234567890123456789\""
290         "u\"!!!!!!\""
291     }
292     gdb_test_sequence "x/6sh TestStringsH" "take 6 strings forward again" {
293         "u\"ABCDEFGHIJKLMNOPQRSTUVWXYZ\""
294         "u\"\""
295         "u\"\""
296         "u\"\\\\x307b\\\\x3052\\\\x307b\\\\x3052\""
297         "u\"012345678901234567890123456789\""
298         "u\"!!!!!!\""
299     }
300     gdb_test "x/-xh" "0x0000" "take 1 char backward"
301     gdb_test "x/-sh" "u\"!!!!!!\"" \
302         "take 1 string backward, 1/6"
303     gdb_test "x/-sh" "u\"012345678901234567890123456789\"" \
304         "take 1 string backward, 2/6"
305     gdb_test "x/-sh" "u\".+\"" \
306         "take 1 string backward, 3/6"
307     gdb_test "x/-sh" "u\"\"" \
308         "take 1 string backward, 4/6"
309     gdb_test "x/-sh" "u\"\"" \
310         "take 1 string backward, 5/6"
311     gdb_test "x/-sh" "u\"ABCDEFGHIJKLMNOPQRSTUVWXYZ\"" \
312         "take 1 string backward, 6/6"
315 with_test_prefix "char-width=1, print-max=4" {
316     gdb_test_no_output "set print elements 4"
317     gdb_test_sequence "x/9s TestStrings" "take 9 strings forward" {
318         "\"ABCD\"\.\.\."
319         "\"EFGH\"\.\.\."
320         "\"IJKL\"\.\.\."
321         "\"MNOP\"\.\.\."
322         "\"QRST\"\.\.\."
323         "\"UVWX\"\.\.\."
324         "\"YZ\""
325         "\"\""
326         "\"\""
327     }
328     gdb_test "x/-xb" "0x00" "take 1 byte backward"
329     gdb_test_sequence "x/-4s" "take 4 strings backward, 1/2" {
330         "\"TUVW\"\.\.\."
331         "\"XYZ\""
332         "\"\""
333         "\"\""
334     }
335     gdb_test_sequence "x/-4s" "take 4 strings backward, 2/2" {
336         "\"CDEF\"\.\.\."
337         "\"GHIJ\"\.\.\."
338         "\"KLMN\"\.\.\."
339         "\"OPQR\"\.\.\."
340     }
343 with_test_prefix "backward disassemble general" {
344     set length_to_examine {1 2 3 4 10}
345     set disassmbly {}
347     gdb_test_no_output "set print asm-demangle on"
348     set main_re "main(\\(\\))?"
350     gdb_test "x/i main" "0x\[0-9a-fA-F\]+ <$main_re>:\t.*" \
351         "move the current position to main, x/i"
352     gdb_test "x/-i" "0x\[0-9a-fA-F\]+ <$main_re>:\t.*" \
353         "move the current position to main, x/-i"
354     for {set i 0} {$i < [llength $length_to_examine]} {incr i} {
355         set len [lindex $length_to_examine $i]
356         set instructions [capture_command_output "x/${len}i" ""]
357         lappend disassmbly $instructions
358     }
359     for {set i 0} {$i < [llength $length_to_examine]} {incr i} {
360         set idx [expr [llength $length_to_examine] - $i - 1]
361         set len [lindex $length_to_examine $idx]
362         set actual [capture_command_output "x/-${len}i" ""]
363         set expected [lindex $disassmbly $idx]
364         if {$actual == $expected} {
365             pass "inst:$idx"
366         } else {
367             fail "inst:$idx"
368         }
369     }