set test "plt"

proc cleanup_handler { verbose } {
    if { $verbose == 0 } {
	catch {exec rm -f libplt1.so libplt2.so plt.x }
    }
}

proc error_handler { res test message } {
    global verbose
    if { $res == 0 } {
	verbose "$test $message" 2
	fail "$test $message"
	return 1
    } elseif { $message != "" } {
	pass $test
	return 0
    } else {
	return 0
    }
}

if {![installtest_p]} { untested $test; return }
if {![plt_probes_p]} { untested $test; return }

set stap_path $env(SYSTEMTAP_PATH)/stap

set exepath "./plt.x"

set F additional_flags
set flags "$F=-I. $F=-shared $F=-fPIC $F=-DLIBPLT1 $F=-g $F=-Wno-deprecated-declarations $F=-Wno-format"
set res [target_compile $srcdir/$subdir/plt.c ./libplt1.so executable $flags ]
if { [error_handler [expr {$res == ""}] "target_compile libplt1.so" ""] } { return }

set flags "$F=-I. $F=-shared $F=-fPIC $F=-DLIBPLT2 $F=-g $F=-Wno-deprecated-declarations $F=-Wno-format"
set res [target_compile $srcdir/$subdir/plt.c ./libplt2.so executable $flags ]
if { [error_handler [expr {$res == ""}] "target_compile libplt2.so" ""] } { return }

set flags "$F=-Wl,-rpath,[pwd] $F=-L[pwd] $F=-lplt1 $F=-lplt2 $F=-DONLY_MAIN $F=-g $F=-Wno-deprecated-declarations $F=-Wno-format"
set res [target_compile $srcdir/$subdir/plt.c $exepath executable $flags ]
if { [error_handler [expr {$res == ""}] "target_compile plt.x" ""] } { return }

# test process.plt

set ok 0
spawn $stap_path -c $exepath -e "global calls probe process(\"./plt.x\").plt {calls\[\$\$name\] += 1} probe process(\"./libplt1.so\").plt {calls\[\$\$name\] += 1} probe process(\"./libplt2.so\").plt {calls\[\$\$name\] += 1} probe end {foreach (x in calls) printf (\"%s %d\\n\", x, calls\[x\])}"

expect {
    -timeout 180
    -re {__libc_start_main 1\r\n} { incr ok; exp_continue }
    -re {xmalloc 2\r\n} { incr ok; exp_continue }
    -re {savestring 1\r\n} { incr ok; exp_continue }
    -re {memcpy 1\r\n} { incr ok; exp_continue }
    -re {open2 1\r\n} { incr ok; exp_continue }
    -re {stpcpy 4\r\n} { incr ok; exp_continue }
    -re {open 2\r\n} { incr ok; exp_continue }
    -re {open3 1\r\n} { incr ok; exp_continue }
    -re {basename2 1\r\n} { incr ok; exp_continue }
    -re {__xpg_basename 1\r\n} { incr ok; exp_continue }
    -re {critters 1\r\n} { incr ok; exp_continue }
    -re {print_critter 32\r\n} { incr ok; exp_continue }
    -re {printf 36\r\n} { incr ok; exp_continue }
    -re {putchar 2\r\n} { incr ok; exp_continue }
    -re {qsort 1\r\n} { incr ok; exp_continue }
    -re {strcmp 51\r\n} { incr ok; exp_continue }
    -re {find_critter 3\r\n} { incr ok; exp_continue }
    -re {bsearch 3\r\n} { incr ok; exp_continue }
    -re {widgets 1\r\n} { incr ok; exp_continue }
    -re {register_printf_function 1\r\n} { incr ok; exp_continue }
    -re {asprintf 3\r\n} { incr ok; exp_continue }
    -re {fprintf 3\r\n} { incr ok; exp_continue }
    -re {datetime 1\r\n} { incr ok; exp_continue }
    -re {time 1\r\n} { incr ok; exp_continue }
    -re {localtime 1\r\n} { incr ok; exp_continue }
    -re {asctime 1\r\n} { incr ok; exp_continue }
    -re {fputs 3\r\n} { incr ok; exp_continue }
    -re {strftime 2\r\n} { incr ok; exp_continue }
    timeout { fail "$test (timeout)" }
    eof {  }
}

catch { close}; catch { wait}

error_handler [expr {$ok == 28}] "plt" "($ok != 28)"

# test process.library.plt

set ok 0
spawn $stap_path -c $exepath -e "global calls probe process(\"./plt.x\").plt {calls\[\$\$name\] += 1} probe process(\"./plt.x\").library(\"*\").plt {calls\[\$\$name\] += 1} probe end {foreach (x in calls) printf (\"%s %d\\n\", x, calls\[x\])}"

expect {
    -timeout 180
    -re {__libc_start_main 1\r\n} { incr ok; exp_continue }
    -re {xmalloc 2\r\n} { incr ok; exp_continue }
    -re {savestring 1\r\n} { incr ok; exp_continue }
    -re {memcpy 1\r\n} { incr ok; exp_continue }
    -re {open2 1\r\n} { incr ok; exp_continue }
    -re {stpcpy 4\r\n} { incr ok; exp_continue }
    -re {open 2\r\n} { incr ok; exp_continue }
    -re {open3 1\r\n} { incr ok; exp_continue }
    -re {basename2 1\r\n} { incr ok; exp_continue }
    -re {__xpg_basename 1\r\n} { incr ok; exp_continue }
    -re {critters 1\r\n} { incr ok; exp_continue }
    -re {print_critter 32\r\n} { incr ok; exp_continue }
    -re {printf 36\r\n} { incr ok; exp_continue }
    -re {putchar 2\r\n} { incr ok; exp_continue }
    -re {qsort 1\r\n} { incr ok; exp_continue }
    -re {strcmp 51\r\n} { incr ok; exp_continue }
    -re {find_critter 3\r\n} { incr ok; exp_continue }
    -re {bsearch 3\r\n} { incr ok; exp_continue }
    -re {widgets 1\r\n} { incr ok; exp_continue }
    -re {register_printf_function 1\r\n} { incr ok; exp_continue }
    -re {asprintf 3\r\n} { incr ok; exp_continue }
    -re {fprintf 3\r\n} { incr ok; exp_continue }
    -re {datetime 1\r\n} { incr ok; exp_continue }
    -re {time 1\r\n} { incr ok; exp_continue }
    -re {localtime 1\r\n} { incr ok; exp_continue }
    -re {asctime 1\r\n} { incr ok; exp_continue }
    -re {fputs 3\r\n} { incr ok; exp_continue }
    -re {strftime 2\r\n} { incr ok; exp_continue }
    timeout { fail "$test (timeout)" }
    eof {  }
}

catch { close}; catch { wait}

error_handler [expr {$ok == 28}] "plt library" "($ok != 28)"

# test process.plt("glob")

set ok 0
spawn $stap_path -c $exepath -e "global calls probe process(\"./libplt2.so\").plt(\"strcmp\") {calls\[\$\$name\] += 1} probe end {foreach (x in calls) printf (\"%s %d\\n\", x, calls\[x\])}"

expect {
    -timeout 180
    -re {strcmp 51\r\n} { incr ok; exp_continue }
    -re {printf 36\r\n} { incr ok; exp_continue }
    timeout { fail "$test (timeout)" }
    eof {  }
}

catch { close}; catch { wait}

error_handler [expr {$ok == 1}] "plt glob" "($ok != 1)"

cleanup_handler $verbose
