1 # Copyright 2002-2020 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 file was written by Michael Snyder (msnyder@redhat.com)
17 # This is a test for the gdb command "dump".
27 if [istarget "alpha*-*-*"] then {
28 # SREC etc cannot handle 64-bit addresses. Force the test
29 # program into the low 31 bits of the address space.
30 lappend options "additional_flags=-Wl,-taso"
33 # Runs the command 'print zero_all ()'. Uses the PRINT_ZERO_ALL_COUNT
34 # global to ensure the test names are unique.
35 set print_zero_all_count 0
36 proc print_zero_all { } {
37 global print_zero_all_count
39 incr print_zero_all_count
40 gdb_test "print zero_all ()" " = void" \
41 "call ${print_zero_all_count} to zero_all function"
44 # Debian9/Ubuntu16.10 onwards default to PIE enabled. Ensure it is disabled as
45 # this causes addresses to be out of range for IHEX.
46 lappend options {nopie}
48 if { [gdb_compile "${srcdir}/${subdir}/${srcfile}" "${binfile}" executable ${options}] != "" } {
49 untested "failed to compile"
53 # Start with a fresh gdb.
57 gdb_reinitialize_dir $srcdir/$subdir
59 gdb_test "dump mem /dev/null 0x10 0x20" "Cannot access memory at address 0x10" \
60 "inaccessible memory is reported"
64 # Check the address of a variable. If it is bigger than 32-bit,
65 # assume our target has 64-bit addresses that are not supported by SREC,
66 # IHEX and TEKHEX. We skip those tests then.
67 set max_32bit_address "0xffffffff"
68 set data_address [get_hexadecimal_valueof "&intarray" 0x100000000]
69 if {${data_address} > ${max_32bit_address}} then {
73 # Clean up any stale output files from previous test runs
77 intarr1.bin intarr1b.bin intarr1.ihex
78 intarr1.srec intarr1.tekhex intarr1.verilog
79 intarr2.bin intarr2b.bin intarr2.ihex
80 intarr2.srec intarr2.tekhex intarr2.verilog
81 intstr1.bin intstr1b.bin intstr1.ihex
82 intstr1.srec intstr1.tekhex intstr1.verilog
83 intstr2.bin intstr2b.bin intstr2.ihex
84 intstr2.srec intstr2.tekhex intstr2.verilog
88 # This loop sets variables dynamically -- each name listed in
89 # $ALL_FILES is both a file name and a variable name.
90 foreach file $all_files {
91 if {[is_remote host]} {
94 set this_name [standard_output_file $file]
97 lappend filenames [set ${file} $this_name]
100 remote_exec host "rm -f $filenames"
104 # Run target program until data structs are initialized.
106 if { ! [ runto checkpoint1 ] } then {
107 untested "couldn't run to checkpoint"
111 # Get the endianness for the later use with endianless formats.
113 set endian [get_endianness]
115 # Now generate some dump files.
117 proc make_dump_file { command msg } {
120 gdb_test_multiple "${command}" "$msg" {
121 -re ".*\[Ee\]rror.*$gdb_prompt $" { fail $msg }
122 -re ".*\[Ww\]arning.*$gdb_prompt $" { fail $msg }
123 -re ".*\[Uu\]ndefined .*$gdb_prompt $" { fail $msg }
124 -re ".*$gdb_prompt $" { pass $msg }
128 make_dump_file "dump val [set intarr1.bin] intarray" \
129 "dump array as value, default"
131 make_dump_file "dump val [set intstr1.bin] intstruct" \
132 "dump struct as value, default"
134 make_dump_file "dump bin val [set intarr1b.bin] intarray" \
135 "dump array as value, binary"
137 make_dump_file "dump bin val [set intstr1b.bin] intstruct" \
138 "dump struct as value, binary"
140 make_dump_file "dump srec val [set intarr1.srec] intarray" \
141 "dump array as value, srec"
143 make_dump_file "dump srec val [set intstr1.srec] intstruct" \
144 "dump struct as value, srec"
146 make_dump_file "dump ihex val [set intarr1.ihex] intarray" \
147 "dump array as value, intel hex"
149 make_dump_file "dump ihex val [set intstr1.ihex] intstruct" \
150 "dump struct as value, intel hex"
152 make_dump_file "dump tekhex val [set intarr1.tekhex] intarray" \
153 "dump array as value, tekhex"
155 make_dump_file "dump tekhex val [set intstr1.tekhex] intstruct" \
156 "dump struct as value, tekhex"
158 make_dump_file "dump verilog val [set intarr1.verilog] intarray" \
159 "dump array as value, verilog"
161 make_dump_file "dump verilog val [set intstr1.verilog] intstruct" \
162 "dump struct as value, verilog"
164 proc capture_value { expression args } {
169 if {[llength $args] > 0} {
170 # Convert $args into a simple string and don't use EXPRESSION
172 set test "[join $args]; capture"
174 set test "capture $expression"
176 gdb_test_multiple "print ${expression}" "$test" {
177 -re "\\$\[0-9\]+ = (\[^\r\n\]+).*$gdb_prompt $" {
178 set output_string "$expect_out(1,string)"
181 -re "(Cannot access memory at address \[^\r\n\]+).*$gdb_prompt $" {
182 # Even a failed value is valid
183 set output_string "$expect_out(1,string)"
187 return $output_string
190 # POINTER is a pointer and this proc captures the value of POINTER along
191 # with POINTER's type. For example, POINTER is "&intarray", this proc will
192 # call "p &intarray", capture "(int (*)[32]) 0x804a0e0", and return this
195 proc capture_pointer_with_type { pointer } {
199 set test "capture type of pointer $pointer"
201 gdb_test_multiple "p ${pointer}" $test {
202 -re "\\$\[0-9\]+ = .*$gdb_prompt $" {
203 # Expected output of "p ${pointer}" is like "$7 = (int (*)[32]) 0x804a0e0",
204 # and we want to extract "(int (*)[32]) 0x804a0e0" from it via
206 if [regexp " \\(.*\\).* 0x\[0-9a-fA-F\]+" $expect_out(0,string) output_string] {
207 # OUTPUT_STRING is expected to be like "(int (*)[32]) 0x804a0e0".
215 return $output_string
218 set array_start [capture_value "/x &intarray\[0\]"]
219 set array_end [capture_value "/x &intarray\[32\]"]
220 set struct_start [capture_value "/x &intstruct"]
221 set struct_end [capture_value "/x &intstruct + 1"]
223 set array_val [capture_value "intarray"]
224 set struct_val [capture_value "intstruct"]
226 set array_ptr_type [capture_pointer_with_type "&intarray"]
227 set struct_ptr_type [capture_pointer_with_type "&intstruct"]
229 make_dump_file "dump mem [set intarr2.bin] $array_start $array_end" \
230 "dump array as memory, default"
232 make_dump_file "dump mem [set intstr2.bin] $struct_start $struct_end" \
233 "dump struct as memory, default"
235 make_dump_file "dump bin mem [set intarr2b.bin] $array_start $array_end" \
236 "dump array as memory, binary"
238 make_dump_file "dump bin mem [set intstr2b.bin] $struct_start $struct_end" \
239 "dump struct as memory, binary"
241 make_dump_file "dump srec mem [set intarr2.srec] $array_start $array_end" \
242 "dump array as memory, srec"
244 make_dump_file "dump srec mem [set intstr2.srec] $struct_start $struct_end" \
245 "dump struct as memory, srec"
247 make_dump_file "dump ihex mem [set intarr2.ihex] $array_start $array_end" \
248 "dump array as memory, ihex"
250 make_dump_file "dump ihex mem [set intstr2.ihex] $struct_start $struct_end" \
251 "dump struct as memory, ihex"
253 make_dump_file "dump tekhex mem [set intarr2.tekhex] $array_start $array_end" \
254 "dump array as memory, tekhex"
256 make_dump_file "dump tekhex mem [set intstr2.tekhex] $struct_start $struct_end" \
257 "dump struct as memory, tekhex"
259 make_dump_file "dump verilog mem [set intarr2.verilog] $array_start $array_end" \
260 "dump array as memory, verilog"
262 make_dump_file "dump verilog mem [set intstr2.verilog] $struct_start $struct_end" \
263 "dump struct as memory, verilog"
265 # test complex expressions
267 "dump srec mem [set intarr3.srec] &intarray \(char *\) &intarray + sizeof intarray" \
268 "dump array as mem, srec, expressions"
270 proc test_restore_saved_value { restore_args msg oldval newval } {
273 gdb_test "restore $restore_args" \
275 "$msg; file restored ok"
276 if { ![string compare $oldval \
277 [capture_value $newval "$msg"]] } then {
278 pass "$msg; value restored ok"
280 fail "$msg; value restored ok"
284 if ![string compare $is64bitonly "no"] then {
287 test_restore_saved_value "[set intarr1.srec]" "array as value, srec" \
288 $array_val "intarray"
290 test_restore_saved_value "[set intstr1.srec]" "struct as value, srec" \
291 $struct_val "intstruct"
295 test_restore_saved_value "[set intarr2.srec]" "array as memory, srec" \
296 $array_val "intarray"
298 test_restore_saved_value "[set intstr2.srec]" "struct as memory, srec" \
299 $struct_val "intstruct"
303 test_restore_saved_value "[set intarr1.ihex]" "array as value, ihex" \
304 $array_val "intarray"
306 test_restore_saved_value "[set intstr1.ihex]" "struct as value, ihex" \
307 $struct_val "intstruct"
311 test_restore_saved_value "[set intarr2.ihex]" "array as memory, ihex" \
312 $array_val "intarray"
314 test_restore_saved_value "[set intstr2.ihex]" "struct as memory, ihex" \
315 $struct_val "intstruct"
319 test_restore_saved_value "[set intarr1.tekhex]" "array as value, tekhex" \
320 $array_val "intarray"
322 test_restore_saved_value "[set intstr1.tekhex]" "struct as value, tekhex" \
323 $struct_val "intstruct"
327 test_restore_saved_value "[set intarr2.tekhex]" "array as memory, tekhex" \
328 $array_val "intarray"
330 test_restore_saved_value "[set intstr2.tekhex]" "struct as memory, tekhex" \
331 $struct_val "intstruct"
336 test_restore_saved_value "[set intarr1.bin] binary $array_start" \
337 "array as value, binary" \
338 $array_val "intarray"
340 test_restore_saved_value "[set intstr1.bin] binary $struct_start" \
341 "struct as value, binary" \
342 $struct_val "intstruct"
346 test_restore_saved_value "[set intarr2.bin] binary $array_start" \
347 "array as memory, binary" \
348 $array_val "intarray"
350 test_restore_saved_value "[set intstr2.bin] binary $struct_start" \
351 "struct as memory, binary" \
352 $struct_val "intstruct"
354 # test restore with offset.
356 set array2_start [capture_value "/x &intarray2\[0\]"]
357 set struct2_start [capture_value "/x &intstruct2"]
359 [capture_value "(char *) &intarray2 - (char *) &intarray"]
361 [capture_value "(char *) &intstruct2 - (char *) &intstruct"]
366 if ![string compare $is64bitonly "no"] then {
367 test_restore_saved_value "[set intarr1.srec] $array2_offset" \
369 $array_val "intarray2"
371 test_restore_saved_value "[set intstr1.srec] $struct2_offset" \
372 "struct copy, srec" \
373 $struct_val "intstruct2"
377 test_restore_saved_value "[set intarr1.ihex] $array2_offset" \
379 $array_val "intarray2"
381 test_restore_saved_value "[set intstr1.ihex] $struct2_offset" \
382 "struct copy, ihex" \
383 $struct_val "intstruct2"
387 test_restore_saved_value "[set intarr1.tekhex] $array2_offset" \
388 "array copy, tekhex" \
389 $array_val "intarray2"
391 test_restore_saved_value "[set intstr1.tekhex] $struct2_offset" \
392 "struct copy, tekhex" \
393 $struct_val "intstruct2"
398 test_restore_saved_value "[set intarr1.bin] binary $array2_start" \
399 "array copy, binary" \
400 $array_val "intarray2"
402 test_restore_saved_value "[set intstr1.bin] binary $struct2_start" \
403 "struct copy, binary" \
404 $struct_val "intstruct2"
407 # test restore with start/stop addresses.
409 # For this purpose, we will restore just the third element of the array,
410 # and check to see that adjacent elements are not modified.
412 # We will need the address and offset of the third and fourth elements.
415 set element3_start [capture_value "/x &intarray\[3\]"]
416 set element4_start [capture_value "/x &intarray\[4\]"]
417 set element3_offset \
418 [capture_value "/x (char *) &intarray\[3\] - (char *) &intarray\[0\]"]
419 set element4_offset \
420 [capture_value "/x (char *) &intarray\[4\] - (char *) &intarray\[0\]"]
422 if ![string compare $is64bitonly "no"] then {
425 test_restore_saved_value "[set intarr1.srec] 0 $element3_start $element4_start" \
426 "array partial, srec" 4 "intarray\[3\]"
428 gdb_test "print intarray\[2\] == 0" " = 1" "element 2 not changed - 1"
429 gdb_test "print intarray\[4\] == 0" " = 1" "element 4 not changed - 1"
433 test_restore_saved_value "[set intarr1.ihex] 0 $element3_start $element4_start" \
434 "array partial, ihex" 4 "intarray\[3\]"
436 gdb_test "print intarray\[2\] == 0" " = 1" "element 2 not changed - 2"
437 gdb_test "print intarray\[4\] == 0" " = 1" "element 4 not changed - 2"
441 test_restore_saved_value "[set intarr1.tekhex] 0 $element3_start $element4_start" \
442 "array partial, tekhex" 4 "intarray\[3\]"
444 gdb_test "print intarray\[2\] == 0" " = 1" "element 2 not changed - 3"
445 gdb_test "print intarray\[4\] == 0" " = 1" "element 4 not changed - 3"
450 test_restore_saved_value \
451 "[set intarr1.bin] binary $array_start $element3_offset $element4_offset" \
452 "array partial, binary" 4 "intarray\[3\]"
454 gdb_test "print intarray\[2\] == 0" " = 1" "element 2 not changed - 4"
455 gdb_test "print intarray\[4\] == 0" " = 1" "element 4 not changed - 4"
457 if ![string compare $is64bitonly "no"] then {
460 # restore with expressions
461 test_restore_saved_value \
462 "[set intarr3.srec] (char*)${array2_start}-(char*)${array_start} &intarray\[3\] &intarray\[4\]" \
463 "array partial with expressions" 4 "intarray2\[3\]"
465 gdb_test "print intarray2\[2\] == 0" " = 1" "element 2 not changed, == 4"
466 gdb_test "print intarray2\[4\] == 0" " = 1" "element 4 not changed, == 4"
470 # Now start a fresh gdb session, and reload the saved value files.
474 gdb_file_cmd ${binfile}
476 # Now fix the endianness at the correct state.
478 gdb_test_multiple "set endian $endian" "set endianness" {
479 -re ".* (big|little) endian.*$gdb_prompt $" {
480 pass "setting $endian endianness"
484 # Reload saved values one by one, and compare.
486 if { ![string compare $array_val \
487 [capture_value "intarray" "file binfile; intarray"]] } then {
488 fail "start with intarray un-initialized"
490 pass "start with intarray un-initialized"
493 if { ![string compare $struct_val \
494 [capture_value "intstruct" "file binfile; intstruct"]] } then {
495 fail "start with intstruct un-initialized"
497 pass "start with intstruct un-initialized"
500 proc test_reload_saved_value { filename msg oldval newval } {
503 gdb_file_cmd $filename
504 if { ![string compare $oldval \
505 [capture_value $newval "$msg"]] } then {
506 pass "$msg; value restored ok"
508 fail "$msg; value restored ok"
512 # srec format can not be loaded for 64-bit-only platforms
513 if ![string compare $is64bitonly "no"] then {
514 test_reload_saved_value "[set intarr1.srec]" "reload array as value, srec" \
515 $array_val "\*$array_ptr_type"
516 test_reload_saved_value "[set intstr1.srec]" "reload struct as value, srec" \
517 $struct_val "\*$struct_ptr_type"
518 test_reload_saved_value "[set intarr2.srec]" "reload array as memory, srec" \
519 $array_val "\*$array_ptr_type"
520 test_reload_saved_value "[set intstr2.srec]" "reload struct as memory, srec" \
521 $struct_val "\*$struct_ptr_type"
524 # ihex format can not be loaded for 64-bit-only platforms
525 if ![string compare $is64bitonly "no"] then {
527 test_reload_saved_value "[set intarr1.ihex]" \
528 "reload array as value, intel hex" \
529 $array_val "\*$array_ptr_type"
530 test_reload_saved_value "[set intstr1.ihex]" \
531 "reload struct as value, intel hex" \
532 $struct_val "\*$struct_ptr_type"
533 test_reload_saved_value "[set intarr2.ihex]" \
534 "reload array as memory, intel hex" \
535 $array_val "\*$array_ptr_type"
536 test_reload_saved_value "[set intstr2.ihex]" \
537 "reload struct as memory, intel hex" \
538 $struct_val "\*$struct_ptr_type"
541 # tekhex format can not be loaded for 64-bit-only platforms
542 if ![string compare $is64bitonly "no"] then {
543 test_reload_saved_value "[set intarr1.tekhex]" \
544 "reload array as value, tekhex" \
545 $array_val "\*$array_ptr_type"
546 test_reload_saved_value "[set intstr1.tekhex]" \
547 "reload struct as value, tekhex" \
548 $struct_val "\*$struct_ptr_type"
549 test_reload_saved_value "[set intarr2.tekhex]" \
550 "reload array as memory, tekhex" \
551 $array_val "\*$array_ptr_type"
552 test_reload_saved_value "[set intstr2.tekhex]" \
553 "reload struct as memory, tekhex" \
554 $struct_val "\*$struct_ptr_type"
559 remote_exec host "rm -f $filenames"