1# Test Framework Driver for GDB driving a ROM monitor (via monitor.c).
2#   Copyright 1995, 1996, 1997, 1998, 1999, 2000
3#   Free Software Foundation, Inc.
4#
5# This program is free software; you can redistribute it and/or modify
6# it under the terms of the GNU General Public License as published by
7# the Free Software Foundation; either version 2 of the License, or
8# (at your option) any later version.
9#
10# This program is distributed in the hope that it will be useful,
11# but WITHOUT ANY WARRANTY; without even the implied warranty of
12# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13# GNU General Public License for more details.
14#
15# You should have received a copy of the GNU General Public License
16# along with this program; if not, write to the Free Software
17# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
18
19load_lib gdb.exp
20# puts "***** DID USE MONITOR ******"
21
22#
23# gdb_target_cmd
24# Send gdb the "target" command
25#
26proc gdb_target_cmd { targetname serialport } {
27    global gdb_prompt
28
29    for {set i 1} {$i <= 3} {incr i} {
30	send_gdb "target $targetname $serialport\n"
31	gdb_expect 60 {
32	    -re "A program is being debugged already.*ill it.*y or n. $" {
33		send_gdb "y\n";
34		exp_continue;
35	    }
36	    -re "Couldn't establish connection to remote.*$gdb_prompt" {
37		verbose "Connection failed";
38	    }
39	    -re "Remote MIPS debugging.*$gdb_prompt" {
40		verbose "Set target to $targetname";
41		return 0;
42	    }
43	    -re "Remote debugging using .*$serialport.*$gdb_prompt" {
44		verbose "Set target to $targetname";
45		return 0;
46	    }
47	    -re "Remote target $targetname connected to.*$gdb_prompt" {
48		verbose "Set target to $targetname";
49		return 0;
50	    }
51	    -re "Connected to.*$gdb_prompt" {
52		verbose "Set target to $targetname";
53		return 0;
54	    }
55	    -re "Ending remote.*$gdb_prompt" { }
56	    -re "Connection refused.*$gdb_prompt" {
57		verbose "Connection refused by remote target.  Pausing, and trying again."
58		sleep 30
59		continue
60	    }
61	    -re "Timeout reading from remote system.*$gdb_prompt" {
62		verbose "Got timeout error from gdb.";
63	    }
64	    timeout {
65		send_gdb "";
66		break
67	    }
68	}
69    }
70    return 1
71}
72
73
74
75#
76# gdb_target_monitor
77# Set gdb to target the monitor
78#
79proc gdb_target_monitor { exec_file } {
80    global gdb_prompt
81    global exit_status
82    global timeout
83
84    if [target_info exists gdb_protocol] {
85	set targetname "[target_info gdb_protocol]"
86    } else {
87	perror "No protocol specified for [target_info name].";
88	return -1;
89    }
90    if [target_info exists baud] {
91	gdb_test "set remotebaud [target_info baud]" "" ""
92    }
93    if [target_info exists binarydownload] {
94	gdb_test "set remotebinarydownload [target_info binarydownload]" "" ""
95    }
96    if { [ target_info exists disable_x_packet ] } {
97	gdb_test "set remote X-packet disable" ""
98    }
99    if { [ target_info exists disable_z_packet ] } {
100	gdb_test "set remote Z-packet disable" ""
101    }
102    if [target_info exists gdb_serial] {
103       set serialport "[target_info gdb_serial]";
104    } elseif [target_info exists netport] {
105	set serialport "[target_info netport]"
106    } else {
107	set serialport "[target_info serial]"
108    }
109
110    for {set j 1} {$j <= 2} {incr j} {
111	if [gdb_file_cmd $exec_file] { return -1; }
112
113	if ![gdb_target_cmd $targetname $serialport] { return 0; }
114
115	gdb_target_exec;
116
117	if { $j == 1 && ![reboot_target] } {
118	    break;
119	}
120    }
121
122    perror "Couldn't set target for $targetname, port is $serialport.";
123    return -1;
124}
125
126proc gdb_target_exec { } {
127    gdb_test "target exec" "No executable file now." "" ".*Kill it.*y or n.*" "y"
128
129}
130#
131# gdb_load -- load a file into the debugger.
132#             return a -1 if anything goes wrong.
133#
134proc gdb_load { arg } {
135    global verbose
136    global loadpath
137    global loadfile
138    global GDB
139    global gdb_prompt
140    global timeout
141    global last_gdb_file;
142
143    if [target_info exists gdb_download_size] {
144	send_gdb "set download-write-size [target_info gdb_download_size]\n";
145	gdb_expect 30 {
146	    -re "$gdb_prompt $" { }
147	    default {
148		perror "Setting download-write-size for target failed";
149		return -1;
150	    }
151	}
152    }
153
154    if { $arg == "" } {
155	if [info exists last_gdb_file] {
156	    set arg $last_gdb_file;
157	} else {
158	    send_gdb "info files\n";
159	    gdb_expect 30 {
160		-re "Symbols from \"(\[^\"\]+)\"" {
161		    set arg $expect_out(1,string);
162		    exp_continue;
163		}
164		-re "Local exec file:\[\r\n\]+\[ \t\]*`(\[^'\]+)'," {
165		    set arg $expect_out(1,string);
166		    exp_continue;
167		}
168		-re "$gdb_prompt $" { }
169	    }
170	}
171    }
172
173    set last_gdb_file $arg;
174
175    for { set j 1; } { $j <= 2 } {incr j; } {
176	if [target_info exists gdb,use_standard_load] {
177	    gdb_target_exec;
178	    if ![target_info exists gdb,no_push_conn] {
179		remote_push_conn host;
180	    }
181	    set state [remote_ld target $arg];
182	    if ![target_info exists gdb,no_push_conn] {
183		remote_close target;
184		remote_pop_conn host;
185	    }
186	    if { $state == "pass" } {
187		if [gdb_target_monitor $arg] { return -1; }
188		gdb_test "list main" ".*" ""
189		verbose "Loaded $arg into $GDB\n";
190		return 0;
191	    }
192	} else {
193
194	    if [gdb_target_monitor $arg] { return -1 }
195
196	    if [is_remote host] {
197		# FIXME: Multiple downloads. bleah.
198		set farg [remote_download host $arg];
199	    } else {
200		set farg $arg;
201	    }
202
203	    if { $arg != "" && [target_info exists gdb_sect_offset] } {
204		set textoff [target_info gdb_sect_offset];
205		send_gdb "sect .text $textoff\n";
206		gdb_expect 30 {
207		    -re "(0x\[0-9a-z]+) - 0x\[0-9a-z\]+ is \\.data" {
208			set dataoff $expect_out(1,string);
209			exp_continue;
210		    }
211		    -re "(0x\[0-9a-z\]+) - 0x\[0-9a-z\]+ is \\.bss" {
212			set bssoff $expect_out(1,string);
213			exp_continue;
214		    }
215		    -re "$gdb_prompt" { }
216		}
217		set dataoff [format 0x%x [expr $dataoff + $textoff]];
218		set bssoff [format 0x%x [expr $bssoff + $textoff]];
219		send_gdb "sect .data $dataoff\n";
220		gdb_expect 30 {
221		    -re "$gdb_prompt" { }
222		}
223		send_gdb "sect .bss $bssoff\n";
224		gdb_expect 30 {
225		    -re "$gdb_prompt" { }
226		}
227	    }
228
229	    verbose "Loading $farg"
230	    if [target_info exists gdb_load_offset] {
231		set command "load $farg [target_info gdb_load_offset]\n";
232	    } else {
233		set command "load $farg\n";
234	    }
235	    if [target_info exists gdb_load_timeout] {
236		set loadtimeout [target_info gdb_load_timeout]
237	    } else {
238		set loadtimeout 1600
239	    }
240
241	    send_gdb $command;
242	    gdb_expect $loadtimeout {
243		-re "\[Ff\]ailed.*$gdb_prompt $" {
244		    verbose "load failed";
245		}
246		-re "Timeout reading from remote.*$gdb_prompt" {
247		}
248		-re "$gdb_prompt $" {
249		    verbose "Loaded $farg into $GDB\n"
250		    return 0;
251		}
252		timeout {
253		    if { $verbose > 1 } {
254			perror "Timed out trying to load $farg."
255		    }
256		}
257	    }
258	}
259
260	# Make sure we don't have an open connection to the target.
261	gdb_target_exec;
262
263	if { $j == 1 } {
264	    if { ![reboot_target] } {
265		break;
266	    }
267	}
268    }
269    perror "Couldn't load file into GDB.";
270    return -1;
271}
272