]> git.ipfire.org Git - thirdparty/binutils-gdb.git/blob - gdb/testsuite/gdb.base/dump.exp
Automatic date update in version.in
[thirdparty/binutils-gdb.git] / gdb / testsuite / gdb.base / dump.exp
1 # Copyright 2002-2024 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 # This file was written by Michael Snyder (msnyder@redhat.com)
17 # This is a test for the gdb command "dump".
18
19
20 standard_testfile
21
22 set options {debug}
23
24 set is64bitonly "no"
25 set endian "auto"
26
27 set formats {binary ihex srec tekhex verilog}
28
29 if {[istarget "alpha*-*-*"]} {
30 # SREC etc cannot handle 64-bit addresses. Force the test
31 # program into the low 31 bits of the address space.
32 lappend options "ldflags=-Wl,-taso"
33 }
34
35 # Runs the command 'print zero_all ()'. Uses the PRINT_ZERO_ALL_COUNT
36 # global to ensure the test names are unique.
37 set print_zero_all_count 0
38 proc print_zero_all { } {
39 global print_zero_all_count
40
41 incr print_zero_all_count
42 gdb_test "print zero_all ()" " = void" \
43 "call ${print_zero_all_count} to zero_all function"
44 }
45
46 # Debian9/Ubuntu16.10 onwards default to PIE enabled. Ensure it is disabled as
47 # this causes addresses to be out of range for IHEX.
48 lappend options {nopie}
49
50 if { [gdb_compile "${srcdir}/${subdir}/${srcfile}" "${binfile}" executable ${options}] != "" } {
51 untested "failed to compile"
52 return -1
53 }
54
55 clean_restart $binfile
56
57 gdb_test "dump mem /dev/null 0x10 0x20" "Cannot access memory at address 0x10" \
58 "inaccessible memory is reported"
59
60 gdb_load ${binfile}
61
62 # Check the address of a variable. If it is bigger than 32-bit,
63 # assume our target has 64-bit addresses that are not supported by SREC,
64 # IHEX and TEKHEX. We skip those tests then.
65 set max_32bit_address "0xffffffff"
66 set data_address [get_hexadecimal_valueof "&intarray" 0x100000000]
67 if {${data_address} > ${max_32bit_address}} {
68 set is64bitonly "yes"
69 }
70
71 # Clean up any stale output files from previous test runs
72
73 set filenames {}
74 set all_files {
75 intarr1.bin intarr1b.bin intarr1.ihex
76 intarr1.srec intarr1.tekhex intarr1.verilog
77 intarr2.bin intarr2b.bin intarr2.ihex
78 intarr2.srec intarr2.tekhex intarr2.verilog
79 intstr1.bin intstr1b.bin intstr1.ihex
80 intstr1.srec intstr1.tekhex intstr1.verilog
81 intstr2.bin intstr2b.bin intstr2.ihex
82 intstr2.srec intstr2.tekhex intstr2.verilog
83 intarr3.srec
84 }
85
86 # This loop sets variables dynamically -- each name listed in
87 # $ALL_FILES is both a file name and a variable name.
88 foreach file $all_files {
89 if {[is_remote host]} {
90 set this_name $file
91 } else {
92 set this_name [standard_output_file $file]
93 }
94
95 lappend filenames [set ${file} $this_name]
96 }
97
98 remote_exec host "rm -f $filenames"
99
100 # Test help (FIXME:)
101
102 # Run target program until data structs are initialized.
103
104 if {![runto checkpoint1]} {
105 untested "couldn't run to checkpoint"
106 return -1
107 }
108
109 # Get the endianness for the later use with endianless formats.
110
111 set endian [get_endianness]
112
113 # Now generate some dump files.
114
115 proc make_dump_file { command msg } {
116 global gdb_prompt
117
118 gdb_test_multiple "${command}" "$msg" {
119 -re ".*\[Ee\]rror.*$gdb_prompt $" { fail $msg }
120 -re ".*\[Ww\]arning.*$gdb_prompt $" { fail $msg }
121 -re ".*\[Uu\]ndefined .*$gdb_prompt $" { fail $msg }
122 -re ".*$gdb_prompt $" { pass $msg }
123 }
124 }
125
126 make_dump_file "dump val [set intarr1.bin] intarray" \
127 "dump array as value, default"
128
129 make_dump_file "dump val [set intstr1.bin] intstruct" \
130 "dump struct as value, default"
131
132 make_dump_file "dump bin val [set intarr1b.bin] intarray" \
133 "dump array as value, binary"
134
135 make_dump_file "dump bin val [set intstr1b.bin] intstruct" \
136 "dump struct as value, binary"
137
138 make_dump_file "dump srec val [set intarr1.srec] intarray" \
139 "dump array as value, srec"
140
141 make_dump_file "dump srec val [set intstr1.srec] intstruct" \
142 "dump struct as value, srec"
143
144 # 64-bit address out of range for Intel Hex file
145 if {![string compare $is64bitonly "no"]} {
146 make_dump_file "dump ihex val [set intarr1.ihex] intarray" \
147 "dump array as value, intel hex"
148
149 make_dump_file "dump ihex val [set intstr1.ihex] intstruct" \
150 "dump struct as value, intel hex"
151 }
152
153 make_dump_file "dump tekhex val [set intarr1.tekhex] intarray" \
154 "dump array as value, tekhex"
155
156 make_dump_file "dump tekhex val [set intstr1.tekhex] intstruct" \
157 "dump struct as value, tekhex"
158
159 make_dump_file "dump verilog val [set intarr1.verilog] intarray" \
160 "dump array as value, verilog"
161
162 make_dump_file "dump verilog val [set intstr1.verilog] intstruct" \
163 "dump struct as value, verilog"
164
165 proc capture_value { expression args } {
166 global gdb_prompt
167 global expect_out
168
169 set output_string ""
170 if {[llength $args] > 0} {
171 # Convert $args into a simple string and don't use EXPRESSION
172 # in the test name.
173 set test "[join $args]; capture"
174 } {
175 set test "capture $expression"
176 }
177 gdb_test_multiple "print ${expression}" "$test" {
178 -re "\\$\[0-9\]+ = (\[^\r\n\]+).*$gdb_prompt $" {
179 set output_string "$expect_out(1,string)"
180 pass "$test"
181 }
182 -re "(Cannot access memory at address \[^\r\n\]+).*$gdb_prompt $" {
183 # Even a failed value is valid
184 set output_string "$expect_out(1,string)"
185 pass "$test"
186 }
187 }
188 return $output_string
189 }
190
191 # POINTER is a pointer and this proc captures the value of POINTER along
192 # with POINTER's type. For example, POINTER is "&intarray", this proc will
193 # call "p &intarray", capture "(int (*)[32]) 0x804a0e0", and return this
194 # string.
195
196 proc capture_pointer_with_type { pointer } {
197 global gdb_prompt
198 global expect_out
199
200 set test "capture type of pointer $pointer"
201 set output_string ""
202 gdb_test_multiple "p ${pointer}" $test {
203 -re "\\$\[0-9\]+ = .*$gdb_prompt $" {
204 # Expected output of "p ${pointer}" is like "$7 = (int (*)[32]) 0x804a0e0",
205 # and we want to extract "(int (*)[32]) 0x804a0e0" from it via
206 # following regexp.
207 if [regexp " \\(.*\\).* 0x\[0-9a-fA-F\]+" $expect_out(0,string) output_string] {
208 # OUTPUT_STRING is expected to be like "(int (*)[32]) 0x804a0e0".
209 pass "$test"
210 } else {
211 fail "$test"
212 }
213 }
214 }
215
216 return $output_string
217 }
218
219 set array_start [capture_value "/x &intarray\[0\]"]
220 set array_end [capture_value "/x &intarray\[32\]"]
221 set struct_start [capture_value "/x &intstruct"]
222 set struct_end [capture_value "/x &intstruct + 1"]
223
224 set array_val [capture_value "intarray"]
225 set struct_val [capture_value "intstruct"]
226
227 set array_ptr_type [capture_pointer_with_type "&intarray"]
228 set struct_ptr_type [capture_pointer_with_type "&intstruct"]
229
230 make_dump_file "dump mem [set intarr2.bin] $array_start $array_end" \
231 "dump array as memory, default"
232
233 make_dump_file "dump mem [set intstr2.bin] $struct_start $struct_end" \
234 "dump struct as memory, default"
235
236 make_dump_file "dump bin mem [set intarr2b.bin] $array_start $array_end" \
237 "dump array as memory, binary"
238
239 make_dump_file "dump bin mem [set intstr2b.bin] $struct_start $struct_end" \
240 "dump struct as memory, binary"
241
242 make_dump_file "dump srec mem [set intarr2.srec] $array_start $array_end" \
243 "dump array as memory, srec"
244
245 make_dump_file "dump srec mem [set intstr2.srec] $struct_start $struct_end" \
246 "dump struct as memory, srec"
247
248 # 64-bit address out of range for Intel Hex file
249 if {![string compare $is64bitonly "no"]} {
250 make_dump_file "dump ihex mem [set intarr2.ihex] $array_start $array_end" \
251 "dump array as memory, ihex"
252
253 make_dump_file "dump ihex mem [set intstr2.ihex] $struct_start $struct_end" \
254 "dump struct as memory, ihex"
255 }
256
257 make_dump_file "dump tekhex mem [set intarr2.tekhex] $array_start $array_end" \
258 "dump array as memory, tekhex"
259
260 make_dump_file "dump tekhex mem [set intstr2.tekhex] $struct_start $struct_end" \
261 "dump struct as memory, tekhex"
262
263 make_dump_file "dump verilog mem [set intarr2.verilog] $array_start $array_end" \
264 "dump array as memory, verilog"
265
266 make_dump_file "dump verilog mem [set intstr2.verilog] $struct_start $struct_end" \
267 "dump struct as memory, verilog"
268
269 # test complex expressions
270 make_dump_file \
271 "dump srec mem [set intarr3.srec] &intarray \(char *\) &intarray + sizeof intarray" \
272 "dump array as mem, srec, expressions"
273
274 proc test_restore_saved_value { restore_args msg oldval newval } {
275 global gdb_prompt
276
277 gdb_test "restore $restore_args" \
278 "Restoring .*" \
279 "$msg; file restored ok"
280 if { ![string compare $oldval \
281 [capture_value $newval "$msg"]] } then {
282 pass "$msg; value restored ok"
283 } else {
284 fail "$msg; value restored ok"
285 }
286 }
287
288 if {![string compare $is64bitonly "no"]} {
289
290
291 test_restore_saved_value "[set intarr1.srec]" "array as value, srec" \
292 $array_val "intarray"
293
294 test_restore_saved_value "[set intstr1.srec]" "struct as value, srec" \
295 $struct_val "intstruct"
296
297 print_zero_all
298
299 test_restore_saved_value "[set intarr2.srec]" "array as memory, srec" \
300 $array_val "intarray"
301
302 test_restore_saved_value "[set intstr2.srec]" "struct as memory, srec" \
303 $struct_val "intstruct"
304
305 print_zero_all
306
307 test_restore_saved_value "[set intarr1.ihex]" "array as value, ihex" \
308 $array_val "intarray"
309
310 test_restore_saved_value "[set intstr1.ihex]" "struct as value, ihex" \
311 $struct_val "intstruct"
312
313 print_zero_all
314
315 test_restore_saved_value "[set intarr2.ihex]" "array as memory, ihex" \
316 $array_val "intarray"
317
318 test_restore_saved_value "[set intstr2.ihex]" "struct as memory, ihex" \
319 $struct_val "intstruct"
320
321 print_zero_all
322
323 test_restore_saved_value "[set intarr1.tekhex]" "array as value, tekhex" \
324 $array_val "intarray"
325
326 test_restore_saved_value "[set intstr1.tekhex]" "struct as value, tekhex" \
327 $struct_val "intstruct"
328
329 print_zero_all
330
331 test_restore_saved_value "[set intarr2.tekhex]" "array as memory, tekhex" \
332 $array_val "intarray"
333
334 test_restore_saved_value "[set intstr2.tekhex]" "struct as memory, tekhex" \
335 $struct_val "intstruct"
336 }
337
338 print_zero_all
339
340 test_restore_saved_value "[set intarr1.bin] binary $array_start" \
341 "array as value, binary" \
342 $array_val "intarray"
343
344 test_restore_saved_value "[set intstr1.bin] binary $struct_start" \
345 "struct as value, binary" \
346 $struct_val "intstruct"
347
348 print_zero_all
349
350 test_restore_saved_value "[set intarr2.bin] binary $array_start" \
351 "array as memory, binary" \
352 $array_val "intarray"
353
354 test_restore_saved_value "[set intstr2.bin] binary $struct_start" \
355 "struct as memory, binary" \
356 $struct_val "intstruct"
357
358 # test restore with offset.
359
360 set array2_start [capture_value "/x &intarray2\[0\]"]
361 set struct2_start [capture_value "/x &intstruct2"]
362 set array2_offset \
363 [capture_value "(char *) &intarray2 - (char *) &intarray"]
364 set struct2_offset \
365 [capture_value "(char *) &intstruct2 - (char *) &intstruct"]
366
367 print_zero_all
368
369
370 if {![string compare $is64bitonly "no"]} {
371 test_restore_saved_value "[set intarr1.srec] $array2_offset" \
372 "array copy, srec" \
373 $array_val "intarray2"
374
375 test_restore_saved_value "[set intstr1.srec] $struct2_offset" \
376 "struct copy, srec" \
377 $struct_val "intstruct2"
378
379 print_zero_all
380
381 test_restore_saved_value "[set intarr1.ihex] $array2_offset" \
382 "array copy, ihex" \
383 $array_val "intarray2"
384
385 test_restore_saved_value "[set intstr1.ihex] $struct2_offset" \
386 "struct copy, ihex" \
387 $struct_val "intstruct2"
388
389 print_zero_all
390
391 test_restore_saved_value "[set intarr1.tekhex] $array2_offset" \
392 "array copy, tekhex" \
393 $array_val "intarray2"
394
395 test_restore_saved_value "[set intstr1.tekhex] $struct2_offset" \
396 "struct copy, tekhex" \
397 $struct_val "intstruct2"
398 }
399
400 print_zero_all
401
402 test_restore_saved_value "[set intarr1.bin] binary $array2_start" \
403 "array copy, binary" \
404 $array_val "intarray2"
405
406 test_restore_saved_value "[set intstr1.bin] binary $struct2_start" \
407 "struct copy, binary" \
408 $struct_val "intstruct2"
409
410 #
411 # test restore with start/stop addresses.
412 #
413 # For this purpose, we will restore just the third element of the array,
414 # and check to see that adjacent elements are not modified.
415 #
416 # We will need the address and offset of the third and fourth elements.
417 #
418
419 set element3_start [capture_value "/x &intarray\[3\]"]
420 set element4_start [capture_value "/x &intarray\[4\]"]
421 set element3_offset \
422 [capture_value "/x (char *) &intarray\[3\] - (char *) &intarray\[0\]"]
423 set element4_offset \
424 [capture_value "/x (char *) &intarray\[4\] - (char *) &intarray\[0\]"]
425
426 if {![string compare $is64bitonly "no"]} {
427 print_zero_all
428
429 test_restore_saved_value "[set intarr1.srec] 0 $element3_start $element4_start" \
430 "array partial, srec" 4 "intarray\[3\]"
431
432 gdb_test "print intarray\[2\] == 0" " = 1" "element 2 not changed - 1"
433 gdb_test "print intarray\[4\] == 0" " = 1" "element 4 not changed - 1"
434
435 print_zero_all
436
437 test_restore_saved_value "[set intarr1.ihex] 0 $element3_start $element4_start" \
438 "array partial, ihex" 4 "intarray\[3\]"
439
440 gdb_test "print intarray\[2\] == 0" " = 1" "element 2 not changed - 2"
441 gdb_test "print intarray\[4\] == 0" " = 1" "element 4 not changed - 2"
442
443 print_zero_all
444
445 test_restore_saved_value "[set intarr1.tekhex] 0 $element3_start $element4_start" \
446 "array partial, tekhex" 4 "intarray\[3\]"
447
448 gdb_test "print intarray\[2\] == 0" " = 1" "element 2 not changed - 3"
449 gdb_test "print intarray\[4\] == 0" " = 1" "element 4 not changed - 3"
450 }
451
452 print_zero_all
453
454 test_restore_saved_value \
455 "[set intarr1.bin] binary $array_start $element3_offset $element4_offset" \
456 "array partial, binary" 4 "intarray\[3\]"
457
458 gdb_test "print intarray\[2\] == 0" " = 1" "element 2 not changed - 4"
459 gdb_test "print intarray\[4\] == 0" " = 1" "element 4 not changed - 4"
460
461 if {![string compare $is64bitonly "no"]} {
462 print_zero_all
463
464 # restore with expressions
465 test_restore_saved_value \
466 "[set intarr3.srec] (char*)${array2_start}-(char*)${array_start} &intarray\[3\] &intarray\[4\]" \
467 "array partial with expressions" 4 "intarray2\[3\]"
468
469 gdb_test "print intarray2\[2\] == 0" " = 1" "element 2 not changed, == 4"
470 gdb_test "print intarray2\[4\] == 0" " = 1" "element 4 not changed, == 4"
471 }
472
473
474 # Test writing a file of each format to a directory that does not exist.
475
476 foreach_with_prefix format $formats {
477 gdb_test "dump $format memory /tmp/non/existent/directory/file $array_start $array_end" \
478 "/tmp/non/existent/directory/file: No such file or directory." \
479 "dump to non-existent directory"
480 }
481
482 # Now start a fresh gdb session, and reload the saved value files.
483
484 clean_restart
485 gdb_file_cmd ${binfile}
486
487 # Now fix the endianness at the correct state.
488
489 gdb_test_multiple "set endian $endian" "set endianness" {
490 -re ".* (big|little) endian.*$gdb_prompt $" {
491 pass "setting $endian endianness"
492 }
493 }
494
495 # Reload saved values one by one, and compare.
496
497 if { ![string compare $array_val \
498 [capture_value "intarray" "file binfile; intarray"]] } then {
499 fail "start with intarray un-initialized"
500 } else {
501 pass "start with intarray un-initialized"
502 }
503
504 if { ![string compare $struct_val \
505 [capture_value "intstruct" "file binfile; intstruct"]] } then {
506 fail "start with intstruct un-initialized"
507 } else {
508 pass "start with intstruct un-initialized"
509 }
510
511 proc test_reload_saved_value { filename msg oldval newval } {
512 global gdb_prompt
513
514 gdb_file_cmd $filename
515 if { ![string compare $oldval \
516 [capture_value $newval "$msg"]] } then {
517 pass "$msg; value restored ok"
518 } else {
519 fail "$msg; value restored ok"
520 }
521 }
522
523 # srec format can not be loaded for 64-bit-only platforms
524 if {![string compare $is64bitonly "no"]} {
525 test_reload_saved_value "[set intarr1.srec]" "reload array as value, srec" \
526 $array_val "\*$array_ptr_type"
527 test_reload_saved_value "[set intstr1.srec]" "reload struct as value, srec" \
528 $struct_val "\*$struct_ptr_type"
529 test_reload_saved_value "[set intarr2.srec]" "reload array as memory, srec" \
530 $array_val "\*$array_ptr_type"
531 test_reload_saved_value "[set intstr2.srec]" "reload struct as memory, srec" \
532 $struct_val "\*$struct_ptr_type"
533 }
534
535 # ihex format can not be loaded for 64-bit-only platforms
536 if {![string compare $is64bitonly "no"]} {
537
538 test_reload_saved_value "[set intarr1.ihex]" \
539 "reload array as value, intel hex" \
540 $array_val "\*$array_ptr_type"
541 test_reload_saved_value "[set intstr1.ihex]" \
542 "reload struct as value, intel hex" \
543 $struct_val "\*$struct_ptr_type"
544 test_reload_saved_value "[set intarr2.ihex]" \
545 "reload array as memory, intel hex" \
546 $array_val "\*$array_ptr_type"
547 test_reload_saved_value "[set intstr2.ihex]" \
548 "reload struct as memory, intel hex" \
549 $struct_val "\*$struct_ptr_type"
550 }
551
552 # tekhex format can not be loaded for 64-bit-only platforms
553 if {![string compare $is64bitonly "no"]} {
554 test_reload_saved_value "[set intarr1.tekhex]" \
555 "reload array as value, tekhex" \
556 $array_val "\*$array_ptr_type"
557 test_reload_saved_value "[set intstr1.tekhex]" \
558 "reload struct as value, tekhex" \
559 $struct_val "\*$struct_ptr_type"
560 test_reload_saved_value "[set intarr2.tekhex]" \
561 "reload array as memory, tekhex" \
562 $array_val "\*$array_ptr_type"
563 test_reload_saved_value "[set intstr2.tekhex]" \
564 "reload struct as memory, tekhex" \
565 $struct_val "\*$struct_ptr_type"
566 }
567
568 # clean up files
569
570 remote_exec host "rm -f $filenames"