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