1 # Copyright 2002-2019 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 if {[istarget "spu*-*-*"]} then {
34 # The internal address format used for the combined Cell/B.E.
35 # debugger requires 64-bit.
39 # Debian9/Ubuntu16.10 onwards default to PIE enabled. Ensure it is disabled as
40 # this causes addresses to be out of range for IHEX.
41 lappend options {nopie}
43 if { [gdb_compile "${srcdir}/${subdir}/${srcfile}" "${binfile}" executable ${options}] != "" } {
44 untested "failed to compile"
48 # Start with a fresh gdb.
52 gdb_reinitialize_dir $srcdir/$subdir
54 gdb_test "dump mem /dev/null 0x10 0x20" "Cannot access memory at address 0x10" \
55 "inaccessible memory is reported"
59 # Check the address of a variable. If it is bigger than 32-bit,
60 # assume our target has 64-bit addresses that are not supported by SREC,
61 # IHEX and TEKHEX. We skip those tests then.
62 set max_32bit_address "0xffffffff"
63 set data_address [get_hexadecimal_valueof "&intarray" 0x100000000]
64 if {${data_address} > ${max_32bit_address}} then {
68 # Clean up any stale output files from previous test runs
72 intarr1.bin intarr1b.bin intarr1.ihex
73 intarr1.srec intarr1.tekhex intarr1.verilog
74 intarr2.bin intarr2b.bin intarr2.ihex
75 intarr2.srec intarr2.tekhex intarr2.verilog
76 intstr1.bin intstr1b.bin intstr1.ihex
77 intstr1.srec intstr1.tekhex intstr1.verilog
78 intstr2.bin intstr2b.bin intstr2.ihex
79 intstr2.srec intstr2.tekhex intstr2.verilog
83 # This loop sets variables dynamically -- each name listed in
84 # $ALL_FILES is both a file name and a variable name.
85 foreach file $all_files {
86 if {[is_remote host]} {
89 set this_name [standard_output_file $file]
92 lappend filenames [set ${file} $this_name]
95 remote_exec host "rm -f $filenames"
99 # Run target program until data structs are initialized.
101 if { ! [ runto checkpoint1 ] } then {
102 untested "couldn't run to checkpoint"
106 # Get the endianness for the later use with endianless formats.
108 set endian [get_endianness]
110 # Now generate some dump files.
112 proc make_dump_file { command msg } {
115 gdb_test_multiple "${command}" "$msg" {
116 -re ".*\[Ee\]rror.*$gdb_prompt $" { fail $msg }
117 -re ".*\[Ww\]arning.*$gdb_prompt $" { fail $msg }
118 -re ".*\[Uu\]ndefined .*$gdb_prompt $" { fail $msg }
119 -re ".*$gdb_prompt $" { pass $msg }
123 make_dump_file "dump val [set intarr1.bin] intarray" \
124 "dump array as value, default"
126 make_dump_file "dump val [set intstr1.bin] intstruct" \
127 "dump struct as value, default"
129 make_dump_file "dump bin val [set intarr1b.bin] intarray" \
130 "dump array as value, binary"
132 make_dump_file "dump bin val [set intstr1b.bin] intstruct" \
133 "dump struct as value, binary"
135 make_dump_file "dump srec val [set intarr1.srec] intarray" \
136 "dump array as value, srec"
138 make_dump_file "dump srec val [set intstr1.srec] intstruct" \
139 "dump struct as value, srec"
141 make_dump_file "dump ihex val [set intarr1.ihex] intarray" \
142 "dump array as value, intel hex"
144 make_dump_file "dump ihex val [set intstr1.ihex] intstruct" \
145 "dump struct as value, intel hex"
147 make_dump_file "dump tekhex val [set intarr1.tekhex] intarray" \
148 "dump array as value, tekhex"
150 make_dump_file "dump tekhex val [set intstr1.tekhex] intstruct" \
151 "dump struct as value, tekhex"
153 make_dump_file "dump verilog val [set intarr1.verilog] intarray" \
154 "dump array as value, verilog"
156 make_dump_file "dump verilog val [set intstr1.verilog] intstruct" \
157 "dump struct as value, verilog"
159 proc capture_value { expression args } {
164 if {[llength $args] > 0} {
165 # Convert $args into a simple string and don't use EXPRESSION
167 set test "[join $args]; capture"
169 set test "capture $expression"
171 gdb_test_multiple "print ${expression}" "$test" {
172 -re "\\$\[0-9\]+ = (\[^\r\n\]+).*$gdb_prompt $" {
173 set output_string "$expect_out(1,string)"
176 -re "(Cannot access memory at address \[^\r\n\]+).*$gdb_prompt $" {
177 # Even a failed value is valid
178 set output_string "$expect_out(1,string)"
182 return $output_string
185 # POINTER is a pointer and this proc captures the value of POINTER along
186 # with POINTER's type. For example, POINTER is "&intarray", this proc will
187 # call "p &intarray", capture "(int (*)[32]) 0x804a0e0", and return this
190 proc capture_pointer_with_type { pointer } {
194 set test "capture type of pointer $pointer"
196 gdb_test_multiple "p ${pointer}" $test {
197 -re "\\$\[0-9\]+ = .*$gdb_prompt $" {
198 # Expected output of "p ${pointer}" is like "$7 = (int (*)[32]) 0x804a0e0",
199 # and we want to extract "(int (*)[32]) 0x804a0e0" from it via
201 if [regexp " \\(.*\\).* 0x\[0-9a-fA-F\]+" $expect_out(0,string) output_string] {
202 # OUTPUT_STRING is expected to be like "(int (*)[32]) 0x804a0e0".
210 return $output_string
213 set array_start [capture_value "/x &intarray\[0\]"]
214 set array_end [capture_value "/x &intarray\[32\]"]
215 set struct_start [capture_value "/x &intstruct"]
216 set struct_end [capture_value "/x &intstruct + 1"]
218 set array_val [capture_value "intarray"]
219 set struct_val [capture_value "intstruct"]
221 set array_ptr_type [capture_pointer_with_type "&intarray"]
222 set struct_ptr_type [capture_pointer_with_type "&intstruct"]
224 make_dump_file "dump mem [set intarr2.bin] $array_start $array_end" \
225 "dump array as memory, default"
227 make_dump_file "dump mem [set intstr2.bin] $struct_start $struct_end" \
228 "dump struct as memory, default"
230 make_dump_file "dump bin mem [set intarr2b.bin] $array_start $array_end" \
231 "dump array as memory, binary"
233 make_dump_file "dump bin mem [set intstr2b.bin] $struct_start $struct_end" \
234 "dump struct as memory, binary"
236 make_dump_file "dump srec mem [set intarr2.srec] $array_start $array_end" \
237 "dump array as memory, srec"
239 make_dump_file "dump srec mem [set intstr2.srec] $struct_start $struct_end" \
240 "dump struct as memory, srec"
242 make_dump_file "dump ihex mem [set intarr2.ihex] $array_start $array_end" \
243 "dump array as memory, ihex"
245 make_dump_file "dump ihex mem [set intstr2.ihex] $struct_start $struct_end" \
246 "dump struct as memory, ihex"
248 make_dump_file "dump tekhex mem [set intarr2.tekhex] $array_start $array_end" \
249 "dump array as memory, tekhex"
251 make_dump_file "dump tekhex mem [set intstr2.tekhex] $struct_start $struct_end" \
252 "dump struct as memory, tekhex"
254 make_dump_file "dump verilog mem [set intarr2.verilog] $array_start $array_end" \
255 "dump array as memory, verilog"
257 make_dump_file "dump verilog mem [set intstr2.verilog] $struct_start $struct_end" \
258 "dump struct as memory, verilog"
260 # test complex expressions
262 "dump srec mem [set intarr3.srec] &intarray \(char *\) &intarray + sizeof intarray" \
263 "dump array as mem, srec, expressions"
265 proc test_restore_saved_value { restore_args msg oldval newval } {
268 gdb_test "restore $restore_args" \
270 "$msg; file restored ok"
271 if { ![string compare $oldval \
272 [capture_value $newval "$msg"]] } then {
273 pass "$msg; value restored ok"
275 fail "$msg; value restored ok"
279 if ![string compare $is64bitonly "no"] then {
281 gdb_test "print zero_all ()" ".*"
283 test_restore_saved_value "[set intarr1.srec]" "array as value, srec" \
284 $array_val "intarray"
286 test_restore_saved_value "[set intstr1.srec]" "struct as value, srec" \
287 $struct_val "intstruct"
289 gdb_test "print zero_all ()" "void" "zero all"
291 test_restore_saved_value "[set intarr2.srec]" "array as memory, srec" \
292 $array_val "intarray"
294 test_restore_saved_value "[set intstr2.srec]" "struct as memory, srec" \
295 $struct_val "intstruct"
297 gdb_test "print zero_all ()" ".*"
299 test_restore_saved_value "[set intarr1.ihex]" "array as value, ihex" \
300 $array_val "intarray"
302 test_restore_saved_value "[set intstr1.ihex]" "struct as value, ihex" \
303 $struct_val "intstruct"
305 gdb_test "print zero_all ()" ".*"
307 test_restore_saved_value "[set intarr2.ihex]" "array as memory, ihex" \
308 $array_val "intarray"
310 test_restore_saved_value "[set intstr2.ihex]" "struct as memory, ihex" \
311 $struct_val "intstruct"
313 gdb_test "print zero_all ()" ".*"
315 test_restore_saved_value "[set intarr1.tekhex]" "array as value, tekhex" \
316 $array_val "intarray"
318 test_restore_saved_value "[set intstr1.tekhex]" "struct as value, tekhex" \
319 $struct_val "intstruct"
321 gdb_test "print zero_all ()" ".*"
323 test_restore_saved_value "[set intarr2.tekhex]" "array as memory, tekhex" \
324 $array_val "intarray"
326 test_restore_saved_value "[set intstr2.tekhex]" "struct as memory, tekhex" \
327 $struct_val "intstruct"
330 gdb_test "print zero_all ()" ".*"
332 test_restore_saved_value "[set intarr1.bin] binary $array_start" \
333 "array as value, binary" \
334 $array_val "intarray"
336 test_restore_saved_value "[set intstr1.bin] binary $struct_start" \
337 "struct as value, binary" \
338 $struct_val "intstruct"
340 gdb_test "print zero_all ()" ".*"
342 test_restore_saved_value "[set intarr2.bin] binary $array_start" \
343 "array as memory, binary" \
344 $array_val "intarray"
346 test_restore_saved_value "[set intstr2.bin] binary $struct_start" \
347 "struct as memory, binary" \
348 $struct_val "intstruct"
350 # test restore with offset.
352 set array2_start [capture_value "/x &intarray2\[0\]"]
353 set struct2_start [capture_value "/x &intstruct2"]
355 [capture_value "(char *) &intarray2 - (char *) &intarray"]
357 [capture_value "(char *) &intstruct2 - (char *) &intstruct"]
359 gdb_test "print zero_all ()" ".*"
362 if ![string compare $is64bitonly "no"] then {
363 test_restore_saved_value "[set intarr1.srec] $array2_offset" \
365 $array_val "intarray2"
367 test_restore_saved_value "[set intstr1.srec] $struct2_offset" \
368 "struct copy, srec" \
369 $struct_val "intstruct2"
371 gdb_test "print zero_all ()" ".*"
373 test_restore_saved_value "[set intarr1.ihex] $array2_offset" \
375 $array_val "intarray2"
377 test_restore_saved_value "[set intstr1.ihex] $struct2_offset" \
378 "struct copy, ihex" \
379 $struct_val "intstruct2"
381 gdb_test "print zero_all ()" ".*"
383 test_restore_saved_value "[set intarr1.tekhex] $array2_offset" \
384 "array copy, tekhex" \
385 $array_val "intarray2"
387 test_restore_saved_value "[set intstr1.tekhex] $struct2_offset" \
388 "struct copy, tekhex" \
389 $struct_val "intstruct2"
392 gdb_test "print zero_all ()" ".*"
394 test_restore_saved_value "[set intarr1.bin] binary $array2_start" \
395 "array copy, binary" \
396 $array_val "intarray2"
398 test_restore_saved_value "[set intstr1.bin] binary $struct2_start" \
399 "struct copy, binary" \
400 $struct_val "intstruct2"
403 # test restore with start/stop addresses.
405 # For this purpose, we will restore just the third element of the array,
406 # and check to see that adjacent elements are not modified.
408 # We will need the address and offset of the third and fourth elements.
411 set element3_start [capture_value "/x &intarray\[3\]"]
412 set element4_start [capture_value "/x &intarray\[4\]"]
413 set element3_offset \
414 [capture_value "/x (char *) &intarray\[3\] - (char *) &intarray\[0\]"]
415 set element4_offset \
416 [capture_value "/x (char *) &intarray\[4\] - (char *) &intarray\[0\]"]
418 if ![string compare $is64bitonly "no"] then {
419 gdb_test "print zero_all ()" ".*"
421 test_restore_saved_value "[set intarr1.srec] 0 $element3_start $element4_start" \
422 "array partial, srec" 4 "intarray\[3\]"
424 gdb_test "print intarray\[2\] == 0" " = 1" "element 2 not changed - 1"
425 gdb_test "print intarray\[4\] == 0" " = 1" "element 4 not changed - 1"
427 gdb_test "print zero_all ()" ".*"
429 test_restore_saved_value "[set intarr1.ihex] 0 $element3_start $element4_start" \
430 "array partial, ihex" 4 "intarray\[3\]"
432 gdb_test "print intarray\[2\] == 0" " = 1" "element 2 not changed - 2"
433 gdb_test "print intarray\[4\] == 0" " = 1" "element 4 not changed - 2"
435 gdb_test "print zero_all ()" ".*"
437 test_restore_saved_value "[set intarr1.tekhex] 0 $element3_start $element4_start" \
438 "array partial, tekhex" 4 "intarray\[3\]"
440 gdb_test "print intarray\[2\] == 0" " = 1" "element 2 not changed - 3"
441 gdb_test "print intarray\[4\] == 0" " = 1" "element 4 not changed - 3"
444 gdb_test "print zero_all ()" ".*"
446 test_restore_saved_value \
447 "[set intarr1.bin] binary $array_start $element3_offset $element4_offset" \
448 "array partial, binary" 4 "intarray\[3\]"
450 gdb_test "print intarray\[2\] == 0" " = 1" "element 2 not changed - 4"
451 gdb_test "print intarray\[4\] == 0" " = 1" "element 4 not changed - 4"
453 if ![string compare $is64bitonly "no"] then {
454 gdb_test "print zero_all ()" ".*" ""
456 # restore with expressions
457 test_restore_saved_value \
458 "[set intarr3.srec] (char*)${array2_start}-(char*)${array_start} &intarray\[3\] &intarray\[4\]" \
459 "array partial with expressions" 4 "intarray2\[3\]"
461 gdb_test "print intarray2\[2\] == 0" " = 1" "element 2 not changed, == 4"
462 gdb_test "print intarray2\[4\] == 0" " = 1" "element 4 not changed, == 4"
466 # Now start a fresh gdb session, and reload the saved value files.
470 gdb_file_cmd ${binfile}
472 # Now fix the endianness at the correct state.
474 gdb_test_multiple "set endian $endian" "set endianness" {
475 -re ".* (big|little) endian.*$gdb_prompt $" {
476 pass "setting $endian endianness"
480 # Reload saved values one by one, and compare.
482 if { ![string compare $array_val \
483 [capture_value "intarray" "file binfile; intarray"]] } then {
484 fail "start with intarray un-initialized"
486 pass "start with intarray un-initialized"
489 if { ![string compare $struct_val \
490 [capture_value "intstruct" "file binfile; intstruct"]] } then {
491 fail "start with intstruct un-initialized"
493 pass "start with intstruct un-initialized"
496 proc test_reload_saved_value { filename msg oldval newval } {
499 gdb_file_cmd $filename
500 if { ![string compare $oldval \
501 [capture_value $newval "$msg"]] } then {
502 pass "$msg; value restored ok"
504 fail "$msg; value restored ok"
508 # srec format can not be loaded for 64-bit-only platforms
509 if ![string compare $is64bitonly "no"] then {
510 test_reload_saved_value "[set intarr1.srec]" "reload array as value, srec" \
511 $array_val "\*$array_ptr_type"
512 test_reload_saved_value "[set intstr1.srec]" "reload struct as value, srec" \
513 $struct_val "\*$struct_ptr_type"
514 test_reload_saved_value "[set intarr2.srec]" "reload array as memory, srec" \
515 $array_val "\*$array_ptr_type"
516 test_reload_saved_value "[set intstr2.srec]" "reload struct as memory, srec" \
517 $struct_val "\*$struct_ptr_type"
520 # ihex format can not be loaded for 64-bit-only platforms
521 if ![string compare $is64bitonly "no"] then {
523 test_reload_saved_value "[set intarr1.ihex]" \
524 "reload array as value, intel hex" \
525 $array_val "\*$array_ptr_type"
526 test_reload_saved_value "[set intstr1.ihex]" \
527 "reload struct as value, intel hex" \
528 $struct_val "\*$struct_ptr_type"
529 test_reload_saved_value "[set intarr2.ihex]" \
530 "reload array as memory, intel hex" \
531 $array_val "\*$array_ptr_type"
532 test_reload_saved_value "[set intstr2.ihex]" \
533 "reload struct as memory, intel hex" \
534 $struct_val "\*$struct_ptr_type"
537 # tekhex format can not be loaded for 64-bit-only platforms
538 if ![string compare $is64bitonly "no"] then {
539 test_reload_saved_value "[set intarr1.tekhex]" \
540 "reload array as value, tekhex" \
541 $array_val "\*$array_ptr_type"
542 test_reload_saved_value "[set intstr1.tekhex]" \
543 "reload struct as value, tekhex" \
544 $struct_val "\*$struct_ptr_type"
545 test_reload_saved_value "[set intarr2.tekhex]" \
546 "reload array as memory, tekhex" \
547 $array_val "\*$array_ptr_type"
548 test_reload_saved_value "[set intstr2.tekhex]" \
549 "reload struct as memory, tekhex" \
550 $struct_val "\*$struct_ptr_type"
555 remote_exec host "rm -f $filenames"