r241845 - CFI: Emit correct bit set information if RTTI is disabled under MS ABI.

Peter Collingbourne peter at pcc.me.uk
Thu Jul 9 12:56:14 PDT 2015


Author: pcc
Date: Thu Jul  9 14:56:14 2015
New Revision: 241845

URL: http://llvm.org/viewvc/llvm-project?rev=241845&view=rev
Log:
CFI: Emit correct bit set information if RTTI is disabled under MS ABI.

We were previously creating bit set entries at virtual table offset
sizeof(void*) unconditionally under the Microsoft C++ ABI. This is incorrect
if RTTI data is disabled; in that case the "address point" is at offset
0. This change modifies bit set emission to take into account whether RTTI
data is being emitted.

Also make a start on a blacklisting scheme for records.

Differential Revision: http://reviews.llvm.org/D11048

Added:
    cfe/trunk/test/CodeGenCXX/cfi-ms-rtti.cpp
Modified:
    cfe/trunk/lib/CodeGen/CGClass.cpp
    cfe/trunk/lib/CodeGen/CGVTables.cpp
    cfe/trunk/lib/CodeGen/CodeGenModule.h
    cfe/trunk/lib/CodeGen/MicrosoftCXXABI.cpp

Modified: cfe/trunk/lib/CodeGen/CGClass.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/CGClass.cpp?rev=241845&r1=241844&r2=241845&view=diff
==============================================================================
--- cfe/trunk/lib/CodeGen/CGClass.cpp (original)
+++ cfe/trunk/lib/CodeGen/CGClass.cpp Thu Jul  9 14:56:14 2015
@@ -2207,8 +2207,7 @@ void CodeGenFunction::EmitVTablePtrCheck
                                          llvm::Value *VTable,
                                          CFITypeCheckKind TCK,
                                          SourceLocation Loc) {
-  // FIXME: Add blacklisting scheme.
-  if (RD->isInStdNamespace())
+  if (CGM.IsCFIBlacklistedRecord(RD))
     return;
 
   SanitizerScope SanScope(this);

Modified: cfe/trunk/lib/CodeGen/CGVTables.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/CGVTables.cpp?rev=241845&r1=241844&r2=241845&view=diff
==============================================================================
--- cfe/trunk/lib/CodeGen/CGVTables.cpp (original)
+++ cfe/trunk/lib/CodeGen/CGVTables.cpp Thu Jul  9 14:56:14 2015
@@ -841,6 +841,11 @@ void CodeGenModule::EmitDeferredVTables(
   DeferredVTables.clear();
 }
 
+bool CodeGenModule::IsCFIBlacklistedRecord(const CXXRecordDecl *RD) {
+  // FIXME: Make this user configurable.
+  return RD->isInStdNamespace();
+}
+
 void CodeGenModule::EmitVTableBitSetEntries(llvm::GlobalVariable *VTable,
                                             const VTableLayout &VTLayout) {
   if (!LangOpts.Sanitize.has(SanitizerKind::CFIVCall) &&
@@ -855,8 +860,7 @@ void CodeGenModule::EmitVTableBitSetEntr
   std::vector<llvm::MDTuple *> BitsetEntries;
   // Create a bit set entry for each address point.
   for (auto &&AP : VTLayout.getAddressPoints()) {
-    // FIXME: Add blacklisting scheme.
-    if (AP.first.getBase()->isInStdNamespace())
+    if (IsCFIBlacklistedRecord(AP.first.getBase()))
       continue;
 
     BitsetEntries.push_back(CreateVTableBitSetEntry(

Modified: cfe/trunk/lib/CodeGen/CodeGenModule.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/CodeGenModule.h?rev=241845&r1=241844&r2=241845&view=diff
==============================================================================
--- cfe/trunk/lib/CodeGen/CodeGenModule.h (original)
+++ cfe/trunk/lib/CodeGen/CodeGenModule.h Thu Jul  9 14:56:14 2015
@@ -1126,6 +1126,10 @@ public:
   /// \param D Threadprivate declaration.
   void EmitOMPThreadPrivateDecl(const OMPThreadPrivateDecl *D);
 
+  /// Returns whether the given record is blacklisted from control flow
+  /// integrity checks.
+  bool IsCFIBlacklistedRecord(const CXXRecordDecl *RD);
+
   /// Emit bit set entries for the given vtable using the given layout if
   /// vptr CFI is enabled.
   void EmitVTableBitSetEntries(llvm::GlobalVariable *VTable,

Modified: cfe/trunk/lib/CodeGen/MicrosoftCXXABI.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/MicrosoftCXXABI.cpp?rev=241845&r1=241844&r2=241845&view=diff
==============================================================================
--- cfe/trunk/lib/CodeGen/MicrosoftCXXABI.cpp (original)
+++ cfe/trunk/lib/CodeGen/MicrosoftCXXABI.cpp Thu Jul  9 14:56:14 2015
@@ -1466,20 +1466,27 @@ void MicrosoftCXXABI::emitVTableBitSetEn
 
   llvm::NamedMDNode *BitsetsMD =
       CGM.getModule().getOrInsertNamedMetadata("llvm.bitsets");
-  CharUnits PointerWidth = getContext().toCharUnitsFromBits(
-      getContext().getTargetInfo().getPointerWidth(0));
 
-  // FIXME: Add blacklisting scheme.
+  // The location of the first virtual function pointer in the virtual table,
+  // aka the "address point" on Itanium. This is at offset 0 if RTTI is
+  // disabled, or sizeof(void*) if RTTI is enabled.
+  CharUnits AddressPoint =
+      getContext().getLangOpts().RTTIData
+          ? getContext().toCharUnitsFromBits(
+                getContext().getTargetInfo().getPointerWidth(0))
+          : CharUnits::Zero();
 
   if (Info->PathToBaseWithVPtr.empty()) {
-    BitsetsMD->addOperand(
-        CGM.CreateVTableBitSetEntry(VTable, PointerWidth, RD));
+    if (!CGM.IsCFIBlacklistedRecord(RD))
+      BitsetsMD->addOperand(
+          CGM.CreateVTableBitSetEntry(VTable, AddressPoint, RD));
     return;
   }
 
   // Add a bitset entry for the least derived base belonging to this vftable.
-  BitsetsMD->addOperand(CGM.CreateVTableBitSetEntry(
-      VTable, PointerWidth, Info->PathToBaseWithVPtr.back()));
+  if (!CGM.IsCFIBlacklistedRecord(Info->PathToBaseWithVPtr.back()))
+    BitsetsMD->addOperand(CGM.CreateVTableBitSetEntry(
+        VTable, AddressPoint, Info->PathToBaseWithVPtr.back()));
 
   // Add a bitset entry for each derived class that is laid out at the same
   // offset as the least derived base.
@@ -1497,14 +1504,15 @@ void MicrosoftCXXABI::emitVTableBitSetEn
       Offset = VBI->second.VBaseOffset;
     if (!Offset.isZero())
       return;
-    BitsetsMD->addOperand(
-        CGM.CreateVTableBitSetEntry(VTable, PointerWidth, DerivedRD));
+    if (!CGM.IsCFIBlacklistedRecord(DerivedRD))
+      BitsetsMD->addOperand(
+          CGM.CreateVTableBitSetEntry(VTable, AddressPoint, DerivedRD));
   }
 
   // Finally do the same for the most derived class.
-  if (Info->FullOffsetInMDC.isZero())
+  if (Info->FullOffsetInMDC.isZero() && !CGM.IsCFIBlacklistedRecord(RD))
     BitsetsMD->addOperand(
-        CGM.CreateVTableBitSetEntry(VTable, PointerWidth, RD));
+        CGM.CreateVTableBitSetEntry(VTable, AddressPoint, RD));
 }
 
 void MicrosoftCXXABI::emitVTableDefinitions(CodeGenVTables &CGVT,

Added: cfe/trunk/test/CodeGenCXX/cfi-ms-rtti.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/CodeGenCXX/cfi-ms-rtti.cpp?rev=241845&view=auto
==============================================================================
--- cfe/trunk/test/CodeGenCXX/cfi-ms-rtti.cpp (added)
+++ cfe/trunk/test/CodeGenCXX/cfi-ms-rtti.cpp Thu Jul  9 14:56:14 2015
@@ -0,0 +1,12 @@
+// RUN: %clang_cc1 -emit-llvm -o - -triple=x86_64-pc-win32 %s -fsanitize=cfi-vcall | FileCheck --check-prefix=RTTI %s
+// RUN: %clang_cc1 -emit-llvm -o - -triple=x86_64-pc-win32 %s -fsanitize=cfi-vcall -fno-rtti-data | FileCheck --check-prefix=NO-RTTI %s
+
+struct A {
+  A();
+  virtual void f() {}
+};
+
+A::A() {}
+
+// RTTI: !{!"A@@", [2 x i8*]* {{.*}}, i64 8}
+// NO-RTTI: !{!"A@@", [1 x i8*]* {{.*}}, i64 0}





More information about the cfe-commits mailing list