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