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

# Copyright 1998, 1999, 2000, 2001, 2002, 2004, 2007, 2008, 2009
# 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 prms_id 0
set bug_id 0

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_multiple "return 0" "$test" {
		-re "Make .* return now.*y or n. $" {
		    send_gdb "y\n"
		    exp_continue
		}
		-re " caller$c .*$gdb_prompt $" {
		    pass "$test"
		}
            }

            # 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 timeout 30
restore_tests
