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