# Test Framework Driver for GDB driving a ROM monitor (via monitor.c).
#   Copyright 1995-2018 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/>.

load_lib gdb.exp
# puts "***** DID USE MONITOR ******"

#
# 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 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
}
