# Test Framework Driver for GDB driving an external simulator # Copyright 1999-2019 Free Software Foundation, Inc. # # This program is free software; you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation; either version 3 of the License, or # (at your option) any later version. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program. If not, see . proc sid_start {} { global verbose set port [lindex [split [target_info netport] ":"] 1] # Set a default endianness case [target_info multilib_flags] in { { *big-endian* *-EB* *-meb* } { set sidendian "-EB" } { *little-endian* *-EL* *-mel* } { set sidendian "-EL" } default { if {[target_info exists sim,defaultendian]} then { set sidendian [target_info sim,defaultendian] } else { # rely on endianness settings in sid configuration defaults set sidendian "" } } } case $sidendian in { { -EB } { set sidendian2 {-e "set cpu endian big"} } { -EL } { set sidendian2 {-e "set cpu endian little"} } default { set sidendian2 {} } } # test to see whether to use use sid in build or install tree set use_build_tree [file exists ../../sid] if {$use_build_tree} then { set pre_spawn { global env set env(SID_LIBRARY_PATH) [join [glob "../../sid/component/*"] ":"] set env(SID) "../../sid/main/dynamic/sid" if {! [file exists $env(SID)]} then { error "Cannot find sid in build tree" } } if { [board_info target sim,protocol] == "sid" } { set spawncmd "[target_info sim] [target_info sim,options] $sidendian2 -e \"set cpu-gdb-socket sockaddr-local 0.0.0.0:$port\"" } elseif { [board_info target sim,protocol] == "rawsid" } { set spawncmd "[target_info sim] [target_info sim,options] -$sidendian --gdb=$port" } else { set spawncmd "../../sid/bsp/[target_info sim] $sidendian --gdb=$port [target_info sim,options]" } set post_spawn { global env unset env(SID_LIBRARY_PATH) unset env(SID) } } else { set pre_spawn {} if { [board_info target sim,protocol] == "sid" } { # FIXME: sim,options may be from the build tree, should find # it in the install tree. set spawncmd "sid [target_info sim,options] $sidendian2 -e \"set cpu-gdb-socket sockaddr-local 0.0.0.0:$port\"" } elseif { [board_info target sim,protocol] == "rawsid" } { set spawncmd "[target_info sim] [target_info sim,options] -$sidendian --gdb=$port" } else { set spawncmd "[target_info sim] $sidendian --gdb=$port [target_info sim,options]" } set post_spawn {} } eval $pre_spawn if {[catch [list remote_spawn host $spawncmd] msg]} { perror $msg exit 1 } eval $post_spawn # Don't do the following any more; it breaks with "runtest ... < /dev/null" # expect_background { # -re \[^\n\]*\n { # regsub "\n" $expect_out(buffer) {} msg # verbose "SID: $msg" 2 # } # } # There should be no need to sleep to give SID time to start; # GDB would wait for a fair while for the stub to respond. sleep 4 if ![target_info exists gdb,no_push_conn] { remote_push_conn host } } # # Handle GDB talking to SID # proc gdb_start {} { sid_start return [default_gdb_start] } proc sid_exit {} { if ![target_info exists gdb,no_push_conn] { remote_close host remote_pop_conn host } } proc gdb_exit {} { set result [default_gdb_exit] sid_exit return $result } # # gdb_target_sid # Set gdb to target the simulator # proc send_target_sid { } { # wait a little while, giving sid time to shut down & restart its # gdb socket sleep 4 send_gdb "target [target_info gdb_protocol] [target_info netport]\n" } proc gdb_target_sid { } { global gdb_prompt global exit_status send_target_sid global timeout set prev_timeout $timeout set timeout 60 verbose "Timeout is now $timeout seconds" 2 gdb_expect { -re ".*\[Ee\]rror.*$gdb_prompt $" { perror "Couldn't set target for remote simulator." gdb_exit } -re "Remote debugging using.*$gdb_prompt" { verbose "Set target to sid" } timeout { perror "Couldn't set target for remote simulator." gdb_exit } } set timeout $prev_timeout verbose "Timeout is now $timeout seconds" 2 } # # gdb_load -- load a file into the debugger. # return a -1 if anything goes wrong. # proc gdb_load { arg } { global verbose global loadpath global loadfile global GDB global gdb_prompt global retval if { $arg != "" } { if [gdb_file_cmd $arg] then { return -1 } } gdb_target_sid send_gdb "load\n" global timeout set prev_timeout $timeout set timeout 2400 verbose "Timeout is now $timeout seconds" 2 gdb_expect { -re ".*\[Ee\]rror.*$gdb_prompt $" { if $verbose>1 then { perror "Error during download." } set retval -1 } -re ".*$gdb_prompt $" { if $verbose>1 then { send_user "Loaded $arg into $GDB\n" } set retval 0 } -re "$gdb_prompt $" { if $verbose>1 then { perror "GDB couldn't load." } set retval -1 } timeout { if $verbose>1 then { perror "Timed out trying to load $arg." } set retval -1 } } set timeout $prev_timeout verbose "Timeout is now $timeout seconds" 2 return $retval }