1 # Copyright 2002-2013 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 if { [gdb_compile "${srcdir}/${subdir}/${srcfile}" "${binfile}" executable ${options}] != "" } {
44 # Start with a fresh gdb.
48 gdb_reinitialize_dir $srcdir/$subdir
50 gdb_test "dump mem /dev/null 0x10 0x20" "Cannot access memory at address 0x10" \
51 "inaccessible memory is reported"
55 # Check the address of a variable. If it is bigger than 32-bit,
56 # assume our target has 64-bit addresses that are not supported by SREC,
57 # IHEX and TEKHEX. We skip those tests then.
58 set max_32bit_address "0xffffffff"
59 set data_address [get_hexadecimal_valueof "&intarray" 0x100000000]
60 if {${data_address} > ${max_32bit_address}} then {
64 # Clean up any stale output files from previous test runs
68 intarr1.bin intarr1b.bin intarr1.ihex
69 intarr1.srec intarr1.tekhex intarr2.bin intarr2b.bin intarr2.ihex
70 intarr2.srec intarr2.tekhex intstr1.bin intstr1b.bin intstr1.ihex
71 intstr1.srec intstr1.tekhex intstr2.bin intstr2b.bin intstr2.ihex
72 intstr2.srec intstr2.tekhex intarr3.srec
75 # This loop sets variables dynamically -- each name listed in
76 # $ALL_FILES is both a file name and a variable name.
77 foreach file $all_files {
78 if {[is_remote host]} {
81 set this_name [standard_output_file $file]
84 lappend filenames [set ${file} $this_name]
87 remote_exec host "rm -f $filenames"
91 # Run target program until data structs are initialized.
93 if { ! [ runto checkpoint1 ] } then {
98 # Get the endianness for the later use with endianless formats.
100 gdb_test_multiple "show endian" "show endian" {
101 -re ".* (big|little) endian.*$gdb_prompt $" {
102 set endian $expect_out(1,string)
103 pass "endianness: $endian"
107 # Now generate some dump files.
109 proc make_dump_file { command msg } {
112 gdb_test_multiple "${command}" "$msg" {
113 -re ".*\[Ee\]rror.*$gdb_prompt $" { fail $msg }
114 -re ".*\[Ww\]arning.*$gdb_prompt $" { fail $msg }
115 -re ".*\[Uu\]ndefined .*$gdb_prompt $" { fail $msg }
116 -re ".*$gdb_prompt $" { pass $msg }
120 make_dump_file "dump val [set intarr1.bin] intarray" \
121 "dump array as value, default"
123 make_dump_file "dump val [set intstr1.bin] intstruct" \
124 "dump struct as value, default"
126 make_dump_file "dump bin val [set intarr1b.bin] intarray" \
127 "dump array as value, binary"
129 make_dump_file "dump bin val [set intstr1b.bin] intstruct" \
130 "dump struct as value, binary"
132 make_dump_file "dump srec val [set intarr1.srec] intarray" \
133 "dump array as value, srec"
135 make_dump_file "dump srec val [set intstr1.srec] intstruct" \
136 "dump struct as value, srec"
138 make_dump_file "dump ihex val [set intarr1.ihex] intarray" \
139 "dump array as value, intel hex"
141 make_dump_file "dump ihex val [set intstr1.ihex] intstruct" \
142 "dump struct as value, intel hex"
144 make_dump_file "dump tekhex val [set intarr1.tekhex] intarray" \
145 "dump array as value, tekhex"
147 make_dump_file "dump tekhex val [set intstr1.tekhex] intstruct" \
148 "dump struct as value, tekhex"
150 proc capture_value { expression args } {
155 if {[llength $args] > 0} {
156 # Convert $args into a simple string and don't use EXPRESSION
158 set test "[join $args]; capture"
160 set test "capture $expression"
162 gdb_test_multiple "print ${expression}" "$test" {
163 -re "\\$\[0-9\]+ = (\[^\r\n\]+).*$gdb_prompt $" {
164 set output_string "$expect_out(1,string)"
167 -re "(Cannot access memory at address \[^\r\n\]+).*$gdb_prompt $" {
168 # Even a failed value is valid
169 set output_string "$expect_out(1,string)"
173 return $output_string
176 # POINTER is a pointer and this proc captures the value of POINTER along
177 # with POINTER's type. For example, POINTER is "&intarray", this proc will
178 # call "p &intarray", capture "(int (*)[32]) 0x804a0e0", and return this
181 proc capture_pointer_with_type { pointer } {
185 set test "capture type of pointer $pointer"
187 gdb_test_multiple "p ${pointer}" $test {
188 -re "\\$\[0-9\]+ = .*$gdb_prompt $" {
189 # Expected output of "p ${pointer}" is like "$7 = (int (*)[32]) 0x804a0e0",
190 # and we want to extract "(int (*)[32]) 0x804a0e0" from it via
192 if [regexp " \\(.*\\).* 0x\[0-9a-fA-F\]+" $expect_out(0,string) output_string] {
193 # OUTPUT_STRING is expected to be like "(int (*)[32]) 0x804a0e0".
201 return $output_string
204 set array_start [capture_value "/x &intarray\[0\]"]
205 set array_end [capture_value "/x &intarray\[32\]"]
206 set struct_start [capture_value "/x &intstruct"]
207 set struct_end [capture_value "/x &intstruct + 1"]
209 set array_val [capture_value "intarray"]
210 set struct_val [capture_value "intstruct"]
212 set array_ptr_type [capture_pointer_with_type "&intarray"]
213 set struct_ptr_type [capture_pointer_with_type "&intstruct"]
215 make_dump_file "dump mem [set intarr2.bin] $array_start $array_end" \
216 "dump array as memory, default"
218 make_dump_file "dump mem [set intstr2.bin] $struct_start $struct_end" \
219 "dump struct as memory, default"
221 make_dump_file "dump bin mem [set intarr2b.bin] $array_start $array_end" \
222 "dump array as memory, binary"
224 make_dump_file "dump bin mem [set intstr2b.bin] $struct_start $struct_end" \
225 "dump struct as memory, binary"
227 make_dump_file "dump srec mem [set intarr2.srec] $array_start $array_end" \
228 "dump array as memory, srec"
230 make_dump_file "dump srec mem [set intstr2.srec] $struct_start $struct_end" \
231 "dump struct as memory, srec"
233 make_dump_file "dump ihex mem [set intarr2.ihex] $array_start $array_end" \
234 "dump array as memory, ihex"
236 make_dump_file "dump ihex mem [set intstr2.ihex] $struct_start $struct_end" \
237 "dump struct as memory, ihex"
239 make_dump_file "dump tekhex mem [set intarr2.tekhex] $array_start $array_end" \
240 "dump array as memory, tekhex"
242 make_dump_file "dump tekhex mem [set intstr2.tekhex] $struct_start $struct_end" \
243 "dump struct as memory, tekhex"
245 # test complex expressions
247 "dump srec mem [set intarr3.srec] &intarray \(char *\) &intarray + sizeof intarray" \
248 "dump array as mem, srec, expressions"
250 proc test_restore_saved_value { restore_args msg oldval newval } {
253 gdb_test "restore $restore_args" \
255 "$msg; file restored ok"
256 if { ![string compare $oldval \
257 [capture_value $newval "$msg"]] } then {
258 pass "$msg; value restored ok"
260 fail "$msg; value restored ok"
264 if ![string compare $is64bitonly "no"] then {
266 gdb_test "print zero_all ()" ".*"
268 test_restore_saved_value "[set intarr1.srec]" "array as value, srec" \
269 $array_val "intarray"
271 test_restore_saved_value "[set intstr1.srec]" "struct as value, srec" \
272 $struct_val "intstruct"
274 gdb_test "print zero_all ()" "void" "zero all"
276 test_restore_saved_value "[set intarr2.srec]" "array as memory, srec" \
277 $array_val "intarray"
279 test_restore_saved_value "[set intstr2.srec]" "struct as memory, srec" \
280 $struct_val "intstruct"
282 gdb_test "print zero_all ()" ".*"
284 test_restore_saved_value "[set intarr1.ihex]" "array as value, ihex" \
285 $array_val "intarray"
287 test_restore_saved_value "[set intstr1.ihex]" "struct as value, ihex" \
288 $struct_val "intstruct"
290 gdb_test "print zero_all ()" ".*"
292 test_restore_saved_value "[set intarr2.ihex]" "array as memory, ihex" \
293 $array_val "intarray"
295 test_restore_saved_value "[set intstr2.ihex]" "struct as memory, ihex" \
296 $struct_val "intstruct"
298 gdb_test "print zero_all ()" ".*"
300 test_restore_saved_value "[set intarr1.tekhex]" "array as value, tekhex" \
301 $array_val "intarray"
303 test_restore_saved_value "[set intstr1.tekhex]" "struct as value, tekhex" \
304 $struct_val "intstruct"
306 gdb_test "print zero_all ()" ".*"
308 test_restore_saved_value "[set intarr2.tekhex]" "array as memory, tekhex" \
309 $array_val "intarray"
311 test_restore_saved_value "[set intstr2.tekhex]" "struct as memory, tekhex" \
312 $struct_val "intstruct"
315 gdb_test "print zero_all ()" ".*"
317 test_restore_saved_value "[set intarr1.bin] binary $array_start" \
318 "array as value, binary" \
319 $array_val "intarray"
321 test_restore_saved_value "[set intstr1.bin] binary $struct_start" \
322 "struct as value, binary" \
323 $struct_val "intstruct"
325 gdb_test "print zero_all ()" ".*"
327 test_restore_saved_value "[set intarr2.bin] binary $array_start" \
328 "array as memory, binary" \
329 $array_val "intarray"
331 test_restore_saved_value "[set intstr2.bin] binary $struct_start" \
332 "struct as memory, binary" \
333 $struct_val "intstruct"
335 # test restore with offset.
337 set array2_start [capture_value "/x &intarray2\[0\]"]
338 set struct2_start [capture_value "/x &intstruct2"]
340 [capture_value "(char *) &intarray2 - (char *) &intarray"]
342 [capture_value "(char *) &intstruct2 - (char *) &intstruct"]
344 gdb_test "print zero_all ()" ".*"
347 if ![string compare $is64bitonly "no"] then {
348 test_restore_saved_value "[set intarr1.srec] $array2_offset" \
350 $array_val "intarray2"
352 test_restore_saved_value "[set intstr1.srec] $struct2_offset" \
353 "struct copy, srec" \
354 $struct_val "intstruct2"
356 gdb_test "print zero_all ()" ".*"
358 test_restore_saved_value "[set intarr1.ihex] $array2_offset" \
360 $array_val "intarray2"
362 test_restore_saved_value "[set intstr1.ihex] $struct2_offset" \
363 "struct copy, ihex" \
364 $struct_val "intstruct2"
366 gdb_test "print zero_all ()" ".*"
368 test_restore_saved_value "[set intarr1.tekhex] $array2_offset" \
369 "array copy, tekhex" \
370 $array_val "intarray2"
372 test_restore_saved_value "[set intstr1.tekhex] $struct2_offset" \
373 "struct copy, tekhex" \
374 $struct_val "intstruct2"
377 gdb_test "print zero_all ()" ".*"
379 test_restore_saved_value "[set intarr1.bin] binary $array2_start" \
380 "array copy, binary" \
381 $array_val "intarray2"
383 test_restore_saved_value "[set intstr1.bin] binary $struct2_start" \
384 "struct copy, binary" \
385 $struct_val "intstruct2"
388 # test restore with start/stop addresses.
390 # For this purpose, we will restore just the third element of the array,
391 # and check to see that adjacent elements are not modified.
393 # We will need the address and offset of the third and fourth elements.
396 set element3_start [capture_value "/x &intarray\[3\]"]
397 set element4_start [capture_value "/x &intarray\[4\]"]
398 set element3_offset \
399 [capture_value "/x (char *) &intarray\[3\] - (char *) &intarray\[0\]"]
400 set element4_offset \
401 [capture_value "/x (char *) &intarray\[4\] - (char *) &intarray\[0\]"]
403 if ![string compare $is64bitonly "no"] then {
404 gdb_test "print zero_all ()" ".*"
406 test_restore_saved_value "[set intarr1.srec] 0 $element3_start $element4_start" \
407 "array partial, srec" 4 "intarray\[3\]"
409 gdb_test "print intarray\[2\] == 0" " = 1" "element 2 not changed - 1"
410 gdb_test "print intarray\[4\] == 0" " = 1" "element 4 not changed - 1"
412 gdb_test "print zero_all ()" ".*"
414 test_restore_saved_value "[set intarr1.ihex] 0 $element3_start $element4_start" \
415 "array partial, ihex" 4 "intarray\[3\]"
417 gdb_test "print intarray\[2\] == 0" " = 1" "element 2 not changed - 2"
418 gdb_test "print intarray\[4\] == 0" " = 1" "element 4 not changed - 2"
420 gdb_test "print zero_all ()" ".*"
422 test_restore_saved_value "[set intarr1.tekhex] 0 $element3_start $element4_start" \
423 "array partial, tekhex" 4 "intarray\[3\]"
425 gdb_test "print intarray\[2\] == 0" " = 1" "element 2 not changed - 3"
426 gdb_test "print intarray\[4\] == 0" " = 1" "element 4 not changed - 3"
429 gdb_test "print zero_all ()" ".*"
431 test_restore_saved_value \
432 "[set intarr1.bin] binary $array_start $element3_offset $element4_offset" \
433 "array partial, binary" 4 "intarray\[3\]"
435 gdb_test "print intarray\[2\] == 0" " = 1" "element 2 not changed - 4"
436 gdb_test "print intarray\[4\] == 0" " = 1" "element 4 not changed - 4"
438 if ![string compare $is64bitonly "no"] then {
439 gdb_test "print zero_all ()" ".*" ""
441 # restore with expressions
442 test_restore_saved_value \
443 "[set intarr3.srec] (char*)${array2_start}-(char*)${array_start} &intarray\[3\] &intarray\[4\]" \
444 "array partial with expressions" 4 "intarray2\[3\]"
446 gdb_test "print intarray2\[2\] == 0" " = 1" "element 2 not changed, == 4"
447 gdb_test "print intarray2\[4\] == 0" " = 1" "element 4 not changed, == 4"
451 # Now start a fresh gdb session, and reload the saved value files.
455 gdb_file_cmd ${binfile}
457 # Now fix the endianness at the correct state.
459 gdb_test_multiple "set endian $endian" "set endianness" {
460 -re ".* (big|little) endian.*$gdb_prompt $" {
461 pass "setting $endian endianness"
465 # Reload saved values one by one, and compare.
467 if { ![string compare $array_val \
468 [capture_value "intarray" "file binfile; intarray"]] } then {
469 fail "start with intarray un-initialized"
471 pass "start with intarray un-initialized"
474 if { ![string compare $struct_val \
475 [capture_value "intstruct" "file binfile; intstruct"]] } then {
476 fail "start with intstruct un-initialized"
478 pass "start with intstruct un-initialized"
481 proc test_reload_saved_value { filename msg oldval newval } {
484 gdb_file_cmd $filename
485 if { ![string compare $oldval \
486 [capture_value $newval "$msg"]] } then {
487 pass "$msg; value restored ok"
489 fail "$msg; value restored ok"
493 # srec format can not be loaded for 64-bit-only platforms
494 if ![string compare $is64bitonly "no"] then {
495 test_reload_saved_value "[set intarr1.srec]" "reload array as value, srec" \
496 $array_val "\*$array_ptr_type"
497 test_reload_saved_value "[set intstr1.srec]" "reload struct as value, srec" \
498 $struct_val "\*$struct_ptr_type"
499 test_reload_saved_value "[set intarr2.srec]" "reload array as memory, srec" \
500 $array_val "\*$array_ptr_type"
501 test_reload_saved_value "[set intstr2.srec]" "reload struct as memory, srec" \
502 $struct_val "\*$struct_ptr_type"
505 # ihex format can not be loaded for 64-bit-only platforms
506 if ![string compare $is64bitonly "no"] then {
508 test_reload_saved_value "[set intarr1.ihex]" \
509 "reload array as value, intel hex" \
510 $array_val "\*$array_ptr_type"
511 test_reload_saved_value "[set intstr1.ihex]" \
512 "reload struct as value, intel hex" \
513 $struct_val "\*$struct_ptr_type"
514 test_reload_saved_value "[set intarr2.ihex]" \
515 "reload array as memory, intel hex" \
516 $array_val "\*$array_ptr_type"
517 test_reload_saved_value "[set intstr2.ihex]" \
518 "reload struct as memory, intel hex" \
519 $struct_val "\*$struct_ptr_type"
522 # tekhex format can not be loaded for 64-bit-only platforms
523 if ![string compare $is64bitonly "no"] then {
524 test_reload_saved_value "[set intarr1.tekhex]" \
525 "reload array as value, tekhex" \
526 $array_val "\*$array_ptr_type"
527 test_reload_saved_value "[set intstr1.tekhex]" \
528 "reload struct as value, tekhex" \
529 $struct_val "\*$struct_ptr_type"
530 test_reload_saved_value "[set intarr2.tekhex]" \
531 "reload array as memory, tekhex" \
532 $array_val "\*$array_ptr_type"
533 test_reload_saved_value "[set intstr2.tekhex]" \
534 "reload struct as memory, tekhex" \
535 $struct_val "\*$struct_ptr_type"
540 remote_exec host "rm -f $filenames"