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

load_lib "trace-support.exp"

standard_testfile
set executable ""

set ws "\[\r\n\t \]+"
set cr "\[\r\n\]+"

# Only x86 and x86_64 targets are supported for now.

if { ![istarget "x86_64-*"] && ![istarget "i?86-*"] } {
    continue
}

proc compile_stap_bin {exec_name {arg ""}} {
    global srcfile
    global srcdir
    global subdir
    global executable

    if { $arg != "" } {
	set arg "additional_flags=$arg"
    }

    set executable ${exec_name}

    if { [gdb_compile "$srcdir/$subdir/$srcfile" \
	      [standard_output_file $exec_name] \
	      executable [concat $arg debug nowarnings]] != "" } {
	untested "Could not compile ${srcfile}"
	return 0
    }

    return 1
}

proc prepare_for_trace_test {} {
    global executable

    clean_restart $executable

    if { ![runto_main] } {
	perror "Could not run to `main'."
	continue
    }

    gdb_breakpoint [gdb_get_line_number "end-here"]
}

proc run_trace_experiment { test_probe msg } {
    global gdb_prompt

    set test "collect $msg: start trace experiment"
    gdb_test_multiple "tstart" "$test" {
	-re "^tstart\r\n$gdb_prompt $" {
	    pass "$test"
	}
    }

    gdb_test "continue" \
	    "Continuing.*Breakpoint \[0-9\]+.*" \
	    "collect $msg: run trace experiment"
    gdb_test "tstop" \
	    "\[\r\n\]+" \
	    "collect $msg: stop trace experiment"
    gdb_test "tfind start" \
	    "#0 .*" \
	    "collect $msg: tfind test frame"
}

proc gdb_collect_probe_arg { msg probe val_arg0 } {
    global gdb_prompt
    global cr

    prepare_for_trace_test

    gdb_test "trace $probe" \
	    "Tracepoint \[0-9\]+ at .*" \
	    "collect $msg: set tracepoint"
    gdb_trace_setactions "collect $msg: define actions" \
	    "" \
	    "collect \$_probe_arg0" "^$"

    # Begin the test.
    run_trace_experiment $msg $probe

    gdb_test "print \$_probe_arg0" \
	    "\\$\[0-9\]+ = $val_arg0$cr" \
	    "collect $msg: collected probe arg0"
}

if {![compile_stap_bin "stap-probe-nosem"]} {
    # An appropriate failure message has already been output
    return -1
}

clean_restart $executable
if { ![runto_main] } {
    perror "Could not run to `main'."
    continue
}

if { ![gdb_target_supports_trace] } {
    # Test cannot run on this target.
    return 1;
}

gdb_collect_probe_arg "probe args without semaphore" "-probe-stap user" "23"
gdb_exit

if {![compile_stap_bin "stap-probe-sem" "-DUSE_PROBES"]} {
    # An appropriate failure message has already been output
    return -1
}

gdb_collect_probe_arg "probe args with semaphore" "-probe-stap two" "46"

# Finished!
gdb_test "tfind none" ".*" ""
