# Copyright 2010-2013 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/>.


if { ![istarget i?86-*-linux*] && ![istarget x86_64-*-linux* ] } {
    verbose "Skipping system register gcore tests."
    return
}

set testfile "system-gcore"
set srcfile  gcore.c
set binfile  ${objdir}/${subdir}/${testfile}

if  { [gdb_compile "${srcdir}/${subdir}/${srcfile}" "${binfile}" executable {debug}] != "" } {
     untested system-gcore.exp
     return -1
}

# Start with a fresh gdb.

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

# Does this gdb support gcore?
send_gdb "help gcore\n"
gdb_expect {
    -re "Undefined command: .gcore.*$gdb_prompt $" {
	# gcore command not supported -- nothing to test here.
	unsupported "gdb does not support gcore on this target"
	return -1
    }
    -re "Save a core file .*$gdb_prompt $" {
	pass "help gcore"
    }
    -re ".*$gdb_prompt $" {
	fail "help gcore"
    }
    timeout {
	fail "help gcore (timeout)"
    }
}

if { ! [ runto_main ] } then {
    untested system-gcore.exp
    return -1
}

proc capture_command_output { command prefix } {
    global gdb_prompt
    global expect_out

    set output_string ""
    gdb_test_multiple "$command" "capture_command_output for $command" {
	-re "${command}\[\r\n\]+${prefix}(.*)\[\r\n\]+$gdb_prompt $" {
	    set output_string $expect_out(1,string)
	}
    }
    return $output_string
}

gdb_test "break terminal_func" "Breakpoint .* at .*${srcfile}, line .*" \
	"set breakpoint at terminal_func"

gdb_test "continue" "Breakpoint .* terminal_func.*" \
	"continue to terminal_func"

set print_prefix ".\[0123456789\]* = "

set pre_corefile_backtrace [capture_command_output "backtrace" ""]
set pre_corefile_regs [capture_command_output "info registers" ""]
set pre_corefile_allregs [capture_command_output "info all-reg" ""]
set pre_corefile_sysregs [capture_command_output "info reg system" ""]
set pre_corefile_static_array \
	[capture_command_output "print static_array" "$print_prefix"]
set pre_corefile_uninit_array \
	[capture_command_output "print un_initialized_array" "$print_prefix"]
set pre_corefile_heap_string \
	[capture_command_output "print heap_string" "$print_prefix"]
set pre_corefile_local_array \
	[capture_command_output "print array_func::local_array" "$print_prefix"]
set pre_corefile_extern_array \
	[capture_command_output "print extern_array" "$print_prefix"]

set core_supported [gdb_gcore_cmd "${objdir}/${subdir}/gcore.test" \
			"save a corefile"]

if {!$core_supported} {
  return -1
}

# Now restart gdb and load the corefile.
gdb_exit
gdb_start
gdb_reinitialize_dir $srcdir/$subdir
gdb_load ${binfile}

send_gdb "core ${objdir}/${subdir}/gcore.test\n"
gdb_expect {
    -re ".* is not a core dump:.*$gdb_prompt $" {
	fail "re-load generated corefile (bad file format)"
	# No use proceeding from here.
	return;	
    }
    -re ".*: No such file or directory.*$gdb_prompt $" {
	fail "re-load generated corefile (file not found)"
	# No use proceeding from here.
	return;	
    }
    -re ".*Couldn't find .* registers in core file.*$gdb_prompt $" {
	fail "re-load generated corefile (incomplete note section)"
    }
    -re "Core was generated by .*$gdb_prompt $" {
	pass "re-load generated corefile"
    }
    -re ".*$gdb_prompt $" {
	fail "re-load generated corefile"
    }
    timeout {
	fail "re-load generated corefile (timeout)"
    }
}

gdb_test_sequence "where" "where in corefile" {
    "\[\r\n\]+#0 .* terminal_func \\(\\) at "
    "\[\r\n\]+#1 .* array_func \\(\\) at "
    "\[\r\n\]+#2 .* factorial_func \\(value=1\\) at "
    "\[\r\n\]+#3 .* factorial_func \\(value=2\\) at "
    "\[\r\n\]+#4 .* factorial_func \\(value=3\\) at "
    "\[\r\n\]+#5 .* factorial_func \\(value=4\\) at "
    "\[\r\n\]+#6 .* factorial_func \\(value=5\\) at "
    "\[\r\n\]+#7 .* factorial_func \\(value=6\\) at "
    "\[\r\n\]+#8 .* main \\(.*\\) at "
}

set post_corefile_regs [capture_command_output "info registers" ""]
if ![string compare $pre_corefile_regs $post_corefile_regs] then {
    pass "corefile restored general registers"
} else {
    fail "corefile restored general registers"
}

set post_corefile_allregs [capture_command_output "info all-reg" ""]
if ![string compare $pre_corefile_allregs $post_corefile_allregs] then {
    pass "corefile restored all registers"
} else {
    fail "corefile restored all registers"
}

set post_corefile_sysregs [capture_command_output "info reg system" ""]
if ![string compare $pre_corefile_sysregs $post_corefile_sysregs] then {
    pass "corefile restored system registers"
} else {
    fail "corefile restored system registers"
}

set post_corefile_extern_array \
	[capture_command_output "print extern_array" "$print_prefix"]
if ![string compare $pre_corefile_extern_array $post_corefile_extern_array]  {
    pass "corefile restored extern array"
} else {
    fail "corefile restored extern array"
}

set post_corefile_static_array \
	[capture_command_output "print static_array" "$print_prefix"]
if ![string compare $pre_corefile_static_array $post_corefile_static_array]  {
    pass "corefile restored static array"
} else {
    fail "corefile restored static array"
}

set post_corefile_uninit_array \
	[capture_command_output "print un_initialized_array" "$print_prefix"]
if ![string compare $pre_corefile_uninit_array $post_corefile_uninit_array]  {
    pass "corefile restored un-initialized array"
} else {
    fail "corefile restored un-initialized array"
}

set post_corefile_heap_string \
	[capture_command_output "print heap_string" "$print_prefix"]
if ![string compare $pre_corefile_heap_string $post_corefile_heap_string]  {
    pass "corefile restored heap array"
} else {
    fail "corefile restored heap array"
}

set post_corefile_local_array \
	[capture_command_output "print array_func::local_array" "$print_prefix"]
if ![string compare $pre_corefile_local_array $post_corefile_local_array]  {
    pass "corefile restored stack array"
} else {
    fail "corefile restored stack array"
}

set post_corefile_backtrace [capture_command_output "backtrace" ""]
if ![string compare $pre_corefile_backtrace $post_corefile_backtrace]  {
    pass "corefile restored backtrace"
} else {
    fail "corefile restored backtrace"
}
