set test "./usymbols"
set testpath "$srcdir/$subdir"
set testsrc  "$testpath/usymbols.c"
set testsrclib  "$testpath/usymbols_lib.c"
set testlibdir "[pwd]"
set testflags "additional_flags=-g additional_flags=-O"

# Only run on make installcheck and utrace present.
if {! [installtest_p]} { untested "$test"; return }
if {! [utrace_p]} { untested "$test"; return }
if {! [uprobes_p]} { untested "$test"; return }

# We need the execname() trick to work around (the workaround of)
# PR6964 otherwise we get also the rt_sigactions of stapio. Get
# the handler (comes from the executable or the library).
#
# We have to use @cast() on act_uaddr since syscall wrappers on
# ppc64/s390x systems turn the 'struct sigaction' into a 'long int'.
set testscript {
    probe syscall.rt_sigaction {
      if (pid() == target() && execname() == "%s") {
	// Note user address.
	handler = user_long(&@cast(act_uaddr, "struct sigaction", "kernel")->sa_handler);
	try {
		printf("handler: %%s (%%s)\n", usymname(handler), umodname(handler));
	} catch {
		printf("handler: %%s (%%s)\n", usymname(handler), "<unknown>");
	}
      }
    }
    probe syscall.rt_sigaction32 ? {
      if (pid() == target() && execname() == "%s") {
	// Note user address.
	handler = user_long(@defined(@cast(0, "compat_sigaction", "kernel")->sa_handler)
			    ? &@cast(act_uaddr, "compat_sigaction", "kernel")->sa_handler
			    : &@cast(act_uaddr, "sigaction32", "kernel")->sa_handler);
	try {
		printf("handler: %%s (%%s)\n", usymname(handler), umodname(handler));
	} catch {
		printf("handler: %%s (%%s)\n", usymname(handler), "<unknown>");
	}
      }
    }
}

for {set i 0} {$i < [all_compile_flags]} {incr i} {
    set extra_flag [all_compile_flag $i]
    set extra_name [all_compile_flag_name $i]

    verbose "testing usymbols $extra_name"

    set testexename "usymbols"
    set testlibname "usymbols"
    set maintestflags "$testflags additional_flags=-L$testlibdir additional_flags=-Wl,-rpath,$testlibdir"
    set testlibflags "testflags additional_flags=-fPIC additional_flags=-shared"
    set testexename "${testexename}-${extra_name}"
    set testlibname "${testlibname}-${extra_name}"
    set maintestflags "$maintestflags additional_flags=-l$testlibname $extra_flag"
    set testlibflags "$testlibflags $extra_flag"

    # Compile our test program and library.
    set testso "$testlibdir/lib${testlibname}.so"
    set res [target_compile $testsrclib $testso executable $testlibflags]
    if { $res != "" } {
	verbose "target_compile for $testso failed: $res" 2
	fail "unable to compile usymbols_lib.c $extra_name"
	continue
    }
    set testexe  "[pwd]/${testexename}"
    set res [target_compile $testsrc $testexe executable $maintestflags]
    if { $res != "" } {
	verbose "target_compile failed: $res" 2
	fail "unable to compile usymbols.c $extra_name"
	continue
    }

    # Originally the output string used 'pwd' to get the full path to
    # the testexename/testlibname.  However, if the test directory has
    # a long path, the start of the path gets truncated in systemtap
    # output, so the test was failing.  Now we just check for a path
    # ending in the correct filename.
    set output "handler: main_handler (.+/${testexename})
handler: lib_handler (.+/lib${testlibname}.so)"

    # Used to need to run stap with both the exe and the libraries
    # used as -d args.  Now use --ldd to pick up both exe and the
    # library we just linked in.
    set script [format $testscript $testexename $testexename]
    send_log "script: $script\n"
    set cmd [concat stap -w -d $testexe --ldd -c $testexe -e {$script}]
    send_log "cmd: $cmd\n"
    catch {eval exec $cmd} res
    send_log "cmd output: $res\n"

    set n 0
    set m [llength [split $output "\n"]]
    set expected [split $output "\n"]
    set nfails 0
    foreach line [split $res "\n"] {
	if {![regexp [lindex $expected $n] $line]} {
	    fail "usymbols $extra_name"
	    send_log "line [expr $n + 1]: expected \"[lindex $expected $n]\", "
	    send_log "Got \"$line\"\n"
	    incr nfails
        }
        incr n
    }
    if { $n != $m } {
	fail "usymbols $extra_name"
	send_log "Got \"$n\" lines, expected \"$m\" lines\n"
    } elseif { $nfails == 0 } {
	pass "usymbols $extra_name"
	exec rm -f $testexe $testso
    }
}
