pcc created this revision.
pcc added a reviewer: rnk.
pcc added a subscriber: cfe-commits.
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.
http://reviews.llvm.org/D11048
Files:
lib/CodeGen/CGClass.cpp
lib/CodeGen/CGVTables.cpp
lib/CodeGen/CodeGenModule.h
lib/CodeGen/MicrosoftCXXABI.cpp
test/CodeGenCXX/cfi-ms-rtti.cpp
Index: test/CodeGenCXX/cfi-ms-rtti.cpp
===================================================================
--- /dev/null
+++ test/CodeGenCXX/cfi-ms-rtti.cpp
@@ -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}
Index: lib/CodeGen/MicrosoftCXXABI.cpp
===================================================================
--- lib/CodeGen/MicrosoftCXXABI.cpp
+++ lib/CodeGen/MicrosoftCXXABI.cpp
@@ -1466,20 +1466,27 @@
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 @@
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,
Index: lib/CodeGen/CodeGenModule.h
===================================================================
--- lib/CodeGen/CodeGenModule.h
+++ lib/CodeGen/CodeGenModule.h
@@ -1126,6 +1126,10 @@
/// \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,
Index: lib/CodeGen/CGVTables.cpp
===================================================================
--- lib/CodeGen/CGVTables.cpp
+++ lib/CodeGen/CGVTables.cpp
@@ -841,6 +841,11 @@
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 @@
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(
Index: lib/CodeGen/CGClass.cpp
===================================================================
--- lib/CodeGen/CGClass.cpp
+++ lib/CodeGen/CGClass.cpp
@@ -2207,8 +2207,7 @@
llvm::Value *VTable,
CFITypeCheckKind TCK,
SourceLocation Loc) {
- // FIXME: Add blacklisting scheme.
- if (RD->isInStdNamespace())
+ if (CGM.IsCFIBlacklistedRecord(RD))
return;
SanitizerScope SanScope(this);
_______________________________________________
cfe-commits mailing list
[email protected]
http://lists.cs.uiuc.edu/mailman/listinfo/cfe-commits