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