# Test `info auxv' and related functionality.

# Copyright (C) 1992-2024 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 based on corefile.exp which was written by Fred
# Fish. (fnf@cygnus.com)

require {is_any_target "*-*-linux*" "*-*-solaris*"}

standard_testfile .c

set corefile ${binfile}.corefile
set gcorefile ${binfile}.gcore

if { [gdb_compile "${srcdir}/${subdir}/${srcfile}" "${binfile}" executable \
		  {debug additional_flags=-DUSE_RLIMIT}] != ""
     && [gdb_compile "${srcdir}/${subdir}/${srcfile}" "${binfile}" executable \
		  {debug}] != "" } {
    untested "failed to compile"
    return -1
}

# Use a fresh directory to confine the native core dumps.
# Make it the working directory for the inferior.
set coredir [standard_output_file coredir.[getpid]]
file mkdir $coredir
set core_works [expr [isnative] && ! [is_remote target]]

# Run GDB on the test program up to where it will dump core.

clean_restart ${binfile}
gdb_test_no_output "set print sevenbit-strings"
gdb_test_no_output "set width 0"

if {$core_works} {
    if {[gdb_test_no_output "set cwd $coredir" \
	     "set cwd to temporary directory for core dumps"]} {
	set core_works 0
    }
}

if {![runto_main]} {
    return 0
}
set print_core_line [gdb_get_line_number "ABORT;"]
gdb_test "tbreak $print_core_line"
gdb_test continue ".*ABORT;.*"

proc fetch_auxv {test} {
    global gdb_prompt

    set auxv_lines {}
    set bad -1
    # Former trailing `\[\r\n\]+' may eat just \r leaving \n in the buffer
    # corrupting the next matches.
    if {[gdb_test_multiple "info auxv" $test {
	-re "info auxv\r\n" {
	    exp_continue
	}
	-ex "The program has no auxiliary information now" {
	    set bad 1
	    exp_continue
	}
	-ex "Auxiliary vector is empty" {
	    set bad 1
	    exp_continue
	}
	-ex "No auxiliary vector found" {
	    set bad 1
	    exp_continue
	}
	-re "^\[0-9\]+\[ \t\]+(AT_\[^ \t\]+)\[^\r\n\]+\r\n" {
	    lappend auxv_lines $expect_out(0,string)
	    exp_continue
	}
	-re "^\[0-9\]+\[ \t\]+\\?\\?\\?\[^\r\n\]+\r\n" {
	    warning "Unrecognized tag value: $expect_out(0,string)"
	    set bad 1
	    lappend auxv_lines $expect_out(0,string)
	    exp_continue
	}
	-re "$gdb_prompt $" {
	    incr bad
	}
	-re "^\[^\r\n\]+\r\n" {
	    if {!$bad} {
		warning "Unrecognized output: $expect_out(0,string)"
		set bad 1
	    }
	    exp_continue
	}
    }] != 0} {
	return {}
    }

    if {$bad} {
	fail $test
	return {}
    }

    pass $test
    return $auxv_lines
}

set live_data [fetch_auxv "info auxv on live process"]

# Now try gcore.
set gcore_works [gdb_gcore_cmd "$gcorefile" "gcore"]

# Let the program continue and die.
gdb_test continue ".*Program received signal.*" "continue until signal"
gdb_test continue ".*Program terminated with signal.*" "continue and terminate"

# Now collect the core dump it left.
set test "generate native core dump"
if {$core_works} {
    # Find the
    set names [glob -nocomplain -directory $coredir *core*]
    if {[llength $names] == 1} {
	set file [file join $coredir [lindex $names 0]]
	remote_exec build "mv $file $corefile"
	pass $test
    } else {
	set core_works 0
	warning "can't generate a core file - core tests suppressed - check ulimit -c"
	unsupported $test
    }
} else {
    unsupported $test
}
remote_exec build "rm -rf $coredir"

# Now we can examine the core files and check that their data matches what
# we saw in the process.  Note that the exact data can vary between runs,
# so it's important that the native core dump file and the gcore-created dump
# both be from the same run of the program as we examined live.

proc do_core_test {works corefile test1 test2} {
    if {! $works} {
	unsupported $test1
	unsupported $test2
    } else {
	gdb_test "core $corefile" "Core was generated by.*" \
	    "load core file for $test1"
	set core_data [fetch_auxv $test1]
	global live_data
	if {$core_data == $live_data} {
	    pass $test2
	} else {
	    fail $test2
	}
    }
}

do_core_test $core_works $corefile \
    "info auxv on native core dump" "matching auxv data from live and core"

do_core_test $gcore_works $gcorefile \
    "info auxv on gcore-created dump" "matching auxv data from live and gcore"
