aboutsummaryrefslogtreecommitdiff
path: root/test/cfi
diff options
context:
space:
mode:
authorDimitry Andric <dim@FreeBSD.org>2018-07-28 11:06:48 +0000
committerDimitry Andric <dim@FreeBSD.org>2018-07-28 11:06:48 +0000
commit93c1b73a09a52d4a265f683bf1954b08bb430049 (patch)
tree5543464d74945196cc890e9d9099e5d0660df7eb /test/cfi
parent0d8e7490d6e8a13a8f0977d9b7771803b9f64ea0 (diff)
downloadsrc-93c1b73a09a52d4a265f683bf1954b08bb430049.tar.gz
src-93c1b73a09a52d4a265f683bf1954b08bb430049.zip
Vendor import of compiler-rt trunk r338150:vendor/compiler-rt/compiler-rt-trunk-r338150
Notes
Notes: svn path=/vendor/compiler-rt/dist/; revision=336817 svn path=/vendor/compiler-rt/compiler-rt-trunk-r338150/; revision=336818; tag=vendor/compiler-rt/compiler-rt-trunk-r338150
Diffstat (limited to 'test/cfi')
-rw-r--r--test/cfi/CMakeLists.txt22
-rw-r--r--test/cfi/create-derivers.test6
-rw-r--r--test/cfi/cross-dso-diagnostic.cpp47
-rw-r--r--test/cfi/cross-dso/icall/dlopen.cpp6
-rw-r--r--test/cfi/lit.site.cfg.in1
-rw-r--r--test/cfi/mfcall.cpp96
-rw-r--r--test/cfi/simple-pass.cpp5
-rw-r--r--test/cfi/target_uninstrumented.cpp6
8 files changed, 174 insertions, 15 deletions
diff --git a/test/cfi/CMakeLists.txt b/test/cfi/CMakeLists.txt
index c7fadde53095..4dbbf1759fcc 100644
--- a/test/cfi/CMakeLists.txt
+++ b/test/cfi/CMakeLists.txt
@@ -1,6 +1,6 @@
set(CFI_TESTSUITES)
-macro (add_cfi_test_suites lld thinlto)
+macro (add_cfi_test_suites lld thinlto newpm)
set(suffix)
if (${lld})
set(suffix ${suffix}-lld)
@@ -8,10 +8,14 @@ macro (add_cfi_test_suites lld thinlto)
if (${thinlto})
set(suffix ${suffix}-thinlto)
endif()
+ if (${newpm})
+ set(suffix ${suffix}-newpm)
+ endif()
set(suffix ${suffix}-${CFI_TEST_TARGET_ARCH})
set(CFI_TEST_USE_LLD ${lld})
set(CFI_TEST_USE_THINLTO ${thinlto})
+ set(CFI_TEST_USE_NEWPM ${newpm})
set(CFI_LIT_TEST_MODE Standalone)
set(CFI_TEST_CONFIG_SUFFIX -standalone${suffix})
@@ -40,16 +44,18 @@ foreach(arch ${CFI_TEST_ARCH})
get_test_cc_for_arch(${arch} CFI_TEST_TARGET_CC CFI_TEST_TARGET_CFLAGS)
if (APPLE)
# FIXME: enable ThinLTO tests after fixing http://llvm.org/pr32741
- add_cfi_test_suites(False False)
+ add_cfi_test_suites(False False False)
elseif(WIN32)
- add_cfi_test_suites(True False)
- add_cfi_test_suites(True True)
+ add_cfi_test_suites(True False False)
+ add_cfi_test_suites(True True False)
else()
- add_cfi_test_suites(False False)
- add_cfi_test_suites(False True)
+ add_cfi_test_suites(False False False)
+ add_cfi_test_suites(False True False)
+ add_cfi_test_suites(False False True)
+ add_cfi_test_suites(False True True)
if (COMPILER_RT_HAS_LLD AND NOT arch STREQUAL "i386")
- add_cfi_test_suites(True False)
- add_cfi_test_suites(True True)
+ add_cfi_test_suites(True False False)
+ add_cfi_test_suites(True True False)
endif()
endif()
endforeach()
diff --git a/test/cfi/create-derivers.test b/test/cfi/create-derivers.test
index 8b569d001d89..b651d9be6bd9 100644
--- a/test/cfi/create-derivers.test
+++ b/test/cfi/create-derivers.test
@@ -7,15 +7,15 @@ B0: {{1B|B@@}}: {{.*}} size 1
RUN: %clangxx_cfi -DB32 -flto -c -o %t2.o %S/simple-fail.cpp
RUN: opt -lowertypetests -debug-only=lowertypetests -o /dev/null %t2.o 2>&1 | FileCheck --check-prefix=B32 %s
-B32: {{1B|B@@}}: {{.*}} size 24
+B32: {{1B|B@@}}: {{.*}} size 2{{3|4}}
B32-NOT: all-ones
RUN: %clangxx_cfi -DB64 -flto -c -o %t3.o %S/simple-fail.cpp
RUN: opt -lowertypetests -debug-only=lowertypetests -o /dev/null %t3.o 2>&1 | FileCheck --check-prefix=B64 %s
-B64: {{1B|B@@}}: {{.*}} size 54
+B64: {{1B|B@@}}: {{.*}} size 5{{3|4}}
B64-NOT: all-ones
RUN: %clangxx_cfi -DBM -flto -c -o %t4.o %S/simple-fail.cpp
RUN: opt -lowertypetests -debug-only=lowertypetests -o /dev/null %t4.o 2>&1 | FileCheck --check-prefix=BM %s
-BM: {{1B|B@@}}: {{.*}} size 84
+BM: {{1B|B@@}}: {{.*}} size 8{{3|4}}
BM-NOT: all-ones
diff --git a/test/cfi/cross-dso-diagnostic.cpp b/test/cfi/cross-dso-diagnostic.cpp
new file mode 100644
index 000000000000..f3782dae0272
--- /dev/null
+++ b/test/cfi/cross-dso-diagnostic.cpp
@@ -0,0 +1,47 @@
+// Check that cross-DSO diagnostics print the names of both modules
+
+// RUN: %clangxx_cfi_diag -g -DSHARED_LIB -fPIC -shared -o %dynamiclib %s %ld_flags_rpath_so
+// RUN: %clangxx_cfi_diag -g -o %t_exe_suffix %s %ld_flags_rpath_exe
+// RUN: %t_exe_suffix 2>&1 | FileCheck -DDSONAME=%xdynamiclib_namespec %s
+
+// UNSUPPORTED: win32
+// REQUIRES: cxxabi
+
+#include <dlfcn.h>
+#include <stdio.h>
+
+struct S1 {
+ virtual void f1();
+};
+
+#ifdef SHARED_LIB
+
+void S1::f1() {}
+
+__attribute__((visibility("default"))) extern "C"
+void* dso_symbol() { return new S1(); }
+
+#else
+
+int main() {
+ void* (*fp)(void) =
+ reinterpret_cast<void*(*)(void)>(dlsym(RTLD_DEFAULT, "dso_symbol"));
+ if (!fp) {
+ perror("failed to resolve dso_symbol");
+ return 1;
+ }
+
+ // CHECK: runtime error: control flow integrity check for type 'void *()' failed during indirect function call
+ // CHECK: dso_symbol defined here
+ // CHECK: check failed in {{.*}}_exe_suffix, destination function located in {{.*}}[[DSONAME]]
+ void *S = fp(); // trigger cfi-icall failure
+
+ // CHECK: runtime error: control flow integrity check for type 'S1' failed during cast to unrelated type
+ // CHECK: invalid vtable
+ // CHECK: check failed in {{.*}}_exe_suffix, vtable located in {{.*}}[[DSONAME]]
+ S1 *Scast = reinterpret_cast<S1*>(S); // trigger cfi-unrelated-cast failure
+
+ return 0;
+}
+
+#endif // SHARED_LIB
diff --git a/test/cfi/cross-dso/icall/dlopen.cpp b/test/cfi/cross-dso/icall/dlopen.cpp
index d238a7acec89..c9674c3fb412 100644
--- a/test/cfi/cross-dso/icall/dlopen.cpp
+++ b/test/cfi/cross-dso/icall/dlopen.cpp
@@ -83,10 +83,12 @@ static void save_code(char *p) {
}
static void restore_code() {
- char *code = (char *)mmap(real_start, kCodeSize, PROT_WRITE | PROT_EXEC,
- MAP_PRIVATE | MAP_ANONYMOUS | MAP_FIXED, 0, 0);
+ char *code =
+ (char *)mmap(real_start, kCodeSize, PROT_READ | PROT_WRITE | PROT_EXEC,
+ MAP_PRIVATE | MAP_ANONYMOUS | MAP_FIXED, 0, 0);
assert(code == real_start);
memcpy(code, saved_code, kCodeSize);
+ __builtin___clear_cache(code, code + kCodeSize);
}
int main(int argc, char *argv[]) {
diff --git a/test/cfi/lit.site.cfg.in b/test/cfi/lit.site.cfg.in
index eb9b44137fdf..a735e8812acd 100644
--- a/test/cfi/lit.site.cfg.in
+++ b/test/cfi/lit.site.cfg.in
@@ -7,6 +7,7 @@ config.target_cflags = "@CFI_TEST_TARGET_CFLAGS@"
config.use_lld = @CFI_TEST_USE_LLD@
config.use_lto = True # CFI *requires* LTO.
config.use_thinlto = @CFI_TEST_USE_THINLTO@
+config.use_newpm = @CFI_TEST_USE_NEWPM@
lit_config.load_config(config, "@COMPILER_RT_BINARY_DIR@/test/lit.common.configured")
lit_config.load_config(config, "@CMAKE_CURRENT_SOURCE_DIR@/lit.cfg")
diff --git a/test/cfi/mfcall.cpp b/test/cfi/mfcall.cpp
new file mode 100644
index 000000000000..6e22e3f3d711
--- /dev/null
+++ b/test/cfi/mfcall.cpp
@@ -0,0 +1,96 @@
+// UNSUPPORTED: win32
+
+// RUN: %clangxx_cfi -o %t %s
+// RUN: %expect_crash %run %t a
+// RUN: %expect_crash %run %t b
+// RUN: %expect_crash %run %t c
+// RUN: %expect_crash %run %t d
+// RUN: %expect_crash %run %t e
+// RUN: %run %t f
+// RUN: %run %t g
+
+// RUN: %clangxx_cfi_diag -o %t2 %s
+// RUN: %run %t2 a 2>&1 | FileCheck --check-prefix=A %s
+// RUN: %run %t2 b 2>&1 | FileCheck --check-prefix=B %s
+// RUN: %run %t2 c 2>&1 | FileCheck --check-prefix=C %s
+// RUN: %run %t2 d 2>&1 | FileCheck --check-prefix=D %s
+// RUN: %run %t2 e 2>&1 | FileCheck --check-prefix=E %s
+
+#include <assert.h>
+#include <string.h>
+
+struct SBase1 {
+ void b1() {}
+};
+
+struct SBase2 {
+ void b2() {}
+};
+
+struct S : SBase1, SBase2 {
+ void f1() {}
+ int f2() { return 1; }
+ virtual void g1() {}
+ virtual int g2() { return 1; }
+ virtual int g3() { return 1; }
+};
+
+struct T {
+ void f1() {}
+ int f2() { return 2; }
+ virtual void g1() {}
+ virtual int g2() { return 2; }
+ virtual void g3() {}
+};
+
+typedef void (S::*S_void)();
+
+typedef int (S::*S_int)();
+typedef int (T::*T_int)();
+
+template <typename To, typename From>
+To bitcast(From f) {
+ assert(sizeof(To) == sizeof(From));
+ To t;
+ memcpy(&t, &f, sizeof(f));
+ return t;
+}
+
+int main(int argc, char **argv) {
+ S s;
+ T t;
+
+ switch (argv[1][0]) {
+ case 'a':
+ // A: runtime error: control flow integrity check for type 'int (S::*)()' failed during non-virtual pointer to member function call
+ // A: note: S::f1() defined here
+ (s.*bitcast<S_int>(&S::f1))();
+ break;
+ case 'b':
+ // B: runtime error: control flow integrity check for type 'int (T::*)()' failed during non-virtual pointer to member function call
+ // B: note: S::f2() defined here
+ (t.*bitcast<T_int>(&S::f2))();
+ break;
+ case 'c':
+ // C: runtime error: control flow integrity check for type 'int (S::*)()' failed during virtual pointer to member function call
+ // C: note: vtable is of type 'S'
+ (s.*bitcast<S_int>(&S::g1))();
+ break;
+ case 'd':
+ // D: runtime error: control flow integrity check for type 'int (S::*)()' failed during virtual pointer to member function call
+ // D: note: vtable is of type 'T'
+ (reinterpret_cast<S &>(t).*&S::g2)();
+ break;
+ case 'e':
+ // E: runtime error: control flow integrity check for type 'void (S::*)()' failed during virtual pointer to member function call
+ // E: note: vtable is of type 'S'
+ (s.*bitcast<S_void>(&T::g3))();
+ break;
+ case 'f':
+ (s.*&SBase1::b1)();
+ break;
+ case 'g':
+ (s.*&SBase2::b2)();
+ break;
+ }
+}
diff --git a/test/cfi/simple-pass.cpp b/test/cfi/simple-pass.cpp
index aba09be2d816..de791fc1073f 100644
--- a/test/cfi/simple-pass.cpp
+++ b/test/cfi/simple-pass.cpp
@@ -1,5 +1,10 @@
+// -mretpoline does not work yet on Darwin.
+// XFAIL: darwin
+
// RUN: %clangxx_cfi -o %t %s
// RUN: %run %t
+// RUN: %clangxx_cfi -mretpoline -o %t2 %s
+// RUN: %run %t2
// Tests that the CFI mechanism does not crash the program when making various
// kinds of valid calls involving classes with various different linkages and
diff --git a/test/cfi/target_uninstrumented.cpp b/test/cfi/target_uninstrumented.cpp
index 5df0738c078b..6379b7e12f44 100644
--- a/test/cfi/target_uninstrumented.cpp
+++ b/test/cfi/target_uninstrumented.cpp
@@ -32,12 +32,14 @@ void A::f() {}
int main(int argc, char *argv[]) {
void *p = create_B();
// CHECK: runtime error: control flow integrity check for type 'A' failed during cast to unrelated type
- // CHECK: invalid vtable in module {{.*}}libtarget_uninstrumented.cpp.dynamic.so
+ // CHECK: invalid vtable
+ // CHECK: check failed in {{.*}}, vtable located in {{.*}}libtarget_uninstrumented.cpp.dynamic.so
A *a = (A *)p;
memset(p, 0, sizeof(A));
+
// CHECK: runtime error: control flow integrity check for type 'A' failed during cast to unrelated type
- // CHECK-NOT: invalid vtable in module
// CHECK: invalid vtable
+ // CHECK: check failed in {{.*}}, vtable located in (unknown)
a = (A *)p;
// CHECK: done
fprintf(stderr, "done %p\n", a);