# Copyright 2002 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 2 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, write to the Free Software
# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.  

# This file was written by Jason Molenda (jmolenda@apple.com)

# This file looks at $pc via different mechanisms as we go up and down the
# stack.  If the pc is consistently wrong, this test won't flag any failures,
# but if the pc is reported differently, we can catch that.

if $tracelevel then {
	strace $tracelevel
}

set prms_id 0
set bug_id 0

set testfile "pc-verify"
set srcfile ${testfile}.c
set binfile ${objdir}/${subdir}/${testfile}

global hex

if  { [gdb_compile "${srcdir}/${subdir}/$srcfile" "${binfile}" executable {debug}] != "" } {
     gdb_suppress_entire_file "Testcase compile failed, so all tests in this fil
e will automatically fail."
}

# Start with a fresh gdb

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

if ![runto_main] then { 
  fail "pc-verify tests suppressed"
  return -1
}

#####
##### Gather some information in main() before we call into a subroutine.
#####

gdb_test "next" ".*factorial.*" "next over boring line"
send_gdb "info line\n"
gdb_expect {
  -re ".*Line.*starts at address ($hex) .*ends at ($hex) <main.$decimal>.\[\r\n\]*$gdb_prompt $" {
      set main_info_line_start $expect_out(1,string)
      set main_info_line_end $expect_out(2,string)
      pass "info line in main()."
  }
  -re ".*$gdb_prompt $" {
      fail "info line in main()."
  }
  timeout { fail "info line in main(). (timeout)" }
}

#warning "got pc value of $main_info_line_start\n"

send_gdb "p/x \$pc\n"
gdb_expect {
  -re ".*$decimal = ($hex)\[\r\n\]*$gdb_prompt $" {
      set main_cur_pc $expect_out(1,string)
      pass "Get pc value in main() #1"
  }
  -re ".*$gdb_prompt $" {
      fail "Get pc value in main() #1"
  }
  timeout { fail "Get pc value in main() #1 (timeout)" }
}

send_gdb "p/x \$fp\n"
gdb_expect {
  -re ".*$decimal = ($hex)\[\r\n\]*$gdb_prompt $" {
      set main_cur_fp $expect_out(1,string)
      pass "Get fp value in main() #1"
  }
  -re ".*$gdb_prompt $" {
      fail "Get fp value in main() #1"
  }
  timeout { fail "Get fp value in main() #1 (timeout)" }
}

send_gdb "info fr\n"
gdb_expect {
  -re ".*Stack level 0, frame at ($hex):.*(pc|eip|rip) = ($hex) in main.*$gdb_prompt $" {
    set main_current_fp_from_info_frame $expect_out(1,string)
    set main_current_pc_from_info_frame $expect_out(3,string)
    pass "info frame in main #1."
  }
  -re ".*$gdb_prompt $" {
    fail "info frame in main #1."
  }
  timeout { fail "info frame in main #1. (timeout)" }
}

if {$main_current_pc_from_info_frame != $main_cur_pc} then {
  fail "p/x \$pc returns the same as info frame's \$pc"
} else {
  pass "p/x \$pc returns the same as info frame's \$pc"
}

# on x86, $fp (aka EBP) points two words into the stack frame.
# info frame will report the correct frame address, which starts
# with the saved EIP, then the saved ESP.  EBP points to the
# space below that.  So for the sake of this comparison add the
# offset to EBP so it matches info frame's output.

if [istarget "i\[3-6\]86-apple-darwin*"] {
  set offset 8
} else {
  set offset 0
}
if {$main_current_fp_from_info_frame != $main_cur_fp + $offset} then {
  fail "p/x \$fp returns the same as info frame's \$fp"
} else {
  pass "p/x \$fp returns the same as info frame's \$fp"
}


#####
##### Call into factorial(), see if the numbers make sense down there.
#####

gdb_test "step" ".*factorial.*" "step into factorial"

send_gdb "bt\n"
gdb_expect {
  -re ".*#0 *factorial.*#1 *($hex) in main.*$gdb_prompt $" {
    set main_calling_pc_from_backtrace $expect_out(1,string)
    pass "backtrace in factorial level 1."
  }
  -re ".*$gdb_prompt $" {
    fail "backtrace in factorial level 1."
  }
  timeout { fail "backtrace in factorial level 1. (timeout)" }
}

if { $main_calling_pc_from_backtrace < $main_info_line_start || \
     $main_calling_pc_from_backtrace > $main_info_line_end } then {
   fail "pc from backtrace is within info line range"
} else {
   pass "pc from backtrace is within info line range"
}

send_gdb "info fr\n"
gdb_expect {
  -re "Stack level 0, frame at ($hex).*(pc|eip|rip) = ($hex) in factorial.*saved (pc|eip|rip) ($hex).*$gdb_prompt $" {
    set factorial_info_frame_fp $expect_out(1,string)
    set factorial_info_frame_pc $expect_out(3,string)
    set factorial_info_frame_saved_pc $expect_out(5,string)
    pass "info frame in factorial"
  }
  -re ".*$gdb_prompt $" {
    fail "info frame in factorial"
  }
  timeout { fail info frame in factorial. (timeout)" }
}

if { $factorial_info_frame_saved_pc < $main_info_line_start || \
     $factorial_info_frame_saved_pc > $main_info_line_end } then {
   fail "pc from info frame in factorial is within info line range"
} else {
   pass "pc from info frame in factorial is within info line range"
}

gdb_test "up" ".*in main.*" "change frame back to main"

send_gdb "p/x \$pc\n"
gdb_expect {
  -re ".*$decimal = ($hex)\[\r\n\]*$gdb_prompt $" {
      set new_main_pc $expect_out(1,string)
      pass "Get pc value in main() #2"
  }
  -re ".*$gdb_prompt $" {
      fail "Get pc value in main() #2"
  }
  timeout { fail "Get pc value in main() #2 (timeout)" }
}

if {$new_main_pc == $factorial_info_frame_saved_pc} then {
  pass "\$pc in main is the same as the saved pc from factorial"
} else {
  fail "\$pc in main is the same as the saved pc from factorial"
}

if { $new_main_pc < $main_info_line_start || \
     $new_main_pc > $main_info_line_end } then {
   fail "p/x \$pc at stack level 1 reports pc within correct range"
} else {
   pass "p/x \$pc at stack level 1 reports pc within correct range"
}

gdb_exit
return 0
