# Test Framework Driver for GDB driving a ROM monitor (via monitor.c).
#   Copyright 1995-2021 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 <http://www.gnu.org/licenses/>.

#
# gdb_target_cmd
# Send gdb the "target" command
#
proc gdb_target_cmd { targetname serialport } {
    global gdb_prompt

    for {set i 1} {$i <= 3} {incr i} {
	send_gdb "target $targetname $serialport\n"
	gdb_expect 60 {
	    -re "A program is being debugged already.*ill it.*y or n. $" {
		send_gdb "y\n"
		exp_continue
	    }
	    -re "Couldn't establish connection to remote.*$gdb_prompt" {
		verbose "Connection failed"
	    }
	    -re "Remote MIPS debugging.*$gdb_prompt" {
		verbose "Set target to $targetname"
		return 0
	    }
	    -re "Remote debugging using .*$serialport.*$gdb_prompt" {
		verbose "Set target to $targetname"
		return 0
	    }
	    -re "Remote target $targetname connected to.*$gdb_prompt" {
		verbose "Set target to $targetname"
		return 0
	    }
	    -re "Connected to.*$gdb_prompt" { 
		verbose "Set target to $targetname"
		return 0
	    }
	    -re "Ending remote.*$gdb_prompt" { }
	    -re "Connection refused.*$gdb_prompt" {
		verbose "Connection refused by remote target.  Pausing, and trying again."
		sleep 30
		continue
	    }
	    -re "Timeout reading from remote system.*$gdb_prompt" {
		verbose "Got timeout error from gdb."
	    }
	    timeout {
		send_gdb ""
		break
	    }
	}
    }
    return 1
}



#
# gdb_target_monitor
# Set gdb to target the monitor
#
proc gdb_target_monitor { exec_file } {
    global gdb_prompt
    global exit_status
    global timeout

    if [target_info exists gdb_protocol] {
	set targetname "[target_info gdb_protocol]"
    } else {
	perror "No protocol specified for [target_info name]."
	return -1
    }
    if [target_info exists baud] {
	gdb_test "set serial baud [target_info baud]" "" ""
    }
    if [target_info exists binarydownload] {
	gdb_test "set remotebinarydownload [target_info binarydownload]" "" ""
    }
    if { [ target_info exists disable_x_packet ] } {
	gdb_test "set remote X-packet disable" ""
    }
    if { [ target_info exists disable_z_packet ] } {
	gdb_test "set remote Z-packet disable" ""
    }
    if [target_info exists gdb_serial] {
       set serialport "[target_info gdb_serial]"
    } elseif [target_info exists netport] {
	set serialport "[target_info netport]"
    } else {
	set serialport "[target_info serial]"
    }

    for {set j 1} {$j <= 2} {incr j} {
	if [gdb_file_cmd $exec_file] { return -1 }

	if ![gdb_target_cmd $targetname $serialport] { return 0 }

	gdb_target_exec

	if { $j == 1 && ![reboot_target] } {
	    break
	}
    }

    perror "Couldn't set target for $targetname, port is $serialport."
    return -1
}

proc gdb_target_exec { } {
    gdb_test "target exec" "No executable file now." "" ".*Kill it.*y or n.*" "y"
    
}
#
# 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 timeout
    global last_gdb_file

    if { $arg == "" } {
	if [info exists last_gdb_file] {
	    set arg $last_gdb_file
	} else {
	    send_gdb "info files\n"
	    gdb_expect 30 {
		-re "Symbols from \"(\[^\"\]+)\"" {
		    set arg $expect_out(1,string)
		    exp_continue
		}
		-re "Local exec file:\[\r\n\]+\[ \t\]*`(\[^'\]+)'," {
		    set arg $expect_out(1,string)
		    exp_continue
		}
		-re "$gdb_prompt $" { }
	    }
	}
    }

    set last_gdb_file $arg

    for { set j 1 } { $j <= 2 } {incr j } {
	if [target_info exists gdb,use_standard_load] {
	    gdb_target_exec
	    if ![target_info exists gdb,no_push_conn] {
		remote_push_conn host
	    }
	    set state [remote_ld target $arg]
	    if ![target_info exists gdb,no_push_conn] {
		remote_close target
		remote_pop_conn host
	    }
	    if { $state == "pass" } {
		if [gdb_target_monitor $arg] { return -1 }
		gdb_test "list -q main" ".*" ""
		verbose "Loaded $arg into $GDB\n"
		return 0
	    }
	} else {

	    if [gdb_target_monitor $arg] { return -1 }

	    if [is_remote host] {
		# FIXME: Multiple downloads. bleah.
		set farg [remote_download host $arg]
	    } else {
		set farg $arg
	    }

	    if { $arg != "" && [target_info exists gdb_sect_offset] } {
		set textoff [target_info gdb_sect_offset]
		send_gdb "sect .text $textoff\n"
		gdb_expect 30 {
		    -re "(0x\[0-9a-z]+) - 0x\[0-9a-z\]+ is \\.data" {
			set dataoff $expect_out(1,string)
			exp_continue
		    }
		    -re "(0x\[0-9a-z\]+) - 0x\[0-9a-z\]+ is \\.bss" {
			set bssoff $expect_out(1,string)
			exp_continue
		    }
		    -re "$gdb_prompt" { }
		}
		set dataoff [format 0x%x [expr $dataoff + $textoff]]
		set bssoff [format 0x%x [expr $bssoff + $textoff]]
		send_gdb "sect .data $dataoff\n"
		gdb_expect 30 {
		    -re "$gdb_prompt" { }
		}
		send_gdb "sect .bss $bssoff\n"
		gdb_expect 30 {
		    -re "$gdb_prompt" { }
		}
	    }

	    verbose "Loading $farg"
	    if [target_info exists gdb_load_offset] {
		set command "load $farg [target_info gdb_load_offset]\n"
	    } else {
		set command "load $farg\n"
	    }
	    if [target_info exists gdb_load_timeout] {
		set loadtimeout [target_info gdb_load_timeout]
	    } else {
		set loadtimeout 1600
	    }

	    if [is_remote target] {
		set oldremotetimeout [get_remotetimeout]
		set_remotetimeout $loadtimeout
	    }

	    set load_ok 0
	    send_gdb $command
	    gdb_expect $loadtimeout {
		-re "\[Ff\]ailed.*$gdb_prompt $" {
		    verbose "load failed"
		}
		-re "Timeout reading from remote.*$gdb_prompt" {
		}
		-re "$gdb_prompt $" {
		    verbose "Loaded $farg into $GDB\n"
		    set load_ok 1
		}
		timeout {
		    if { $verbose > 1 } {
			perror "Timed out trying to load $farg."
		    }
		}
	    }

	    if [is_remote target] {
		set_remotetimeout $oldremotetimeout
	    }

	    if { $load_ok == 1 } {
		return 0
	    }
	}

	# Make sure we don't have an open connection to the target.
	gdb_target_exec

	if { $j == 1 } {
	    if { ![reboot_target] } {
		break
	    }
	}
    }
    perror "Couldn't load file into GDB."
    return -1
}
