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 # Debian9/Ubuntu16.10 onwards default to PIE enabled. Ensure it is disabled as
34 # this causes addresses to be out of range for IHEX.
35 lappend options {nopie}
37 if { [gdb_compile "${srcdir}/${subdir}/${srcfile}" "${binfile}" executable ${options}] != "" } {
38 untested "failed to compile"
42 # Start with a fresh gdb.
46 gdb_reinitialize_dir $srcdir/$subdir
48 gdb_test "dump mem /dev/null 0x10 0x20" "Cannot access memory at address 0x10" \
49 "inaccessible memory is reported"
53 # Check the address of a variable. If it is bigger than 32-bit,
54 # assume our target has 64-bit addresses that are not supported by SREC,
55 # IHEX and TEKHEX. We skip those tests then.
56 set max_32bit_address "0xffffffff"
57 set data_address [get_hexadecimal_valueof "&intarray" 0x100000000]
58 if {${data_address} > ${max_32bit_address}} then {
62 # Clean up any stale output files from previous test runs
66 intarr1.bin intarr1b.bin intarr1.ihex
67 intarr1.srec intarr1.tekhex intarr1.verilog
68 intarr2.bin intarr2b.bin intarr2.ihex
69 intarr2.srec intarr2.tekhex intarr2.verilog
70 intstr1.bin intstr1b.bin intstr1.ihex
71 intstr1.srec intstr1.tekhex intstr1.verilog
72 intstr2.bin intstr2b.bin intstr2.ihex
73 intstr2.srec intstr2.tekhex intstr2.verilog
77 # This loop sets variables dynamically -- each name listed in
78 # $ALL_FILES is both a file name and a variable name.
79 foreach file $all_files {
80 if {[is_remote host]} {
83 set this_name [standard_output_file $file]
86 lappend filenames [set ${file} $this_name]
89 remote_exec host "rm -f $filenames"
93 # Run target program until data structs are initialized.
95 if { ! [ runto checkpoint1 ] } then {
96 untested "couldn't run to checkpoint"
100 # Get the endianness for the later use with endianless formats.
102 set endian [get_endianness]
104 # Now generate some dump files.
106 proc make_dump_file { command msg } {
109 gdb_test_multiple "${command}" "$msg" {
110 -re ".*\[Ee\]rror.*$gdb_prompt $" { fail $msg }
111 -re ".*\[Ww\]arning.*$gdb_prompt $" { fail $msg }
112 -re ".*\[Uu\]ndefined .*$gdb_prompt $" { fail $msg }
113 -re ".*$gdb_prompt $" { pass $msg }
117 make_dump_file "dump val [set intarr1.bin] intarray" \
118 "dump array as value, default"
120 make_dump_file "dump val [set intstr1.bin] intstruct" \
121 "dump struct as value, default"
123 make_dump_file "dump bin val [set intarr1b.bin] intarray" \
124 "dump array as value, binary"
126 make_dump_file "dump bin val [set intstr1b.bin] intstruct" \
127 "dump struct as value, binary"
129 make_dump_file "dump srec val [set intarr1.srec] intarray" \
130 "dump array as value, srec"
132 make_dump_file "dump srec val [set intstr1.srec] intstruct" \
133 "dump struct as value, srec"
135 make_dump_file "dump ihex val [set intarr1.ihex] intarray" \
136 "dump array as value, intel hex"
138 make_dump_file "dump ihex val [set intstr1.ihex] intstruct" \
139 "dump struct as value, intel hex"
141 make_dump_file "dump tekhex val [set intarr1.tekhex] intarray" \
142 "dump array as value, tekhex"
144 make_dump_file "dump tekhex val [set intstr1.tekhex] intstruct" \
145 "dump struct as value, tekhex"
147 make_dump_file "dump verilog val [set intarr1.verilog] intarray" \
148 "dump array as value, verilog"
150 make_dump_file "dump verilog val [set intstr1.verilog] intstruct" \
151 "dump struct as value, verilog"
153 proc capture_value { expression args } {
158 if {[llength $args] > 0} {
159 # Convert $args into a simple string and don't use EXPRESSION
161 set test "[join $args]; capture"
163 set test "capture $expression"
165 gdb_test_multiple "print ${expression}" "$test" {
166 -re "\\$\[0-9\]+ = (\[^\r\n\]+).*$gdb_prompt $" {
167 set output_string "$expect_out(1,string)"
170 -re "(Cannot access memory at address \[^\r\n\]+).*$gdb_prompt $" {
171 # Even a failed value is valid
172 set output_string "$expect_out(1,string)"
176 return $output_string
179 # POINTER is a pointer and this proc captures the value of POINTER along
180 # with POINTER's type. For example, POINTER is "&intarray", this proc will
181 # call "p &intarray", capture "(int (*)[32]) 0x804a0e0", and return this
184 proc capture_pointer_with_type { pointer } {
188 set test "capture type of pointer $pointer"
190 gdb_test_multiple "p ${pointer}" $test {
191 -re "\\$\[0-9\]+ = .*$gdb_prompt $" {
192 # Expected output of "p ${pointer}" is like "$7 = (int (*)[32]) 0x804a0e0",
193 # and we want to extract "(int (*)[32]) 0x804a0e0" from it via
195 if [regexp " \\(.*\\).* 0x\[0-9a-fA-F\]+" $expect_out(0,string) output_string] {
196 # OUTPUT_STRING is expected to be like "(int (*)[32]) 0x804a0e0".
204 return $output_string
207 set array_start [capture_value "/x &intarray\[0\]"]
208 set array_end [capture_value "/x &intarray\[32\]"]
209 set struct_start [capture_value "/x &intstruct"]
210 set struct_end [capture_value "/x &intstruct + 1"]
212 set array_val [capture_value "intarray"]
213 set struct_val [capture_value "intstruct"]
215 set array_ptr_type [capture_pointer_with_type "&intarray"]
216 set struct_ptr_type [capture_pointer_with_type "&intstruct"]
218 make_dump_file "dump mem [set intarr2.bin] $array_start $array_end" \
219 "dump array as memory, default"
221 make_dump_file "dump mem [set intstr2.bin] $struct_start $struct_end" \
222 "dump struct as memory, default"
224 make_dump_file "dump bin mem [set intarr2b.bin] $array_start $array_end" \
225 "dump array as memory, binary"
227 make_dump_file "dump bin mem [set intstr2b.bin] $struct_start $struct_end" \
228 "dump struct as memory, binary"
230 make_dump_file "dump srec mem [set intarr2.srec] $array_start $array_end" \
231 "dump array as memory, srec"
233 make_dump_file "dump srec mem [set intstr2.srec] $struct_start $struct_end" \
234 "dump struct as memory, srec"
236 make_dump_file "dump ihex mem [set intarr2.ihex] $array_start $array_end" \
237 "dump array as memory, ihex"
239 make_dump_file "dump ihex mem [set intstr2.ihex] $struct_start $struct_end" \
240 "dump struct as memory, ihex"
242 make_dump_file "dump tekhex mem [set intarr2.tekhex] $array_start $array_end" \
243 "dump array as memory, tekhex"
245 make_dump_file "dump tekhex mem [set intstr2.tekhex] $struct_start $struct_end" \
246 "dump struct as memory, tekhex"
248 make_dump_file "dump verilog mem [set intarr2.verilog] $array_start $array_end" \
249 "dump array as memory, verilog"
251 make_dump_file "dump verilog mem [set intstr2.verilog] $struct_start $struct_end" \
252 "dump struct as memory, verilog"
254 # test complex expressions
256 "dump srec mem [set intarr3.srec] &intarray \(char *\) &intarray + sizeof intarray" \
257 "dump array as mem, srec, expressions"
259 proc test_restore_saved_value { restore_args msg oldval newval } {
262 gdb_test "restore $restore_args" \
264 "$msg; file restored ok"
265 if { ![string compare $oldval \
266 [capture_value $newval "$msg"]] } then {
267 pass "$msg; value restored ok"
269 fail "$msg; value restored ok"
273 if ![string compare $is64bitonly "no"] then {
275 gdb_test "print zero_all ()" ".*"
277 test_restore_saved_value "[set intarr1.srec]" "array as value, srec" \
278 $array_val "intarray"
280 test_restore_saved_value "[set intstr1.srec]" "struct as value, srec" \
281 $struct_val "intstruct"
283 gdb_test "print zero_all ()" "void" "zero all"
285 test_restore_saved_value "[set intarr2.srec]" "array as memory, srec" \
286 $array_val "intarray"
288 test_restore_saved_value "[set intstr2.srec]" "struct as memory, srec" \
289 $struct_val "intstruct"
291 gdb_test "print zero_all ()" ".*"
293 test_restore_saved_value "[set intarr1.ihex]" "array as value, ihex" \
294 $array_val "intarray"
296 test_restore_saved_value "[set intstr1.ihex]" "struct as value, ihex" \
297 $struct_val "intstruct"
299 gdb_test "print zero_all ()" ".*"
301 test_restore_saved_value "[set intarr2.ihex]" "array as memory, ihex" \
302 $array_val "intarray"
304 test_restore_saved_value "[set intstr2.ihex]" "struct as memory, ihex" \
305 $struct_val "intstruct"
307 gdb_test "print zero_all ()" ".*"
309 test_restore_saved_value "[set intarr1.tekhex]" "array as value, tekhex" \
310 $array_val "intarray"
312 test_restore_saved_value "[set intstr1.tekhex]" "struct as value, tekhex" \
313 $struct_val "intstruct"
315 gdb_test "print zero_all ()" ".*"
317 test_restore_saved_value "[set intarr2.tekhex]" "array as memory, tekhex" \
318 $array_val "intarray"
320 test_restore_saved_value "[set intstr2.tekhex]" "struct as memory, tekhex" \
321 $struct_val "intstruct"
324 gdb_test "print zero_all ()" ".*"
326 test_restore_saved_value "[set intarr1.bin] binary $array_start" \
327 "array as value, binary" \
328 $array_val "intarray"
330 test_restore_saved_value "[set intstr1.bin] binary $struct_start" \
331 "struct as value, binary" \
332 $struct_val "intstruct"
334 gdb_test "print zero_all ()" ".*"
336 test_restore_saved_value "[set intarr2.bin] binary $array_start" \
337 "array as memory, binary" \
338 $array_val "intarray"
340 test_restore_saved_value "[set intstr2.bin] binary $struct_start" \
341 "struct as memory, binary" \
342 $struct_val "intstruct"
344 # test restore with offset.
346 set array2_start [capture_value "/x &intarray2\[0\]"]
347 set struct2_start [capture_value "/x &intstruct2"]
349 [capture_value "(char *) &intarray2 - (char *) &intarray"]
351 [capture_value "(char *) &intstruct2 - (char *) &intstruct"]
353 gdb_test "print zero_all ()" ".*"
356 if ![string compare $is64bitonly "no"] then {
357 test_restore_saved_value "[set intarr1.srec] $array2_offset" \
359 $array_val "intarray2"
361 test_restore_saved_value "[set intstr1.srec] $struct2_offset" \
362 "struct copy, srec" \
363 $struct_val "intstruct2"
365 gdb_test "print zero_all ()" ".*"
367 test_restore_saved_value "[set intarr1.ihex] $array2_offset" \
369 $array_val "intarray2"
371 test_restore_saved_value "[set intstr1.ihex] $struct2_offset" \
372 "struct copy, ihex" \
373 $struct_val "intstruct2"
375 gdb_test "print zero_all ()" ".*"
377 test_restore_saved_value "[set intarr1.tekhex] $array2_offset" \
378 "array copy, tekhex" \
379 $array_val "intarray2"
381 test_restore_saved_value "[set intstr1.tekhex] $struct2_offset" \
382 "struct copy, tekhex" \
383 $struct_val "intstruct2"
386 gdb_test "print zero_all ()" ".*"
388 test_restore_saved_value "[set intarr1.bin] binary $array2_start" \
389 "array copy, binary" \
390 $array_val "intarray2"
392 test_restore_saved_value "[set intstr1.bin] binary $struct2_start" \
393 "struct copy, binary" \
394 $struct_val "intstruct2"
397 # test restore with start/stop addresses.
399 # For this purpose, we will restore just the third element of the array,
400 # and check to see that adjacent elements are not modified.
402 # We will need the address and offset of the third and fourth elements.
405 set element3_start [capture_value "/x &intarray\[3\]"]
406 set element4_start [capture_value "/x &intarray\[4\]"]
407 set element3_offset \
408 [capture_value "/x (char *) &intarray\[3\] - (char *) &intarray\[0\]"]
409 set element4_offset \
410 [capture_value "/x (char *) &intarray\[4\] - (char *) &intarray\[0\]"]
412 if ![string compare $is64bitonly "no"] then {
413 gdb_test "print zero_all ()" ".*"
415 test_restore_saved_value "[set intarr1.srec] 0 $element3_start $element4_start" \
416 "array partial, srec" 4 "intarray\[3\]"
418 gdb_test "print intarray\[2\] == 0" " = 1" "element 2 not changed - 1"
419 gdb_test "print intarray\[4\] == 0" " = 1" "element 4 not changed - 1"
421 gdb_test "print zero_all ()" ".*"
423 test_restore_saved_value "[set intarr1.ihex] 0 $element3_start $element4_start" \
424 "array partial, ihex" 4 "intarray\[3\]"
426 gdb_test "print intarray\[2\] == 0" " = 1" "element 2 not changed - 2"
427 gdb_test "print intarray\[4\] == 0" " = 1" "element 4 not changed - 2"
429 gdb_test "print zero_all ()" ".*"
431 test_restore_saved_value "[set intarr1.tekhex] 0 $element3_start $element4_start" \
432 "array partial, tekhex" 4 "intarray\[3\]"
434 gdb_test "print intarray\[2\] == 0" " = 1" "element 2 not changed - 3"
435 gdb_test "print intarray\[4\] == 0" " = 1" "element 4 not changed - 3"
438 gdb_test "print zero_all ()" ".*"
440 test_restore_saved_value \
441 "[set intarr1.bin] binary $array_start $element3_offset $element4_offset" \
442 "array partial, binary" 4 "intarray\[3\]"
444 gdb_test "print intarray\[2\] == 0" " = 1" "element 2 not changed - 4"
445 gdb_test "print intarray\[4\] == 0" " = 1" "element 4 not changed - 4"
447 if ![string compare $is64bitonly "no"] then {
448 gdb_test "print zero_all ()" ".*" ""
450 # restore with expressions
451 test_restore_saved_value \
452 "[set intarr3.srec] (char*)${array2_start}-(char*)${array_start} &intarray\[3\] &intarray\[4\]" \
453 "array partial with expressions" 4 "intarray2\[3\]"
455 gdb_test "print intarray2\[2\] == 0" " = 1" "element 2 not changed, == 4"
456 gdb_test "print intarray2\[4\] == 0" " = 1" "element 4 not changed, == 4"
460 # Now start a fresh gdb session, and reload the saved value files.
464 gdb_file_cmd ${binfile}
466 # Now fix the endianness at the correct state.
468 gdb_test_multiple "set endian $endian" "set endianness" {
469 -re ".* (big|little) endian.*$gdb_prompt $" {
470 pass "setting $endian endianness"
474 # Reload saved values one by one, and compare.
476 if { ![string compare $array_val \
477 [capture_value "intarray" "file binfile; intarray"]] } then {
478 fail "start with intarray un-initialized"
480 pass "start with intarray un-initialized"
483 if { ![string compare $struct_val \
484 [capture_value "intstruct" "file binfile; intstruct"]] } then {
485 fail "start with intstruct un-initialized"
487 pass "start with intstruct un-initialized"
490 proc test_reload_saved_value { filename msg oldval newval } {
493 gdb_file_cmd $filename
494 if { ![string compare $oldval \
495 [capture_value $newval "$msg"]] } then {
496 pass "$msg; value restored ok"
498 fail "$msg; value restored ok"
502 # srec format can not be loaded for 64-bit-only platforms
503 if ![string compare $is64bitonly "no"] then {
504 test_reload_saved_value "[set intarr1.srec]" "reload array as value, srec" \
505 $array_val "\*$array_ptr_type"
506 test_reload_saved_value "[set intstr1.srec]" "reload struct as value, srec" \
507 $struct_val "\*$struct_ptr_type"
508 test_reload_saved_value "[set intarr2.srec]" "reload array as memory, srec" \
509 $array_val "\*$array_ptr_type"
510 test_reload_saved_value "[set intstr2.srec]" "reload struct as memory, srec" \
511 $struct_val "\*$struct_ptr_type"
514 # ihex format can not be loaded for 64-bit-only platforms
515 if ![string compare $is64bitonly "no"] then {
517 test_reload_saved_value "[set intarr1.ihex]" \
518 "reload array as value, intel hex" \
519 $array_val "\*$array_ptr_type"
520 test_reload_saved_value "[set intstr1.ihex]" \
521 "reload struct as value, intel hex" \
522 $struct_val "\*$struct_ptr_type"
523 test_reload_saved_value "[set intarr2.ihex]" \
524 "reload array as memory, intel hex" \
525 $array_val "\*$array_ptr_type"
526 test_reload_saved_value "[set intstr2.ihex]" \
527 "reload struct as memory, intel hex" \
528 $struct_val "\*$struct_ptr_type"
531 # tekhex format can not be loaded for 64-bit-only platforms
532 if ![string compare $is64bitonly "no"] then {
533 test_reload_saved_value "[set intarr1.tekhex]" \
534 "reload array as value, tekhex" \
535 $array_val "\*$array_ptr_type"
536 test_reload_saved_value "[set intstr1.tekhex]" \
537 "reload struct as value, tekhex" \
538 $struct_val "\*$struct_ptr_type"
539 test_reload_saved_value "[set intarr2.tekhex]" \
540 "reload array as memory, tekhex" \
541 $array_val "\*$array_ptr_type"
542 test_reload_saved_value "[set intstr2.tekhex]" \
543 "reload struct as memory, tekhex" \
544 $struct_val "\*$struct_ptr_type"
549 remote_exec host "rm -f $filenames"