summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorEvgeniy Stepanov <eugeni.stepanov@gmail.com>2013-11-14 12:31:18 +0000
committerEvgeniy Stepanov <eugeni.stepanov@gmail.com>2013-11-14 12:31:18 +0000
commitb9ac7162892b283f05b70b6d79eb92119712ff0d (patch)
tree90da2162f020d3c30ca3f91f623803b0110d4ea0
parent5e43cfa5e7f6d344f4b0a6a9f7a4b2811d5b8bab (diff)
downloadcompiler-rt-b9ac7162892b283f05b70b6d79eb92119712ff0d.tar.gz
[msan] A test for r194697.
git-svn-id: https://llvm.org/svn/llvm-project/compiler-rt/trunk@194699 91177308-0d34-0410-b5e6-96231b3b80d8
-rw-r--r--lib/msan/lit_tests/wrap_indirect_calls.cc64
-rw-r--r--lib/msan/lit_tests/wrap_indirect_calls/caller.cc51
-rw-r--r--lib/msan/lit_tests/wrap_indirect_calls/lit.local.cfg3
-rw-r--r--lib/msan/lit_tests/wrap_indirect_calls/one.cc3
-rw-r--r--lib/msan/lit_tests/wrap_indirect_calls/two.cc11
-rw-r--r--lib/msan/lit_tests/wrap_indirect_calls/wrapper.cc11
6 files changed, 143 insertions, 0 deletions
diff --git a/lib/msan/lit_tests/wrap_indirect_calls.cc b/lib/msan/lit_tests/wrap_indirect_calls.cc
new file mode 100644
index 000000000..b4bac1ecb
--- /dev/null
+++ b/lib/msan/lit_tests/wrap_indirect_calls.cc
@@ -0,0 +1,64 @@
+// Test indirect call wrapping in MemorySanitizer.
+
+// RUN: %clangxx_msan -O0 %p/wrap_indirect_calls/two.cc -fPIC -shared -o %t-two-so.so
+// RUN: %clangxx_msan -O0 %p/wrap_indirect_calls/wrapper.cc -fPIC -shared -o %t-wrapper-so.so
+
+// Disable fast path.
+
+// RUN: %clangxx_msan -O0 %p/wrap_indirect_calls/caller.cc %p/wrap_indirect_calls/one.cc %s \
+// RUN: %t-two-so.so %t-wrapper-so.so \
+// RUN: -mllvm -msan-wrap-indirect-calls=wrapper \
+// RUN: -mllvm -msan-wrap-indirect-calls-fast=0 \
+// RUN: -DSLOW=1 \
+// RUN: -Wl,--defsym=__executable_start=0 -o %t
+// RUN: %t
+
+// Enable fast path, call from executable, -O0.
+
+// RUN: %clangxx_msan -O0 %p/wrap_indirect_calls/caller.cc %p/wrap_indirect_calls/one.cc %s \
+// RUN: %t-two-so.so %t-wrapper-so.so \
+// RUN: -mllvm -msan-wrap-indirect-calls=wrapper \
+// RUN: -mllvm -msan-wrap-indirect-calls-fast=1 \
+// RUN: -DSLOW=0 \
+// RUN: -Wl,--defsym=__executable_start=0 -o %t
+// RUN: %t
+
+// Enable fast path, call from executable, -O3.
+
+// RUN: %clangxx_msan -O3 %p/wrap_indirect_calls/caller.cc %p/wrap_indirect_calls/one.cc %s \
+// RUN: %t-two-so.so %t-wrapper-so.so \
+// RUN: -mllvm -msan-wrap-indirect-calls=wrapper \
+// RUN: -mllvm -msan-wrap-indirect-calls-fast=1 \
+// RUN: -DSLOW=0 \
+// RUN: -Wl,--defsym=__executable_start=0 -o %t
+// RUN: %t
+
+// Enable fast path, call from DSO, -O0.
+
+// RUN: %clangxx_msan -O0 %p/wrap_indirect_calls/caller.cc %p/wrap_indirect_calls/one.cc -shared \
+// RUN: %t-two-so.so %t-wrapper-so.so \
+// RUN: -mllvm -msan-wrap-indirect-calls=wrapper \
+// RUN: -mllvm -msan-wrap-indirect-calls-fast=1 \
+// RUN: -DSLOW=0 \
+// RUN: -Wl,--defsym=__executable_start=0 -o %t-caller-so.so
+// RUN: %clangxx_msan -O0 %s %t-caller-so.so %t-two-so.so %t-wrapper-so.so -o %t
+// RUN: %t
+
+// Enable fast path, call from DSO, -O3.
+
+// RUN: %clangxx_msan -O3 %p/wrap_indirect_calls/caller.cc %p/wrap_indirect_calls/one.cc -shared \
+// RUN: %t-two-so.so %t-wrapper-so.so \
+// RUN: -mllvm -msan-wrap-indirect-calls=wrapper \
+// RUN: -mllvm -msan-wrap-indirect-calls-fast=1 \
+// RUN: -DSLOW=0 \
+// RUN: -Wl,--defsym=__executable_start=0 -o %t-caller-so.so
+// RUN: %clangxx_msan -O3 %s %t-caller-so.so %t-two-so.so %t-wrapper-so.so -o %t
+// RUN: %t
+
+// The actual test is in multiple files in wrap_indirect_calls/ directory.
+void run_test();
+
+int main() {
+ run_test();
+ return 0;
+}
diff --git a/lib/msan/lit_tests/wrap_indirect_calls/caller.cc b/lib/msan/lit_tests/wrap_indirect_calls/caller.cc
new file mode 100644
index 000000000..a0af8b7bb
--- /dev/null
+++ b/lib/msan/lit_tests/wrap_indirect_calls/caller.cc
@@ -0,0 +1,51 @@
+// Indirectly call a bunch of functions.
+
+#include <assert.h>
+
+extern int cnt;
+
+typedef int (*F)(int, int);
+
+// A function in the same object.
+int f_local(int x, int y) {
+ return x + y;
+}
+
+// A function in another object.
+int f_other_object(int x, int y);
+
+// A function in another DSO.
+int f_dso(int x, int y);
+
+// A function in another DSO that is replaced by the wrapper.
+int f_replaced(int x, int y);
+
+void run_test(void) {
+ int x;
+ int expected_cnt = 0;
+ volatile F f;
+
+ if (SLOW) ++expected_cnt;
+ f = &f_local;
+ x = f(1, 2);
+ assert(x == 3);
+ assert(cnt == expected_cnt);
+
+ if (SLOW) ++expected_cnt;
+ f = &f_other_object;
+ x = f(2, 3);
+ assert(x == 6);
+ assert(cnt == expected_cnt);
+
+ ++expected_cnt;
+ f = &f_dso;
+ x = f(2, 3);
+ assert(x == 7);
+ assert(cnt == expected_cnt);
+
+ ++expected_cnt;
+ f = &f_replaced;
+ x = f(2, 3);
+ assert(x == 11);
+ assert(cnt == expected_cnt);
+}
diff --git a/lib/msan/lit_tests/wrap_indirect_calls/lit.local.cfg b/lib/msan/lit_tests/wrap_indirect_calls/lit.local.cfg
new file mode 100644
index 000000000..5e01230c0
--- /dev/null
+++ b/lib/msan/lit_tests/wrap_indirect_calls/lit.local.cfg
@@ -0,0 +1,3 @@
+# Sources in this directory are used by tests in parent directory.
+
+config.suffixes = []
diff --git a/lib/msan/lit_tests/wrap_indirect_calls/one.cc b/lib/msan/lit_tests/wrap_indirect_calls/one.cc
new file mode 100644
index 000000000..ab7bf4125
--- /dev/null
+++ b/lib/msan/lit_tests/wrap_indirect_calls/one.cc
@@ -0,0 +1,3 @@
+int f_other_object(int x, int y) {
+ return x * y;
+}
diff --git a/lib/msan/lit_tests/wrap_indirect_calls/two.cc b/lib/msan/lit_tests/wrap_indirect_calls/two.cc
new file mode 100644
index 000000000..c939a993b
--- /dev/null
+++ b/lib/msan/lit_tests/wrap_indirect_calls/two.cc
@@ -0,0 +1,11 @@
+int f_dso(int x, int y) {
+ return 2 * x + y;
+}
+
+int f_replaced(int x, int y) {
+ return x + y + 5;
+}
+
+int f_replacement(int x, int y) {
+ return x + y + 6;
+}
diff --git a/lib/msan/lit_tests/wrap_indirect_calls/wrapper.cc b/lib/msan/lit_tests/wrap_indirect_calls/wrapper.cc
new file mode 100644
index 000000000..8fcd0c635
--- /dev/null
+++ b/lib/msan/lit_tests/wrap_indirect_calls/wrapper.cc
@@ -0,0 +1,11 @@
+int f_replaced(int x, int y);
+int f_replacement(int x, int y);
+
+int cnt;
+
+extern "C" void *wrapper(void *p) {
+ ++cnt;
+ if (p == (void *)f_replaced)
+ return (void *)f_replacement;
+ return p;
+}