label, _bar;
0xb7, $$, -, -, 50; /* mov $$, 50 */
label, _done;
- /* 0xbf, $$, $$, -, -; /* dummy op */
%}
function bar:long (x:long) {
}
probe begin {
- printf("foo(1)=%d should be %d\n", foo(1), bar(1))
- printf("foo(8)=%d should be %d\n", foo(8), bar(8))
- printf("foo(15)=%d should be %d\n", foo(15), bar(15))
- exit()
+ printf("U foo(1)=%d should be %d\n", foo(1), bar(1))
+ printf("U foo(8)=%d should be %d\n", foo(8), bar(8))
+ printf("U foo(15)=%d should be %d\n", foo(15), bar(15))
}
+probe kernel.function("vfs_read") {
+ printf("K foo(1)=%d should be %d\n", foo(1), bar(1))
+ printf("K foo(8)=%d should be %d\n", foo(8), bar(8))
+ printf("K foo(15)=%d should be %d\n", foo(15), bar(15))
+ exit()
+}
--- /dev/null
+function foo:long (x:long) %{ /* bpf */
+ call, -, printf, "x = 0x%p causing exit\n", $x, $x, $x, $x;
+ 0xb7, $$, -, -, 0x0; /* mov $$, 0 */
+%}
+
+probe begin {
+ printf("U x = 10 should print:\n"); foo(10)
+ exit()
+}
printf("foo(15)=%d should be %d\n", foo(15), bar(15))
exit()
}
-
label, _done;
%}
+function bar:long (x:long) {
+ if (x < 10) return 17 else return 16
+}
+
probe begin {
- printf("foo(1)=%d\n", foo(1))
- printf("foo(15)=%d\n", foo(15))
- exit()
+ printf("U foo(1)=%d should be %d\n", foo(1), bar(1))
+ printf("U foo(15)=%d should be %d\n", foo(15), bar(15))
}
+probe kernel.function("vfs_read") {
+ printf("K foo(1)=%d should be %d\n", foo(1), bar(1))
+ printf("K foo(15)=%d should be %d\n", foo(15), bar(15))
+ exit()
+}
--- /dev/null
+function foo:long (x:long) %{ /* bpf */
+ call, -, printf, "x = %p \n", $x;
+ 0xb7, $$, -, -, 0x0; /* mov $$, 0 */
+%}
+
+probe begin {
+ printf("U 'x = 0xa' should print:\n"); foo(10)
+ exit()
+}
--- /dev/null
+function foo:long (x:long) %{ /* bpf */ /* calls:exit */
+ 0xb5, $x, -, _skip, 20; /* jle n, 20, _skip */
+ call, -, printf, "x = %d causing exit\n", $x; /* like error() */
+ call, -, exit;
+ label, _skip;
+ call, -, printf, "x = %d not causing exit\n", $x;
+ 0xb7, $$, -, -, 0x0; /* mov $$, 0 */
+%}
+
+probe begin {
+ printf("U 'x = 10' should print:\n"); foo(10)
+}
+
+probe kernel.function("vfs_read") {
+ printf("K 'x = 25' should print:\n"); foo(25)
+}
%}
probe begin {
- printf("foo(1)=%d, should be 99\n", foo(1))
- printf("foo(15)=%d, should be 85\n", foo(15))
+ printf("U foo(1)=%d, should be 99\n", foo(1))
+ printf("U foo(15)=%d, should be 85\n", foo(15))
+}
+
+probe kernel.function("vfs_read") {
+ printf("K foo(1)=%d, should be 99\n", foo(1))
+ printf("K foo(15)=%d, should be 85\n", foo(15))
exit()
}
-function foo:long (x:long) %{ /* bpf */ /* pure */
+function foo:string (x:long) %{ /* bpf */ /* pure */
/* if x <= 10 then "fifty" else "one-hundred" */
0xd5, $x, -, _bar, 10; /* jsle $x, 10, _bar */
0xbf, $$, "one-hundred", -, -; /* mov $$, "one-hundred" */
/* 0xbf, $$, $$, -, -; /* dummy op */
%}
-function bar:long (x:long) {
- if (x <= 10) return 50 else return 100
+function bar:string (x:long) {
+ if (x <= 10) return "fifty" else return "one-hundred"
}
probe begin {
- printf("foo(1)=%d should be %d\n", foo(1), bar(1))
- printf("foo(8)=%d should be %d\n", foo(8), bar(8))
- printf("foo(15)=%d should be %d\n", foo(15), bar(15))
+ printf("U foo(1)=%s should be %s\n", foo(1), bar(1))
+ printf("U foo(8)=%s should be %s\n", foo(8), bar(8))
+ printf("U foo(15)=%s should be %s\n", foo(15), bar(15))
+}
+
+probe kernel.function("vfs_read") {
+ printf("K foo(1)=%s should be %s\n", bar(1), bar(1))
+ printf("K foo(8)=%s should be %s\n", bar(8), bar(8))
+ printf("K foo(15)=%s should be %s\n", bar(15), bar(15))
+ # printf("K foo(1)=%s should be %s\n", foo(1), bar(1))
+ # printf("K foo(8)=%s should be %s\n", foo(8), bar(8))
+ # printf("K foo(15)=%s should be %s\n", foo(15), bar(15))
exit()
}
%}
probe begin {
- printf("foo(1)=%d, should be 99*3=297\n", foo(1))
- printf("foo(15)=%d, should be 85*18=1530\n", foo(15))
+ printf("U foo(1)=%d, should be 99*3=297\n", foo(1))
+ printf("U foo(15)=%d, should be 85*18=1530\n", foo(15))
+}
+
+probe kernel.function("vfs_read") {
+ printf("K foo(1)=%d, should be 99*3=297\n", foo(1))
+ printf("K foo(15)=%d, should be 85*18=1530\n", foo(15))
exit()
}
--- /dev/null
+/* testcase for an early bug that would generate duplicate jump */
+function foo:long (x:long) %{ /* bpf */
+ /* the code in the middle is unreachable */
+ 0xd5, $x, -, _bar, 20; /* jsle $x, 20, _done */
+ 0xb7, $$, -, -, 100; /* mov $$, 100 */
+ 0x05, -, -, _done, -;
+ label, _bar;
+ 0xb7, $$, -, -, 50; /* mov $$, 50 */
+ label, _done;
+%}
+
+probe kernel.function("vfs_read") {
+ x = 10
+ if (x > 12) printf("unreachable\n")
+ printf ("got %d (should be 50)\n", foo(x))
+ exit()
+}
--- /dev/null
+# bpf-asm.exp
+#
+# TODO: Very basic test driver. Need to work out a way of signaling correctness.
+
+set testdir "$srcdir/$subdir/asm_tests"
+
+proc stapbpf_run { TEST_NAME args } {
+ global rc
+ set rc -1
+
+ # return codes
+ set pass 0
+ #set fail 1
+ #set bad_output 2
+ set eof_start 3
+ set eof_end 4
+ set timeout_start 5
+ set timeout_end 6
+ set invalid_prog 7
+ set comp_err 8
+
+ set cmd [concat stap -vg --runtime=bpf $args]
+ send_log "executing: $cmd\n"
+ eval spawn $cmd
+ set mypid [exp_pid -i $spawn_id]
+ expect {
+ -timeout 30
+ -re {Pass 5: starting run} {
+ expect {
+ -timeout 20
+ -re {Pass 5: run completed} {
+ set rc $pass
+ }
+ -re "bpf program load failed:" { set rc $invalid_prog }
+ default {
+ set rc $bad_output
+ }
+ timeout {
+ set rc $timeout_end
+ kill -INT -$mypid
+ }
+ eof {
+ set rc $eof_end
+ }
+ }
+ }
+ -re "semantic error:" { set rc $comp_err }
+ -re "bpf program load failed:" { set rc $invalid_prog }
+ timeout {
+ set rc $timeout_start
+ kill -INT -$mypid
+ }
+ eof {
+ set rc $eof_start
+ }
+ }
+ # again for good measure with KILL after 3s
+ kill -INT -$mypid 3
+ catch close
+ wait
+ return $rc
+}
+
+set stap_files [lsort [glob -nocomplain $testdir/*.stp]]
+
+foreach file $stap_files {
+ global mypid
+ set mypid 0
+ set test [file tail $file]
+ if {! [installtest_p]} { untested $test; continue }
+ if {! [bpf_p]} { untested $test; continue }
+
+ set errtest_p [regexp {^err} [file tail $file]]
+ verbose -log "Running $file"
+ switch [stapbpf_run $test $file] {
+ 0 {
+ if $errtest_p {
+ fail "$test unexpected success"
+ } else {
+ pass $test
+ }
+ }
+ 1 { fail "$test incorrect result" }
+ 2 { fail "$test unexpected output" }
+ 3 { fail "$test eof (startup)" }
+ 4 { fail "$test eof (shutdown)" }
+ 5 { fail "$test timeout (startup)" }
+ 6 { fail "$test timeout (startup)" }
+ 7 { fail "$test invalid bpf program" }
+ 8 {
+ if $errtest_p {
+ pass $test
+ } else {
+ fail "$test compilation"
+ }
+ }
+ default { fail "$test unknown return value" }
+ }
+
+ if { $mypid > 0 } {
+ kill -INT -$mypid 3
+ catch close
+ wait
+ }
+}