# Copyright 2004, 2007-2012 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/>.
#
# This file is part of the gdb testsuite.


# Test handling of nullified instructions for the pa target.

switch -glob -- [istarget] {
    "hppa-*-*" {
	set testfile "pa-nullify"
    }
    "hppa64-*-*" {
	set testfile "pa64-nullify"
    }
    "*" {
        verbose "Skipping hppa nullification tests."
        return
    }
}

set srcfile ${testfile}.s
set binfile ${objdir}/${subdir}/${testfile}
set gcorefile ${objdir}/${subdir}/${testfile}.gcore

if { [gdb_compile "${srcdir}/${subdir}/${srcfile}" "${binfile}" executable {}] != "" } {
    unsupported "Testcase compile failed."
    return -1
}

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

# In the first test, we do a "step" on a function whose last instruction 
# contains a branch-with-nullify.  The instruction in the delay slot belongs
# to the next function.  We verify that when we step off the first function
# that we end up back at the caller and not at the second instruction.

gdb_breakpoint foo
gdb_test "run" "Breakpoint 1, .* in foo.*" "Breakpoint at foo"

set test "stepi till main"
gdb_test_multiple "stepi" "${test}" {
  -re ".*in foo.*$gdb_prompt $" {
    send_gdb "stepi\n"
    exp_continue -continue_timer
  }
  -re ".*in bar.*$gdb_prompt $" {
    fail $test
  }
  -re ".*in main.*$gdb_prompt $" {
    pass $test
  }
}

# In the second test, we verify that we can get a proper backtrace 
# even when we are in a nullified instruction that belongs to the next function.
# We also verify that when stepping over a branch-with-nullify insn that we 
# stay on the same insn for two steps.

proc get_addr_of_sym { sym } {
  set addr 0
  global gdb_prompt
  global hex

  set test "get address of $sym"
  gdb_test_multiple "print $sym" $test {
    -re ".*($hex) <$sym>.*$gdb_prompt $" {
      set addr $expect_out(1,string)
      pass $test
    }
  }

  return $addr
}

if { ! [ runto_main ] } then { gdb_suppress_tests; }

set foo [get_addr_of_sym "foo"]
set bar [get_addr_of_sym "bar"]
set foo_last "(bar - 4)"

gdb_breakpoint "*$foo_last"

gdb_test "continue" "Breakpoint \[0-9\]*,.* in foo.*"
gdb_test "backtrace" "in foo.*in main.*" "Backtrace from last insn in foo"
gdb_test "stepi" "in foo.*" "stepi to nullified instruction stays in foo"
gdb_test "backtrace" "in foo.*in main.*" "Backtrace from nullified insn"
gdb_test "stepi" "in main.*" "stepi to main"

# In the third test, we verify that backtraces from nullified instructions
# work even in coredumps

proc gen_core { test } {
  global gcorefile
  global gdb_prompt
  set gcore_works 0
  set escapedfilename [string_to_regexp $gcorefile]

  # gcore is not yet implemented for HPUX
  setup_xfail hppa*-*-hpux*

  gdb_test_multiple "gcore $gcorefile" "$test: gcore" {
    -re "Saved corefile ${escapedfilename}\[\r\n\]+$gdb_prompt $" {
      pass "$test: gcore"
      set gcore_works 1
    }
    -re "Undefined command.*$gdb_prompt $" {
      fail "$test: gcore (undefined command)"
    }
    -re "Can't create a corefile\[\r\n\]+$gdb_prompt $" {
      fail "$test: gcore (can't create corefile)"
    }
  }

  return $gcore_works
}

proc test_core_bt { test } {
  global gcorefile

  gdb_test "core $gcorefile" "Core was generated by.*" \
    "$test: load core file" "A program is being debugged already.*" "y"

  gdb_test "backtrace" ".*in foo.*in main.*" "$test: backtrace in gcore"
}

set test "core at last insn in foo"
if { ! [ runto_main ] } then { gdb_suppress_tests; }
gdb_breakpoint "*$foo_last"
gdb_test "continue" "Breakpoint \[0-9\]*,.* in foo.*" "$test: continue to breakpoint"
if [gen_core $test] {
  test_core_bt $test
}

set test "core at nullified insn"
if { ! [ runto_main ] } then { gdb_suppress_tests; }
gdb_breakpoint "*$foo_last"
gdb_test "continue" "Breakpoint \[0-9\]*,.* in foo.*" "$test: continue to breakpoint"
gdb_test "stepi" ".*in foo.*" "$test: step to nullified instruction"
if [gen_core $test] {
  test_core_bt $test
}
