1# Test Framework Driver for GDB driving an external simulator 2# Copyright 1999-2021 Free Software Foundation, Inc. 3# 4# This program is free software; you can redistribute it and/or modify 5# it under the terms of the GNU General Public License as published by 6# the Free Software Foundation; either version 3 of the License, or 7# (at your option) any later version. 8# 9# This program is distributed in the hope that it will be useful, 10# but WITHOUT ANY WARRANTY; without even the implied warranty of 11# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12# GNU General Public License for more details. 13# 14# You should have received a copy of the GNU General Public License 15# along with this program. If not, see <http://www.gnu.org/licenses/>. 16 17proc sid_start {} { 18 set port [lindex [split [target_info netport] ":"] 1] 19 20 # Set a default endianness 21 case [target_info multilib_flags] in { 22 { *big-endian* *-EB* *-meb* } { set sidendian "-EB" } 23 { *little-endian* *-EL* *-mel* } { set sidendian "-EL" } 24 default { 25 if {[target_info exists sim,defaultendian]} then { 26 set sidendian [target_info sim,defaultendian] 27 } else { 28 # rely on endianness settings in sid configuration defaults 29 set sidendian "" 30 } 31 } 32 } 33 case $sidendian in { 34 { -EB } { set sidendian2 {-e "set cpu endian big"} } 35 { -EL } { set sidendian2 {-e "set cpu endian little"} } 36 default { set sidendian2 {} } 37 } 38 39 # test to see whether to use use sid in build or install tree 40 set use_build_tree [file exists ../../sid] 41 42 if {$use_build_tree} then { 43 set pre_spawn { 44 global env 45 set env(SID_LIBRARY_PATH) [join [glob "../../sid/component/*"] ":"] 46 set env(SID) "../../sid/main/dynamic/sid" 47 if {! [file exists $env(SID)]} then { error "Cannot find sid in build tree" } 48 } 49 if { [board_info target sim,protocol] == "sid" } { 50 set spawncmd "[target_info sim] [target_info sim,options] $sidendian2 -e \"set cpu-gdb-socket sockaddr-local 0.0.0.0:$port\"" 51 } elseif { [board_info target sim,protocol] == "rawsid" } { 52 set spawncmd "[target_info sim] [target_info sim,options] -$sidendian --gdb=$port" 53 } else { 54 set spawncmd "../../sid/bsp/[target_info sim] $sidendian --gdb=$port [target_info sim,options]" 55 } 56 set post_spawn { 57 global env 58 unset env(SID_LIBRARY_PATH) 59 unset env(SID) 60 } 61 } else { 62 set pre_spawn {} 63 if { [board_info target sim,protocol] == "sid" } { 64 # FIXME: sim,options may be from the build tree, should find 65 # it in the install tree. 66 set spawncmd "sid [target_info sim,options] $sidendian2 -e \"set cpu-gdb-socket sockaddr-local 0.0.0.0:$port\"" 67 } elseif { [board_info target sim,protocol] == "rawsid" } { 68 set spawncmd "[target_info sim] [target_info sim,options] -$sidendian --gdb=$port" 69 } else { 70 set spawncmd "[target_info sim] $sidendian --gdb=$port [target_info sim,options]" 71 } 72 set post_spawn {} 73 } 74 75 eval $pre_spawn 76 if {[catch [list remote_spawn host $spawncmd] msg]} { 77 perror $msg 78 exit 1 79 } 80 eval $post_spawn 81 82 # Don't do the following any more; it breaks with "runtest ... < /dev/null" 83# expect_background { 84# -re \[^\n\]*\n { 85# regsub "\n" $expect_out(buffer) {} msg 86# verbose "SID: $msg" 2 87# } 88# } 89 90 # There should be no need to sleep to give SID time to start; 91 # GDB would wait for a fair while for the stub to respond. 92 sleep 4 93 94 if ![target_info exists gdb,no_push_conn] { 95 remote_push_conn host 96 } 97} 98 99# 100# Handle GDB talking to SID 101# 102 103proc gdb_start {} { 104 sid_start 105 return [default_gdb_start] 106} 107 108proc sid_exit {} { 109 if ![target_info exists gdb,no_push_conn] { 110 remote_close host 111 remote_pop_conn host 112 } 113} 114 115proc gdb_exit {} { 116 set result [default_gdb_exit] 117 sid_exit 118 return $result 119} 120 121# 122# gdb_target_sid 123# Set gdb to target the simulator 124# 125proc send_target_sid { } { 126 # wait a little while, giving sid time to shut down & restart its 127 # gdb socket 128 sleep 4 129 send_gdb "target [target_info gdb_protocol] [target_info netport]\n" 130} 131 132proc gdb_target_sid { } { 133 global gdb_prompt 134 global exit_status 135 136 send_target_sid 137 138 global timeout 139 set prev_timeout $timeout 140 set timeout 60 141 verbose "Timeout is now $timeout seconds" 2 142 gdb_expect { 143 -re ".*\[Ee\]rror.*$gdb_prompt $" { 144 perror "Couldn't set target for remote simulator." 145 gdb_exit 146 } 147 -re "Remote debugging using.*$gdb_prompt" { 148 verbose "Set target to sid" 149 } 150 timeout { 151 perror "Couldn't set target for remote simulator." 152 gdb_exit 153 } 154 } 155 set timeout $prev_timeout 156 verbose "Timeout is now $timeout seconds" 2 157} 158 159# 160# gdb_load -- load a file into the debugger. 161# return a -1 if anything goes wrong. 162# 163proc gdb_load { arg } { 164 global verbose 165 global loadpath 166 global loadfile 167 global GDB 168 global gdb_prompt 169 global retval 170 171 if { $arg != "" } { 172 if [gdb_file_cmd $arg] then { return -1 } 173 } 174 175 gdb_target_sid 176 177 send_gdb "load\n" 178 global timeout 179 set prev_timeout $timeout 180 set timeout 2400 181 verbose "Timeout is now $timeout seconds" 2 182 gdb_expect { 183 -re ".*\[Ee\]rror.*$gdb_prompt $" { 184 if $verbose>1 then { 185 perror "Error during download." 186 } 187 set retval -1 188 } 189 -re ".*$gdb_prompt $" { 190 if $verbose>1 then { 191 send_user "Loaded $arg into $GDB\n" 192 } 193 set retval 0 194 } 195 -re "$gdb_prompt $" { 196 if $verbose>1 then { 197 perror "GDB couldn't load." 198 } 199 set retval -1 200 } 201 timeout { 202 if $verbose>1 then { 203 perror "Timed out trying to load $arg." 204 } 205 set retval -1 206 } 207 } 208 set timeout $prev_timeout 209 verbose "Timeout is now $timeout seconds" 2 210 return $retval 211} 212