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