summaryrefslogtreecommitdiffstats
path: root/clang/test/CodeGenCXX/cfi-vptr.cpp
diff options
context:
space:
mode:
authorPeter Collingbourne <peter@pcc.me.uk>2015-02-20 20:30:56 +0000
committerPeter Collingbourne <peter@pcc.me.uk>2015-02-20 20:30:56 +0000
commita4ccff32818c05c9f2d7a2a6503866d13636b664 (patch)
treed0853e78880e850956141ea043fecb36250e5842 /clang/test/CodeGenCXX/cfi-vptr.cpp
parente6909c8e8ba07acb5e6366186fe186c91054e93c (diff)
downloadbcm5719-llvm-a4ccff32818c05c9f2d7a2a6503866d13636b664.tar.gz
bcm5719-llvm-a4ccff32818c05c9f2d7a2a6503866d13636b664.zip
Implement Control Flow Integrity for virtual calls.
This patch introduces the -fsanitize=cfi-vptr flag, which enables a control flow integrity scheme that checks that virtual calls take place using a vptr of the correct dynamic type. More details in the new docs/ControlFlowIntegrity.rst file. It also introduces the -fsanitize=cfi flag, which is currently a synonym for -fsanitize=cfi-vptr, but will eventually cover all CFI checks implemented in Clang. Differential Revision: http://reviews.llvm.org/D7424 llvm-svn: 230055
Diffstat (limited to 'clang/test/CodeGenCXX/cfi-vptr.cpp')
-rw-r--r--clang/test/CodeGenCXX/cfi-vptr.cpp74
1 files changed, 74 insertions, 0 deletions
diff --git a/clang/test/CodeGenCXX/cfi-vptr.cpp b/clang/test/CodeGenCXX/cfi-vptr.cpp
new file mode 100644
index 00000000000..545f22c3c72
--- /dev/null
+++ b/clang/test/CodeGenCXX/cfi-vptr.cpp
@@ -0,0 +1,74 @@
+// RUN: %clang_cc1 -triple x86_64-unknown-linux -fsanitize=cfi-vptr -emit-llvm -o - %s | FileCheck %s
+
+struct A {
+ A();
+ virtual void f();
+};
+
+struct B : virtual A {
+ B();
+};
+
+struct C : virtual A {
+ C();
+};
+
+namespace {
+
+struct D : B, C {
+ D();
+ virtual void f();
+};
+
+}
+
+A::A() {}
+B::B() {}
+C::C() {}
+D::D() {}
+
+void A::f() {
+}
+
+void D::f() {
+}
+
+// CHECK: define void @_Z2afP1A
+void af(A *a) {
+ // CHECK: [[P:%[^ ]*]] = call i1 @llvm.bitset.test(i8* {{%[^ ]*}}, metadata !"1A")
+ // CHECK-NEXT: br i1 [[P]], label %[[CONTBB:[^ ]*]], label %[[TRAPBB:[^ ]*]]
+
+ // CHECK: [[TRAPBB]]
+ // CHECK-NEXT: call void @llvm.trap()
+ // CHECK-NEXT: unreachable
+
+ // CHECK: [[CONTBB]]
+ // CHECK: call void %
+ a->f();
+}
+
+// CHECK: define internal void @_Z2dfPN12_GLOBAL__N_11DE
+void df(D *d) {
+ // CHECK: {{%[^ ]*}} = call i1 @llvm.bitset.test(i8* {{%[^ ]*}}, metadata !"[{{.*}}cfi-vptr.cpp]N12_GLOBAL__N_11DE")
+ d->f();
+}
+
+D d;
+
+void foo() {
+ df(&d);
+}
+
+// CHECK-DAG: !{!"1A", [3 x i8*]* @_ZTV1A, i64 16}
+// CHECK-DAG: !{!"1A", [5 x i8*]* @_ZTCN12_GLOBAL__N_11DE0_1B, i64 32}
+// CHECK-DAG: !{!"1B", [5 x i8*]* @_ZTCN12_GLOBAL__N_11DE0_1B, i64 32}
+// CHECK-DAG: !{!"1A", [9 x i8*]* @_ZTCN12_GLOBAL__N_11DE8_1C, i64 64}
+// CHECK-DAG: !{!"1C", [9 x i8*]* @_ZTCN12_GLOBAL__N_11DE8_1C, i64 32}
+// CHECK-DAG: !{!"1A", [10 x i8*]* @_ZTVN12_GLOBAL__N_11DE, i64 32}
+// CHECK-DAG: !{!"1B", [10 x i8*]* @_ZTVN12_GLOBAL__N_11DE, i64 32}
+// CHECK-DAG: !{!"1C", [10 x i8*]* @_ZTVN12_GLOBAL__N_11DE, i64 72}
+// CHECK-DAG: !{!"[{{.*}}cfi-vptr.cpp]N12_GLOBAL__N_11DE", [10 x i8*]* @_ZTVN12_GLOBAL__N_11DE, i64 32}
+// CHECK-DAG: !{!"1A", [5 x i8*]* @_ZTV1B, i64 32}
+// CHECK-DAG: !{!"1B", [5 x i8*]* @_ZTV1B, i64 32}
+// CHECK-DAG: !{!"1A", [5 x i8*]* @_ZTV1C, i64 32}
+// CHECK-DAG: !{!"1C", [5 x i8*]* @_ZTV1C, i64 32}
OpenPOWER on IntegriCloud