# This testcase is part of GDB, the GNU debugger.

# Copyright 1998, 1999, 2000, 2001, 2002, 2004, 2007, 2008, 2009, 2010, 2011
# 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/>.

# Test GDB's ability to restore saved registers from stack frames
# when using the `return' command.
#
# This file was written by Jim Blandy <jimb@cygnus.com>, with
# fragments borrowed from return.exp.

if $tracelevel then {
    strace $tracelevel
}


set testfile "restore"
set srcfile ${testfile}.c
set binfile ${objdir}/${subdir}/${testfile}
if  { [gdb_compile "${srcdir}/${subdir}/${srcfile}" "${binfile}" executable {debug}] != "" } {
    untested restore.exp
    return -1
}

proc restore_tests { } {
    global gdb_prompt

    if { ! [ runto driver ] } {
	return 0
    }

    set limit 5

    # For each caller function,
    #   call each of the callee functions,
    #   force a return from the callee, and
    #   make sure that the local variables still have the right values.

    for {set c 1} {$c <= $limit} {incr c} {

        # Set a breakpoint at the next caller function.
        gdb_test "tbreak caller$c" "Temporary breakpoint.*\[0-9\]*\\." \
	    "tbreak caller$c"

	# Continue to the next caller function.
	gdb_test "continue" " caller$c prologue .*" "run to caller$c"

	# Do each callee function.
        for {set e 1} {$e <= $limit} {incr e} {

            gdb_test "tbreak callee$e" "Temporary breakpoint.*\[0-9\]*\\." \
		"caller$c calls callee$e; tbreak callee"
            
  	    gdb_test "continue" " callee$e prologue .*/" \
		"caller$c calls callee$e; continue to callee"
	    
            # Do a forced return from the callee.
	    set test "caller$c calls callee$e; return callee now"

	    gdb_test "return 0" \
		" caller$c .*" \
		"$test" \
		"Make .* return now.*y or n. $" \
		"y"

            # Check that the values of the local variables are what
	    # they should be.
            for {set var 1} {$var <= $c} {incr var} {
                set expected [expr 0x7eeb + $var]
	        gdb_test "print l$var" " = $expected" \
		    "caller$c calls callee$e; return restored l$var to $expected"
            }
        }
    }

    if ![gdb_skip_stdio_test "run to completion"] {
	send_gdb "continue\n"

	gdb_expect {
	    -re "exiting" {
		pass "run to completion"
	    }
	    timeout { 
		fail "(timeout) run to completion"
	    }
	}
    } else {
	gdb_test "continue" ".*" ""
    }
}



# Start with a fresh gdb.

gdb_exit
gdb_start
gdb_reinitialize_dir $srcdir/$subdir
gdb_load ${binfile}

set prev_timeout $timeout
set timeout 30
restore_tests
set timeout $prev_timeout
