Fix: Null pointer dereference in ldlex.l
[binutils-gdb.git] / gdb / testsuite / gdb.base / dump.exp
blobb361d05d392f66ff5cb02f1cabb2289f93fcbd74
1 # Copyright 2002-2023 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".
20 standard_testfile
22 set options {debug}
24 set is64bitonly "no"
25 set endian "auto"
27 set formats {binary ihex srec tekhex verilog}
29 if {[istarget "alpha*-*-*"]} {
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 "ldflags=-Wl,-taso"
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
41 incr print_zero_all_count
42 gdb_test "print zero_all ()" " = void" \
43 "call ${print_zero_all_count} to zero_all function"
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}
50 if { [gdb_compile "${srcdir}/${subdir}/${srcfile}" "${binfile}" executable ${options}] != "" } {
51 untested "failed to compile"
52 return -1
55 clean_restart $binfile
57 gdb_test "dump mem /dev/null 0x10 0x20" "Cannot access memory at address 0x10" \
58 "inaccessible memory is reported"
60 gdb_load ${binfile}
62 # Check the address of a variable. If it is bigger than 32-bit,
63 # assume our target has 64-bit addresses that are not supported by SREC,
64 # IHEX and TEKHEX. We skip those tests then.
65 set max_32bit_address "0xffffffff"
66 set data_address [get_hexadecimal_valueof "&intarray" 0x100000000]
67 if {${data_address} > ${max_32bit_address}} {
68 set is64bitonly "yes"
71 # Clean up any stale output files from previous test runs
73 set filenames {}
74 set all_files {
75 intarr1.bin intarr1b.bin intarr1.ihex
76 intarr1.srec intarr1.tekhex intarr1.verilog
77 intarr2.bin intarr2b.bin intarr2.ihex
78 intarr2.srec intarr2.tekhex intarr2.verilog
79 intstr1.bin intstr1b.bin intstr1.ihex
80 intstr1.srec intstr1.tekhex intstr1.verilog
81 intstr2.bin intstr2b.bin intstr2.ihex
82 intstr2.srec intstr2.tekhex intstr2.verilog
83 intarr3.srec
86 # This loop sets variables dynamically -- each name listed in
87 # $ALL_FILES is both a file name and a variable name.
88 foreach file $all_files {
89 if {[is_remote host]} {
90 set this_name $file
91 } else {
92 set this_name [standard_output_file $file]
95 lappend filenames [set ${file} $this_name]
98 remote_exec host "rm -f $filenames"
100 # Test help (FIXME:)
102 # Run target program until data structs are initialized.
104 if {![runto checkpoint1]} {
105 untested "couldn't run to checkpoint"
106 return -1
109 # Get the endianness for the later use with endianless formats.
111 set endian [get_endianness]
113 # Now generate some dump files.
115 proc make_dump_file { command msg } {
116 global gdb_prompt
118 gdb_test_multiple "${command}" "$msg" {
119 -re ".*\[Ee\]rror.*$gdb_prompt $" { fail $msg }
120 -re ".*\[Ww\]arning.*$gdb_prompt $" { fail $msg }
121 -re ".*\[Uu\]ndefined .*$gdb_prompt $" { fail $msg }
122 -re ".*$gdb_prompt $" { pass $msg }
126 make_dump_file "dump val [set intarr1.bin] intarray" \
127 "dump array as value, default"
129 make_dump_file "dump val [set intstr1.bin] intstruct" \
130 "dump struct as value, default"
132 make_dump_file "dump bin val [set intarr1b.bin] intarray" \
133 "dump array as value, binary"
135 make_dump_file "dump bin val [set intstr1b.bin] intstruct" \
136 "dump struct as value, binary"
138 make_dump_file "dump srec val [set intarr1.srec] intarray" \
139 "dump array as value, srec"
141 make_dump_file "dump srec val [set intstr1.srec] intstruct" \
142 "dump struct as value, srec"
144 # 64-bit address out of range for Intel Hex file
145 if {![string compare $is64bitonly "no"]} {
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"
153 make_dump_file "dump tekhex val [set intarr1.tekhex] intarray" \
154 "dump array as value, tekhex"
156 make_dump_file "dump tekhex val [set intstr1.tekhex] intstruct" \
157 "dump struct as value, tekhex"
159 make_dump_file "dump verilog val [set intarr1.verilog] intarray" \
160 "dump array as value, verilog"
162 make_dump_file "dump verilog val [set intstr1.verilog] intstruct" \
163 "dump struct as value, verilog"
165 proc capture_value { expression args } {
166 global gdb_prompt
167 global expect_out
169 set output_string ""
170 if {[llength $args] > 0} {
171 # Convert $args into a simple string and don't use EXPRESSION
172 # in the test name.
173 set test "[join $args]; capture"
175 set test "capture $expression"
177 gdb_test_multiple "print ${expression}" "$test" {
178 -re "\\$\[0-9\]+ = (\[^\r\n\]+).*$gdb_prompt $" {
179 set output_string "$expect_out(1,string)"
180 pass "$test"
182 -re "(Cannot access memory at address \[^\r\n\]+).*$gdb_prompt $" {
183 # Even a failed value is valid
184 set output_string "$expect_out(1,string)"
185 pass "$test"
188 return $output_string
191 # POINTER is a pointer and this proc captures the value of POINTER along
192 # with POINTER's type. For example, POINTER is "&intarray", this proc will
193 # call "p &intarray", capture "(int (*)[32]) 0x804a0e0", and return this
194 # string.
196 proc capture_pointer_with_type { pointer } {
197 global gdb_prompt
198 global expect_out
200 set test "capture type of pointer $pointer"
201 set output_string ""
202 gdb_test_multiple "p ${pointer}" $test {
203 -re "\\$\[0-9\]+ = .*$gdb_prompt $" {
204 # Expected output of "p ${pointer}" is like "$7 = (int (*)[32]) 0x804a0e0",
205 # and we want to extract "(int (*)[32]) 0x804a0e0" from it via
206 # following regexp.
207 if [regexp " \\(.*\\).* 0x\[0-9a-fA-F\]+" $expect_out(0,string) output_string] {
208 # OUTPUT_STRING is expected to be like "(int (*)[32]) 0x804a0e0".
209 pass "$test"
210 } else {
211 fail "$test"
216 return $output_string
219 set array_start [capture_value "/x &intarray\[0\]"]
220 set array_end [capture_value "/x &intarray\[32\]"]
221 set struct_start [capture_value "/x &intstruct"]
222 set struct_end [capture_value "/x &intstruct + 1"]
224 set array_val [capture_value "intarray"]
225 set struct_val [capture_value "intstruct"]
227 set array_ptr_type [capture_pointer_with_type "&intarray"]
228 set struct_ptr_type [capture_pointer_with_type "&intstruct"]
230 make_dump_file "dump mem [set intarr2.bin] $array_start $array_end" \
231 "dump array as memory, default"
233 make_dump_file "dump mem [set intstr2.bin] $struct_start $struct_end" \
234 "dump struct as memory, default"
236 make_dump_file "dump bin mem [set intarr2b.bin] $array_start $array_end" \
237 "dump array as memory, binary"
239 make_dump_file "dump bin mem [set intstr2b.bin] $struct_start $struct_end" \
240 "dump struct as memory, binary"
242 make_dump_file "dump srec mem [set intarr2.srec] $array_start $array_end" \
243 "dump array as memory, srec"
245 make_dump_file "dump srec mem [set intstr2.srec] $struct_start $struct_end" \
246 "dump struct as memory, srec"
248 # 64-bit address out of range for Intel Hex file
249 if {![string compare $is64bitonly "no"]} {
250 make_dump_file "dump ihex mem [set intarr2.ihex] $array_start $array_end" \
251 "dump array as memory, ihex"
253 make_dump_file "dump ihex mem [set intstr2.ihex] $struct_start $struct_end" \
254 "dump struct as memory, ihex"
257 make_dump_file "dump tekhex mem [set intarr2.tekhex] $array_start $array_end" \
258 "dump array as memory, tekhex"
260 make_dump_file "dump tekhex mem [set intstr2.tekhex] $struct_start $struct_end" \
261 "dump struct as memory, tekhex"
263 make_dump_file "dump verilog mem [set intarr2.verilog] $array_start $array_end" \
264 "dump array as memory, verilog"
266 make_dump_file "dump verilog mem [set intstr2.verilog] $struct_start $struct_end" \
267 "dump struct as memory, verilog"
269 # test complex expressions
270 make_dump_file \
271 "dump srec mem [set intarr3.srec] &intarray \(char *\) &intarray + sizeof intarray" \
272 "dump array as mem, srec, expressions"
274 proc test_restore_saved_value { restore_args msg oldval newval } {
275 global gdb_prompt
277 gdb_test "restore $restore_args" \
278 "Restoring .*" \
279 "$msg; file restored ok"
280 if { ![string compare $oldval \
281 [capture_value $newval "$msg"]] } then {
282 pass "$msg; value restored ok"
283 } else {
284 fail "$msg; value restored ok"
288 if {![string compare $is64bitonly "no"]} {
291 test_restore_saved_value "[set intarr1.srec]" "array as value, srec" \
292 $array_val "intarray"
294 test_restore_saved_value "[set intstr1.srec]" "struct as value, srec" \
295 $struct_val "intstruct"
297 print_zero_all
299 test_restore_saved_value "[set intarr2.srec]" "array as memory, srec" \
300 $array_val "intarray"
302 test_restore_saved_value "[set intstr2.srec]" "struct as memory, srec" \
303 $struct_val "intstruct"
305 print_zero_all
307 test_restore_saved_value "[set intarr1.ihex]" "array as value, ihex" \
308 $array_val "intarray"
310 test_restore_saved_value "[set intstr1.ihex]" "struct as value, ihex" \
311 $struct_val "intstruct"
313 print_zero_all
315 test_restore_saved_value "[set intarr2.ihex]" "array as memory, ihex" \
316 $array_val "intarray"
318 test_restore_saved_value "[set intstr2.ihex]" "struct as memory, ihex" \
319 $struct_val "intstruct"
321 print_zero_all
323 test_restore_saved_value "[set intarr1.tekhex]" "array as value, tekhex" \
324 $array_val "intarray"
326 test_restore_saved_value "[set intstr1.tekhex]" "struct as value, tekhex" \
327 $struct_val "intstruct"
329 print_zero_all
331 test_restore_saved_value "[set intarr2.tekhex]" "array as memory, tekhex" \
332 $array_val "intarray"
334 test_restore_saved_value "[set intstr2.tekhex]" "struct as memory, tekhex" \
335 $struct_val "intstruct"
338 print_zero_all
340 test_restore_saved_value "[set intarr1.bin] binary $array_start" \
341 "array as value, binary" \
342 $array_val "intarray"
344 test_restore_saved_value "[set intstr1.bin] binary $struct_start" \
345 "struct as value, binary" \
346 $struct_val "intstruct"
348 print_zero_all
350 test_restore_saved_value "[set intarr2.bin] binary $array_start" \
351 "array as memory, binary" \
352 $array_val "intarray"
354 test_restore_saved_value "[set intstr2.bin] binary $struct_start" \
355 "struct as memory, binary" \
356 $struct_val "intstruct"
358 # test restore with offset.
360 set array2_start [capture_value "/x &intarray2\[0\]"]
361 set struct2_start [capture_value "/x &intstruct2"]
362 set array2_offset \
363 [capture_value "(char *) &intarray2 - (char *) &intarray"]
364 set struct2_offset \
365 [capture_value "(char *) &intstruct2 - (char *) &intstruct"]
367 print_zero_all
370 if {![string compare $is64bitonly "no"]} {
371 test_restore_saved_value "[set intarr1.srec] $array2_offset" \
372 "array copy, srec" \
373 $array_val "intarray2"
375 test_restore_saved_value "[set intstr1.srec] $struct2_offset" \
376 "struct copy, srec" \
377 $struct_val "intstruct2"
379 print_zero_all
381 test_restore_saved_value "[set intarr1.ihex] $array2_offset" \
382 "array copy, ihex" \
383 $array_val "intarray2"
385 test_restore_saved_value "[set intstr1.ihex] $struct2_offset" \
386 "struct copy, ihex" \
387 $struct_val "intstruct2"
389 print_zero_all
391 test_restore_saved_value "[set intarr1.tekhex] $array2_offset" \
392 "array copy, tekhex" \
393 $array_val "intarray2"
395 test_restore_saved_value "[set intstr1.tekhex] $struct2_offset" \
396 "struct copy, tekhex" \
397 $struct_val "intstruct2"
400 print_zero_all
402 test_restore_saved_value "[set intarr1.bin] binary $array2_start" \
403 "array copy, binary" \
404 $array_val "intarray2"
406 test_restore_saved_value "[set intstr1.bin] binary $struct2_start" \
407 "struct copy, binary" \
408 $struct_val "intstruct2"
411 # test restore with start/stop addresses.
413 # For this purpose, we will restore just the third element of the array,
414 # and check to see that adjacent elements are not modified.
416 # We will need the address and offset of the third and fourth elements.
419 set element3_start [capture_value "/x &intarray\[3\]"]
420 set element4_start [capture_value "/x &intarray\[4\]"]
421 set element3_offset \
422 [capture_value "/x (char *) &intarray\[3\] - (char *) &intarray\[0\]"]
423 set element4_offset \
424 [capture_value "/x (char *) &intarray\[4\] - (char *) &intarray\[0\]"]
426 if {![string compare $is64bitonly "no"]} {
427 print_zero_all
429 test_restore_saved_value "[set intarr1.srec] 0 $element3_start $element4_start" \
430 "array partial, srec" 4 "intarray\[3\]"
432 gdb_test "print intarray\[2\] == 0" " = 1" "element 2 not changed - 1"
433 gdb_test "print intarray\[4\] == 0" " = 1" "element 4 not changed - 1"
435 print_zero_all
437 test_restore_saved_value "[set intarr1.ihex] 0 $element3_start $element4_start" \
438 "array partial, ihex" 4 "intarray\[3\]"
440 gdb_test "print intarray\[2\] == 0" " = 1" "element 2 not changed - 2"
441 gdb_test "print intarray\[4\] == 0" " = 1" "element 4 not changed - 2"
443 print_zero_all
445 test_restore_saved_value "[set intarr1.tekhex] 0 $element3_start $element4_start" \
446 "array partial, tekhex" 4 "intarray\[3\]"
448 gdb_test "print intarray\[2\] == 0" " = 1" "element 2 not changed - 3"
449 gdb_test "print intarray\[4\] == 0" " = 1" "element 4 not changed - 3"
452 print_zero_all
454 test_restore_saved_value \
455 "[set intarr1.bin] binary $array_start $element3_offset $element4_offset" \
456 "array partial, binary" 4 "intarray\[3\]"
458 gdb_test "print intarray\[2\] == 0" " = 1" "element 2 not changed - 4"
459 gdb_test "print intarray\[4\] == 0" " = 1" "element 4 not changed - 4"
461 if {![string compare $is64bitonly "no"]} {
462 print_zero_all
464 # restore with expressions
465 test_restore_saved_value \
466 "[set intarr3.srec] (char*)${array2_start}-(char*)${array_start} &intarray\[3\] &intarray\[4\]" \
467 "array partial with expressions" 4 "intarray2\[3\]"
469 gdb_test "print intarray2\[2\] == 0" " = 1" "element 2 not changed, == 4"
470 gdb_test "print intarray2\[4\] == 0" " = 1" "element 4 not changed, == 4"
474 # Test writing a file of each format to a directory that does not exist.
476 foreach_with_prefix format $formats {
477 gdb_test "dump $format memory /tmp/non/existent/directory/file $array_start $array_end" \
478 "/tmp/non/existent/directory/file: No such file or directory." \
479 "dump to non-existent directory"
482 # Now start a fresh gdb session, and reload the saved value files.
484 clean_restart
485 gdb_file_cmd ${binfile}
487 # Now fix the endianness at the correct state.
489 gdb_test_multiple "set endian $endian" "set endianness" {
490 -re ".* (big|little) endian.*$gdb_prompt $" {
491 pass "setting $endian endianness"
495 # Reload saved values one by one, and compare.
497 if { ![string compare $array_val \
498 [capture_value "intarray" "file binfile; intarray"]] } then {
499 fail "start with intarray un-initialized"
500 } else {
501 pass "start with intarray un-initialized"
504 if { ![string compare $struct_val \
505 [capture_value "intstruct" "file binfile; intstruct"]] } then {
506 fail "start with intstruct un-initialized"
507 } else {
508 pass "start with intstruct un-initialized"
511 proc test_reload_saved_value { filename msg oldval newval } {
512 global gdb_prompt
514 gdb_file_cmd $filename
515 if { ![string compare $oldval \
516 [capture_value $newval "$msg"]] } then {
517 pass "$msg; value restored ok"
518 } else {
519 fail "$msg; value restored ok"
523 # srec format can not be loaded for 64-bit-only platforms
524 if {![string compare $is64bitonly "no"]} {
525 test_reload_saved_value "[set intarr1.srec]" "reload array as value, srec" \
526 $array_val "\*$array_ptr_type"
527 test_reload_saved_value "[set intstr1.srec]" "reload struct as value, srec" \
528 $struct_val "\*$struct_ptr_type"
529 test_reload_saved_value "[set intarr2.srec]" "reload array as memory, srec" \
530 $array_val "\*$array_ptr_type"
531 test_reload_saved_value "[set intstr2.srec]" "reload struct as memory, srec" \
532 $struct_val "\*$struct_ptr_type"
535 # ihex format can not be loaded for 64-bit-only platforms
536 if {![string compare $is64bitonly "no"]} {
538 test_reload_saved_value "[set intarr1.ihex]" \
539 "reload array as value, intel hex" \
540 $array_val "\*$array_ptr_type"
541 test_reload_saved_value "[set intstr1.ihex]" \
542 "reload struct as value, intel hex" \
543 $struct_val "\*$struct_ptr_type"
544 test_reload_saved_value "[set intarr2.ihex]" \
545 "reload array as memory, intel hex" \
546 $array_val "\*$array_ptr_type"
547 test_reload_saved_value "[set intstr2.ihex]" \
548 "reload struct as memory, intel hex" \
549 $struct_val "\*$struct_ptr_type"
552 # tekhex format can not be loaded for 64-bit-only platforms
553 if {![string compare $is64bitonly "no"]} {
554 test_reload_saved_value "[set intarr1.tekhex]" \
555 "reload array as value, tekhex" \
556 $array_val "\*$array_ptr_type"
557 test_reload_saved_value "[set intstr1.tekhex]" \
558 "reload struct as value, tekhex" \
559 $struct_val "\*$struct_ptr_type"
560 test_reload_saved_value "[set intarr2.tekhex]" \
561 "reload array as memory, tekhex" \
562 $array_val "\*$array_ptr_type"
563 test_reload_saved_value "[set intstr2.tekhex]" \
564 "reload struct as memory, tekhex" \
565 $struct_val "\*$struct_ptr_type"
568 # clean up files
570 remote_exec host "rm -f $filenames"