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

load_lib "trace-support.exp";

set testfile "ftrace"
set executable $testfile
set srcfile $testfile.c
set binfile $objdir/$subdir/$testfile
set expfile $testfile.exp

# Some targets have leading underscores on assembly symbols.
set additional_flags [gdb_target_symbol_prefix_flags]

if [prepare_for_testing $expfile $executable $srcfile \
	[list debug $additional_flags]] {
    untested "failed to prepare for trace tests"
    return -1
}

if ![runto_main] {
    fail "Can't run to main to check for trace support"
    return -1
}

if ![gdb_target_supports_trace] {
    unsupported "target does not support trace"
    return -1
}

set libipa $objdir/../gdbserver/libinproctrace.so
gdb_load_shlibs $libipa

# Can't use prepare_for_testing, because that splits compiling into
# building objects and then linking, and we'd fail with "linker input
# file unused because linking not done" when building the object.

if { [gdb_compile "$srcdir/$subdir/$srcfile" $binfile \
	  executable [list debug $additional_flags shlib=$libipa] ] != "" } {
    untested "failed to compile ftrace tests"
    return -1
}
clean_restart ${executable}

if ![runto_main] {
    fail "Can't run to main for ftrace tests"
    return 0
}

proc run_trace_experiment {} {

    gdb_test "continue" \
	".*Breakpoint \[0-9\]+, begin .*" \
	"advance to trace begin"

    gdb_test_no_output "tstart" "start trace experiment"

    gdb_test "continue" \
	".*Breakpoint \[0-9\]+, end .*" \
	"advance through tracing"

    gdb_test "tstatus" ".*Trace .*" "check on trace status"

    gdb_test "tstop" "" ""
}

proc test_fast_tracepoints {} {
    global gdb_prompt

    set fourgood 0

    gdb_test "break begin" ".*" ""

    gdb_test "break end" ".*" ""

    gdb_test "print gdb_agent_gdb_trampoline_buffer_error" ".*" ""

    if { [is_x86_like_target] } {

	gdb_test "ftrace set_point" "Fast tracepoint .*" \
	    "fast tracepoint at a long insn"

	gdb_trace_setactions "collect at set_point: define actions" \
	    "" \
	    "collect globvar, anarg" "^$"

	# Make a test of shorter fast tracepoints, 32-bit x86 only

	if { [istarget "i?86-*-*"] } {

	    # A Linux target needs to be able to allocate trampolines in the
	    # 16-bit range, check mmap_min_addr so we can warn testers.
	    if { [istarget "i?86-*-linux*"] } {

		set minaddr [exec sh -c "cat /proc/sys/vm/mmap_min_addr"]

		if { [expr $minaddr > 64512] } {
		    warning "mmap_min_addr > 64512, fast tracepoint will fail"
		    warning "do \"sudo sysctl -w vm.mmap_min_addr=32768\" to adjust"
		}
	    }

	    gdb_test_multiple "ftrace four_byter" "set 4-byte fast tracepoint" {
		-re "May not have a fast tracepoint at .*\r\n$gdb_prompt $" {
		    pass "4-byte fast tracepoint could not be set"
		}
		-re "Fast tracepoint .*\r\n$gdb_prompt $" {
		    pass "4-byte fast tracepoint is set"
		    set fourgood 1
		}
	    }

	    if { $fourgood } {

		gdb_trace_setactions "collect at four_byter: define actions" \
		"" \
		"collect globvar, anarg" "^$"
	    }
	}

	run_trace_experiment

	gdb_test "tfind pc *set_point" "Found trace frame .*" \
	    "tfind set_point frame, first time"

	gdb_test "print globvar" " = 1"

	gdb_test "tfind pc *set_point" "Found trace frame .*" \
	    "tfind set_point frame, second time"

	gdb_test "print anarg" " = 200"

	gdb_test "tfind start" "Found trace frame .*" \
	    "reset tfinding"

	if { $fourgood } {

	    gdb_test "tfind pc *four_byter" "Found trace frame .*" \
		"tfind four_byter frame, first time"

	    gdb_test "print anarg" " = 101" \
		"look at collected local, first time"

	    gdb_test "tfind pc *four_byter" "Found trace frame .*" \
		"tfind four_byter frame, second time"

	    gdb_test "print anarg" " = 201" \
		"look at collected local, second time"

	}
    }
}

gdb_reinitialize_dir $srcdir/$subdir

if { [gdb_test "info sharedlibrary" ".*libinproctrace\.so.*" "IPA loaded"] != 0 } {
    untested "Could not find IPA lib loaded"
    return 1
}

test_fast_tracepoints
