Regenerate build system files
[dejagnu.git] / config / gdb_stub.exp
blob6ad22a1551f8e031a04f51b824331f9fa2a7a4f3
1 # Copyright (C) 1992-2016 Free Software Foundation, Inc.
3 # This file is part of DejaGnu.
5 # DejaGnu is free software; you can redistribute it and/or modify it
6 # 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.
10 # DejaGnu is distributed in the hope that it will be useful, but
11 # WITHOUT ANY WARRANTY; without even the implied warranty of
12 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 # General Public License for more details.
15 # You should have received a copy of the GNU General Public License
16 # along with DejaGnu; if not, write to the Free Software Foundation,
17 # Inc., 51 Franklin Street - Fifth Floor, Boston, MA 02110-1301, USA.
19 # This file was written by Michael Snyder <msnyder@cygnus.com>.
22 # Stub remote run command.
25 proc gdb_stub_init { dest args } {
26 global gdb_prompt
27 global GDB
28 global tool_root_dir
30 if {![info exists GDB]} then {
31 set GDB "[lookfor_file $tool_root_dir gdb/gdb]"
32 if { $GDB eq "" } {
33 set GDB [transform gdb]
37 if {[board_info $dest exists gdb_prompt]} {
38 set gdb_prompt [board_info $dest gdb_prompt]
39 } else {
40 set gdb_prompt {\(gdb\)}
43 return 1
46 proc gdb_stub_restart { dest } {
47 global gdb_prompt
48 global GDB
50 gdb_stub_init $dest
52 for { set x 1 } { $x < 4 } {incr x} {
53 remote_close $dest
54 sleep 2
55 set command "$GDB -nw -nx"
56 if {[host_info exists gdb_opts]} {
57 append command " [host_info gdb_opts]"
59 set spawn_id [remote_spawn host $command]
60 remote_expect host 30 {
61 -re $gdb_prompt { }
63 if { $spawn_id >= 0 } {
64 if {[board_info $dest exists baud]} {
65 remote_send host "set remotebaud [board_info $dest baud]\n"
66 remote_expect host 5 {
67 -re $gdb_prompt { }
68 default {
69 warning "Error setting baud rate."
70 return -1
76 set value [gdb_stub_startup $dest]
77 if { $value > 0 } {
78 break
80 verbose "got $value from gdb_stub_startup"
81 remote_send host "quit\n"
83 remote_reboot $dest
85 if { $x < 4 } {
86 global board_info
87 set name [board_info $dest name]
89 set board_info($name,gdb_is_running) 1
90 return 1
91 } else {
92 return 0
96 proc gdb_stub_remote_check { dest } {
97 global gdb_prompt
99 if {[board_info $dest exists gdb_serial]} {
100 set serial [board_info $dest gdb_serial]
101 } elseif {[board_info $dest exists serial]} {
102 set serial [board_info $dest serial]
103 } else {
104 set serial [board_info $dest netport]
106 remote_send host "target remote $serial\n"
107 remote_expect host 10 {
108 -re "Couldn't establish connection.*$gdb_prompt" {
109 return 0
111 -re "Remote debugging.*$gdb_prompt" {
112 verbose "stub is already running"
113 return 1
115 -re $gdb_prompt {
116 return 0
118 timeout {
119 remote_send host "\003"
120 remote_expect host 10 {
121 -re $gdb_prompt { }
123 return 0
125 default {
126 return 0
131 proc gdb_stub_startup { dest } {
132 global gdb_prompt
133 global GDB
135 set is_running_stub 0
137 if {[gdb_stub_remote_check $dest]} {
138 set is_running_stub 1
141 if {[board_info $dest exists serial]} {
142 set serial [board_info $dest serial]
143 } else {
144 set serial [board_info $dest netport]
147 if { ! $is_running_stub } {
148 set command "target [board_info $dest gdb_protocol] $serial\n"
149 remote_send host $command
150 remote_expect host 5 {
151 -re "already.*y or n." {
152 remote_send host "y\n"
153 exp_continue
155 -re "appears to be alive.*$gdb_prompt" { }
156 -re "Remote target.*connected to.*$gdb_prompt" { }
157 default {
158 return -1
162 if { $is_running_stub == 0 } {
163 global libdir
165 verbose "building loader"
166 set loader "loader"
167 if {![file exists $loader]} {
168 if {[board_info $dest exists gdb_stub_offset]} {
169 set result [target_compile $libdir/stub-loader.c $loader executable "libs=-Wl,-Ttext,[board_info $dest gdb_stub_offset]"]
170 } else {
171 set result [target_compile $libdir/stub-loader.c $loader executable "ldscript=[board_info $dest gdb_stub_ldscript]"]
173 verbose "result is $result"
174 if {[isremote host]} {
175 set loader [remote_download host $loader]
178 remote_send host "file $loader\n"
179 remote_expect host 20 {
180 -re "A program is being debug.*Kill it.*y or n. $" {
181 remote_send host "y\n"
182 exp_continue
184 -re "Load new symbol table.*y or n. $" {
185 remote_send host "y\n"
186 exp_continue
188 -re "Reading symbols from.*done..*$gdb_prompt $" {}
189 -re "$gdb_prompt $" { warning "GDB couldn't find loader" }
190 timeout {
191 warning "(timeout) read symbol file"
192 return -1
196 if {[board_info $dest exists serial]} {
197 set serial [board_info $dest serial]
198 } else {
199 set serial [board_info $dest netport]
201 remote_send host "target [board_info $dest gdb_protocol] $serial\n"
202 remote_expect host 60 {
203 -re "appears to be alive.*$gdb_prompt" { }
204 -re "Remote target.*connected to.*$gdb_prompt" { }
205 -re $gdb_prompt {
206 warning "Error reconnecting to stub."
207 return -1
209 default {
210 warning "Error reconnecting to stub."
211 return -1
215 # We only send the offset if gdb_load_offset is set. Otherwise, we
216 # assume that sending the offset isn't needed.
217 if {[board_info $dest exists gdb_load_offset]} {
218 remote_send host "load $loader [board_info $dest gdb_stub_offset]\n"
219 } else {
220 remote_send host "load $loader\n"
222 verbose "Loading $loader into $GDB" 2
223 global verbose
224 set no_run_command 0
225 # FIXME: The value 1200 below should be a parameter.
226 remote_expect host 1200 {
227 -re "Transfer rate:.*Switching to remote protocol.*Remote debugging" {
228 set no_run_command 1
229 remote_send host "\x03"
230 sleep 2
231 remote_send host "\x03"
232 sleep 1
234 -re "Loading.*Starting.*at.*$gdb_prompt $" {
235 verbose "Loaded $loader into $GDB" 1
236 set no_run_command 1
238 -re "Loading.*$gdb_prompt $" {
239 verbose "Loaded $loader into $GDB" 1
241 -re "$gdb_prompt $" {
242 if $verbose>1 then {
243 warning "GDB couldn't load."
246 timeout {
247 if $verbose>1 then {
248 warning "Timed out trying to load $arg."
253 if { ! $no_run_command } {
254 remote_send host "run\n"
255 remote_expect host 60 {
256 -re "A program is being debug.*Kill it.*y or n. $" {
257 remote_send host "y\n"
258 exp_continue
260 -re "The program being debugged .*y or n. $" {
261 remote_send host "y\n"
262 exp_continue
264 -re "Starting program:.*loader.*$" {
265 verbose "Starting loader succeeded"
267 timeout {
268 warning "(timeout) starting the loader"
269 return -1
271 default {
272 warning "error starting the loader"
275 sleep 2
276 remote_send host "\x03"
277 sleep 1
278 remote_send host "\x03"
279 verbose "Sent ^C^C"
280 remote_expect host 30 {
281 -re "Give up .and stop debugging it.*$" {
282 remote_send host "y\n"
283 exp_continue
285 -re "$gdb_prompt $" {
286 verbose "Running loader succeeded"
288 timeout {
289 warning "(timeout) interrupting the loader"
290 return -1
292 default {
293 warning "error interrupting the loader"
297 remote_send host "quit\n"
298 return [gdb_stub_restart $dest]
300 return 1
304 # Delete all breakpoints and verify that they were deleted. If anything
305 # goes wrong we just exit.
307 proc gdb_stub_delete_breakpoints {} {
308 global gdb_prompt
310 remote_send host "delete breakpoints\n"
311 remote_expect host 10 {
312 -re "Delete all breakpoints.*y or n. $" {
313 remote_send host "y\n"
314 exp_continue
316 -re "$gdb_prompt $" { }
317 timeout { warning "Delete all breakpoints (timeout)" ; return -1}
319 remote_send host "info breakpoints\n"
320 remote_expect host 10 {
321 -re "No breakpoints or watchpoints..*$gdb_prompt $" {}
322 -re "$gdb_prompt $" { warning "breakpoints not deleted" ; return -1}
323 timeout { warning "info breakpoints (timeout)" ; return -1}
325 return 0
328 proc gdb_stub_go_idle { dest } {
329 gdb_stub_delete_breakpoints
332 proc gdb_stub_add_breakpoint { function args } {
333 global gdb_prompt
335 remote_send host "break $function\n"
336 remote_expect host 60 {
337 -re "Breakpoint (\[0-9\]+).*$gdb_prompt $" { return $expect_out(1,string) }
338 -re "Function.*not defined.*$gdb_prompt $" { return "undef" }
339 -re "No symbol table.*$gdb_prompt $" { return "undef" }
340 default {
341 return "undef"
346 proc gdb_stub_start { dest } {
347 global gdb_prompt
349 set exit_brnum [gdb_stub_add_breakpoint _exit]
350 if { $exit_brnum eq "undef" || [board_info $dest exists always_break_exit] } {
351 set exit_brnum [gdb_stub_add_breakpoint exit]
353 set abort_brnum [gdb_stub_add_breakpoint abort]
355 upvar #0 gdb_stub_info I
356 set I($dest,exit_brnum) $exit_brnum
357 set I($dest,abort_brnum) $abort_brnum
359 remote_send host "set \$fp=0\n"
360 remote_expect host 10 {
361 -re $gdb_prompt { }
363 # This is needed for the SparcLite. Whee.
364 if {[board_info $dest exists gdb,start_symbol]} {
365 set start_comm "jump *[board_info $dest gdb,start_symbol]\n"
366 } else {
367 set start_comm "jump *start\n"
369 remote_send host "break copyloop\n"
370 remote_expect host 10 {
371 -re "Breakpoint.*$gdb_prompt $" {
372 set start_comm "continue\n"
374 -re "Function.*not defined.*$gdb_prompt $" { }
375 default { }
377 remote_send host $start_comm
378 remote_expect host 10 {
379 -re "y or n. $" {
380 remote_send host "y\n"
381 exp_continue
383 -re "Breakpoint.*in copyloop.*$gdb_prompt $" {
384 remote_send host "jump relocd\n"
385 exp_continue
387 -re {Continuing at.*[\r\n]} { }
388 default {
389 return { "fail" "" }
392 return { "pass" "" }
395 proc gdb_stub_spawn { dest prog args } {
396 for { set x 0 } { $x < 3 } { incr x } {
397 if { [remote_ld $dest $prog] != 1 } {
398 return [list "fail" "remote_ld failed"]
401 set result [gdb_stub_start $dest]
402 if { [lindex $result 0] ne "pass" } {
403 remote_reboot target
404 } else {
405 return 666; # does anyone use this value?
408 return -1
411 proc gdb_stub_wait { dest timeout } {
412 global gdb_prompt
415 upvar #0 gdb_stub_info I
416 set exit_brnum $I($dest,exit_brnum)
417 set abort_brnum $I($dest,abort_brnum)
419 remote_expect host $timeout {
420 -re "Breakpoint.*exit.*=0.*$gdb_prompt $" {
421 gdb_stub_go_idle $dest
422 return [list 0 ""]
424 -re "Breakpoint.*exit.*=\[1-9\]\[0-9\]*.*$gdb_prompt $" {
425 gdb_stub_go_idle $dest
426 return [list 0 ""]
428 -re "Breakpoint.*exit.*$gdb_prompt $" {
429 gdb_stub_go_idle $dest
430 return [list 0 ""]
432 -re "Breakpoint.*abort.*$gdb_prompt $" {
433 gdb_stub_go_idle $dest
434 return [list 1 ""]
436 -re " EXIT code 0.*$gdb_prompt $" {
437 gdb_stub_go_idle $dest
438 return [list 0 ""]
440 -re " EXIT code \[1-9]\[0-9]*.*$gdb_prompt $" {
441 gdb_stub_go_idle $dest
442 return [list 0 ""]
444 -re " EXIT code 4242.*$gdb_prompt $" {
445 gdb_stub_go_idle $dest
446 return [list 1 ""]
448 -re "Program received.*$gdb_prompt $" {
449 gdb_stub_go_idle $dest
450 return [list 1 ""]
452 -re "Program exited.*$gdb_prompt $" {
453 gdb_stub_go_idle $dest
454 return [list 1 ""]
456 -re "Breakpoint $exit_brnum.*$gdb_prompt $" {
457 gdb_stub_go_idle $dest
458 return [list 0 ""]
460 -re "Breakpoint $abort_brnum.*$gdb_prompt $" {
461 gdb_stub_go_idle $dest
462 return [list 1 ""]
464 default {
465 remote_close $dest
466 remote_reboot $dest
467 return [list -1 ""]
470 return [list -1 ""]
473 proc gdb_stub_load { dest prog args } {
474 global gdb_prompt
475 set argnames { "command-line arguments" "input file" "output file" }
477 for { set x 0 } { $x < [llength $args] } { incr x } {
478 if { [lindex $args $x] ne "" } {
479 return [list "unsupported" "no support for [lindex $argnames $x] on this target"]
483 set result [remote_spawn $dest $prog]
485 if { $result < 0 } {
486 return [list "fail" "remote_spawn failed"]
489 # FIXME: The value 120 should be a parameter.
490 set result [remote_wait $dest 120]
491 set status [lindex $result 0]
492 set output [lindex $result 1]
494 if { $status == 0 } {
495 return [list "pass" $output]
496 } elseif { $status > 0 } {
497 return [list "fail" $output]
498 } else {
499 global gdb_stub_retry
501 if {![info exists gdb_stub_retry]} {
502 set gdb_stub_retry 1
504 set result [eval gdb_stub_load \{$dest\} \{$prog\} $args]
505 unset gdb_stub_retry
506 return $result
507 } else {
508 return [list "fail" $output]
515 # gdb_stub_ld -- load PROG into the board
516 # Returns a 0 if there was an error,
517 # 1 if it loaded successfully.
519 proc gdb_stub_ld { dest prog } {
520 global gdb_prompt
521 global GDB
523 if {![board_info $dest exists gdb_is_running]} {
524 if {![gdb_stub_restart $dest]} {
525 return 0
529 set loadfile [file tail $prog]
530 set loadpath [file dirname $prog]
532 remote_send host "file $prog\n"
533 remote_expect host 30 {
534 -re "A program is being debug.*Kill it.*y or n. $" {
535 remote_send host "y\n"
536 exp_continue
538 -re "Load new symbol table.*y or n. $" {
539 remote_send host "y\n"
540 exp_continue
542 -re "Reading symbols from.*done..*$gdb_prompt $" {}
543 -re "$gdb_prompt $" {
544 # Hmmm...is retrying going to help? I kinda doubt it.
545 warning "GDB couldn't read file"
546 return [gdb_stub_retry_ld $dest $prog]
548 timeout {
549 warning "(timeout) read symbol file"
550 return [gdb_stub_retry_ld $dest $prog]
554 # just in case there are old breakpoints lying around.
555 gdb_stub_delete_breakpoints
557 if {[board_info $dest exists gdb_serial]} {
558 set serial [board_info $dest gdb_serial]
559 } elseif {[board_info $dest exists serial]} {
560 set serial [board_info $dest serial]
561 } else {
562 set serial [board_info $dest netport]
565 remote_send host "target remote $serial\n"
566 remote_expect host 60 {
567 -re "Kill it?.*y or n.*" {
568 remote_send host "y\n"
569 exp_continue
571 -re "$gdb_prompt $" {
572 verbose "Set remote target to $serial" 2
574 timeout {
575 warning "Couldn't set remote target."
576 return 0
580 if {[board_info $dest exists gdb_load_offset]} {
581 set offset "[board_info $dest gdb_load_offset]"
582 } else {
583 set offset ""
585 remote_send host "load $prog $offset\n"
586 verbose "Loading $prog into $GDB" 2
587 global verbose
588 remote_expect host 1200 {
589 -re "Loading.*$gdb_prompt $" {
590 verbose "Loaded $prog into $GDB" 1
592 -re "$gdb_prompt $" {
593 if $verbose>1 then {
594 warning "GDB couldn't load."
597 timeout {
598 if $verbose>1 then {
599 perror "Timed out trying to load $prog."
603 return 1
607 # Retry the ld operation, but only once.
610 proc gdb_stub_retry_ld { dest prog } {
611 global gdb_stub_retry_ld
613 remote_reboot $dest
614 if {[info exists gdb_stub_retry_ld]} {
615 unset gdb_stub_retry_ld
616 return 0
617 } else {
618 set gdb_stub_retry_ld 1
620 gdb_stub_restart $dest
621 set status [gdb_stub_ld $dest $prog]
622 if {[info exists gdb_stub_retry_ld]} {
623 unset gdb_stub_retry_ld
625 return $status
628 proc gdb_stub_close { dest } {
629 global board_info
630 set name [board_info $dest name]
631 if {[info exists board_info($name,gdb_is_running)]} {
632 unset board_info($name,gdb_is_running)
634 return [remote_close host]
637 set_board_info protocol "gdb_stub"