[PATCH] D30756: [cfi] Move all vtables to .data.rel.ro in cross-DSO mode

Evgeniy Stepanov via Phabricator via llvm-commits llvm-commits at lists.llvm.org
Wed Mar 8 13:50:06 PST 2017


eugenis created this revision.

All call targets (which for virtual calls are vtable address points)
must be located above __cfi_check.
https://clang.llvm.org/docs/ControlFlowIntegrityDesign.html#cfi-shadow


Repository:
  rL LLVM

https://reviews.llvm.org/D30756

Files:
  lib/Transforms/IPO/LowerTypeTests.cpp
  test/Transforms/LowerTypeTests/cross-dso-ro.ll


Index: test/Transforms/LowerTypeTests/cross-dso-ro.ll
===================================================================
--- /dev/null
+++ test/Transforms/LowerTypeTests/cross-dso-ro.ll
@@ -0,0 +1,23 @@
+; Check that in cross-DSO mode all constants with !type go to .data.rel.ro.
+; RUN: opt -mtriple i686-linux -S -lowertypetests < %s | FileCheck %s
+; RUN: opt -mtriple i686-linux -S -passes=lowertypetests < %s | FileCheck %s
+
+target datalayout = "e-p:32:32"
+
+; CHECK: @0 = private constant { i32 } { i32 1 }, section ".data.rel.ro"
+; CHECK: @a = alias i32, getelementptr inbounds ({ i32 }, { i32 }* @0, i32 0, i32 0
+ at a = constant i32 1, !type !0
+
+declare i1 @llvm.type.test(i8* %ptr, metadata %bitset) nounwind readnone
+
+; CHECK-LABEL: @foo(
+define i1 @foo() {
+  ; CHECK: ret i1 true
+  %x = call i1 @llvm.type.test(i8* bitcast (i32* @a to i8*), metadata !"typeid1")
+  ret i1 %x
+}
+
+!llvm.module.flags = !{!1}
+
+!0 = !{i32 0, !"typeid1"}
+!1 = !{i32 4, !"Cross-DSO CFI", i32 1}
Index: lib/Transforms/IPO/LowerTypeTests.cpp
===================================================================
--- lib/Transforms/IPO/LowerTypeTests.cpp
+++ lib/Transforms/IPO/LowerTypeTests.cpp
@@ -655,6 +655,12 @@
   auto *CombinedGlobal =
       new GlobalVariable(M, NewInit->getType(), /*isConstant=*/true,
                          GlobalValue::PrivateLinkage, NewInit);
+  // Cross-DSO CFI has a requirement that CFI targets are located at higher
+  // addresses than __cfi_check. This is broken in the rare case when a virtual
+  // table is emitted in .rodata (which can only happen for virtual classes w/o
+  // virtual methods and -fno-rtti). Move them to .data.rel.ro with the rest.
+  if (ObjectFormat == Triple::ELF && M.getModuleFlag("Cross-DSO CFI"))
+    CombinedGlobal->setSection(".data.rel.ro");
 
   StructType *NewTy = cast<StructType>(NewInit->getType());
   const StructLayout *CombinedGlobalLayout = DL.getStructLayout(NewTy);


-------------- next part --------------
A non-text attachment was scrubbed...
Name: D30756.91068.patch
Type: text/x-patch
Size: 1953 bytes
Desc: not available
URL: <http://lists.llvm.org/pipermail/llvm-commits/attachments/20170308/bf74f2b1/attachment.bin>


More information about the llvm-commits mailing list