This revision was automatically updated to reflect the committed changes.
Closed by commit rL320638: IRGen: When performing CFI checks, load vtable
pointer from vbase when… (authored by pcc, committed by ).
Changed prior to commit:
https://reviews.llvm.org/D41036?vs=126220&id=126831#toc
Repository:
rL LLVM
https://reviews.llvm.org/D41036
Files:
cfe/trunk/lib/CodeGen/CGCXXABI.h
cfe/trunk/lib/CodeGen/CGClass.cpp
cfe/trunk/lib/CodeGen/CGExprCXX.cpp
cfe/trunk/lib/CodeGen/ItaniumCXXABI.cpp
cfe/trunk/lib/CodeGen/MicrosoftCXXABI.cpp
cfe/trunk/test/CodeGenCXX/cfi-ms-vbase-derived-cast.cpp
cfe/trunk/test/CodeGenCXX/cfi-ms-vbase-nvcall.cpp
Index: cfe/trunk/test/CodeGenCXX/cfi-ms-vbase-nvcall.cpp
===================================================================
--- cfe/trunk/test/CodeGenCXX/cfi-ms-vbase-nvcall.cpp
+++ cfe/trunk/test/CodeGenCXX/cfi-ms-vbase-nvcall.cpp
@@ -0,0 +1,27 @@
+// RUN: %clang_cc1 -flto -flto-unit -emit-llvm -o - -triple=x86_64-pc-win32 %s -fsanitize=cfi-nvcall -fsanitize-trap=cfi-nvcall | FileCheck %s
+
+struct foo {
+ virtual ~foo() {}
+ virtual void f() = 0;
+};
+
+template <typename T>
+struct bar : virtual public foo {
+ void f() {}
+};
+
+struct baz : public bar<baz> {
+ virtual ~baz() {}
+ void g() {}
+};
+
+void f(baz *z) {
+ // CHECK: define{{.*}}@"\01?f@@YAXPEAUbaz@@@Z"
+ // Load z, vbtable, vbase offset and vtable.
+ // CHECK: load
+ // CHECK: load
+ // CHECK: load
+ // CHECK: load
+ // CHECK: @llvm.type.test{{.*}}!"?AUfoo@@"
+ z->g();
+}
Index: cfe/trunk/test/CodeGenCXX/cfi-ms-vbase-derived-cast.cpp
===================================================================
--- cfe/trunk/test/CodeGenCXX/cfi-ms-vbase-derived-cast.cpp
+++ cfe/trunk/test/CodeGenCXX/cfi-ms-vbase-derived-cast.cpp
@@ -0,0 +1,29 @@
+// RUN: %clang_cc1 -flto -flto-unit -emit-llvm -o - -triple=x86_64-pc-win32 %s -fsanitize=cfi-derived-cast -fsanitize-trap=cfi-derived-cast | FileCheck %s
+
+struct foo {
+ virtual ~foo() {}
+ virtual void f() = 0;
+};
+
+template <typename T>
+struct bar : virtual public foo {
+ void f() {
+ // CHECK: define{{.*}}@"\01?f@?$bar@Ubaz@@@@UEAAXXZ"
+ // Load "this", vbtable, vbase offset and vtable.
+ // CHECK: load
+ // CHECK: load
+ // CHECK: load
+ // CHECK: load
+ // CHECK: @llvm.type.test{{.*}}!"?AUfoo@@"
+ static_cast<T&>(*this);
+ }
+};
+
+struct baz : public bar<baz> {
+ virtual ~baz() {}
+};
+
+int main() {
+ baz *z = new baz;
+ z->f();
+}
Index: cfe/trunk/lib/CodeGen/ItaniumCXXABI.cpp
===================================================================
--- cfe/trunk/lib/CodeGen/ItaniumCXXABI.cpp
+++ cfe/trunk/lib/CodeGen/ItaniumCXXABI.cpp
@@ -389,6 +389,10 @@
void emitCXXStructor(const CXXMethodDecl *MD, StructorType Type) override;
+ std::pair<llvm::Value *, const CXXRecordDecl *>
+ LoadVTablePtr(CodeGenFunction &CGF, Address This,
+ const CXXRecordDecl *RD) override;
+
private:
bool hasAnyUnusedVirtualInlineFunction(const CXXRecordDecl *RD) const {
const auto &VtableLayout =
@@ -4041,3 +4045,9 @@
}
return CGF.EmitNounwindRuntimeCall(CGF.CGM.getTerminateFn());
}
+
+std::pair<llvm::Value *, const CXXRecordDecl *>
+ItaniumCXXABI::LoadVTablePtr(CodeGenFunction &CGF, Address This,
+ const CXXRecordDecl *RD) {
+ return {CGF.GetVTablePtr(This, CGM.Int8PtrTy, RD), RD};
+}
Index: cfe/trunk/lib/CodeGen/MicrosoftCXXABI.cpp
===================================================================
--- cfe/trunk/lib/CodeGen/MicrosoftCXXABI.cpp
+++ cfe/trunk/lib/CodeGen/MicrosoftCXXABI.cpp
@@ -578,7 +578,7 @@
return GetVBaseOffsetFromVBPtr(CGF, Base, VBPOffset, VBTOffset, VBPtr);
}
- std::pair<Address, llvm::Value *>
+ std::tuple<Address, llvm::Value *, const CXXRecordDecl *>
performBaseAdjustment(CodeGenFunction &CGF, Address Value,
QualType SrcRecordTy);
@@ -745,6 +745,10 @@
llvm::GlobalVariable *getThrowInfo(QualType T) override;
+ std::pair<llvm::Value *, const CXXRecordDecl *>
+ LoadVTablePtr(CodeGenFunction &CGF, Address This,
+ const CXXRecordDecl *RD) override;
+
private:
typedef std::pair<const CXXRecordDecl *, CharUnits> VFTableIdTy;
typedef llvm::DenseMap<VFTableIdTy, llvm::GlobalVariable *> VTablesMapTy;
@@ -926,7 +930,7 @@
/// We need to perform a generic polymorphic operation (like a typeid
/// or a cast), which requires an object with a vfptr. Adjust the
/// address to point to an object with a vfptr.
-std::pair<Address, llvm::Value *>
+std::tuple<Address, llvm::Value *, const CXXRecordDecl *>
MicrosoftCXXABI::performBaseAdjustment(CodeGenFunction &CGF, Address Value,
QualType SrcRecordTy) {
Value = CGF.Builder.CreateBitCast(Value, CGF.Int8PtrTy);
@@ -937,7 +941,8 @@
// covers non-virtual base subobjects: a class with its own virtual
// functions would be a candidate to be a primary base.
if (Context.getASTRecordLayout(SrcDecl).hasExtendableVFPtr())
- return std::make_pair(Value, llvm::ConstantInt::get(CGF.Int32Ty, 0));
+ return std::make_tuple(Value, llvm::ConstantInt::get(CGF.Int32Ty, 0),
+ SrcDecl);
// Okay, one of the vbases must have a vfptr, or else this isn't
// actually a polymorphic class.
@@ -956,7 +961,7 @@
llvm::Value *Ptr = CGF.Builder.CreateInBoundsGEP(Value.getPointer(), Offset);
CharUnits VBaseAlign =
CGF.CGM.getVBaseAlignment(Value.getAlignment(), SrcDecl, PolymorphicBase);
- return std::make_pair(Address(Ptr, VBaseAlign), Offset);
+ return std::make_tuple(Address(Ptr, VBaseAlign), Offset, PolymorphicBase);
}
bool MicrosoftCXXABI::shouldTypeidBeNullChecked(bool IsDeref,
@@ -987,7 +992,7 @@
QualType SrcRecordTy,
Address ThisPtr,
llvm::Type *StdTypeInfoPtrTy) {
- std::tie(ThisPtr, std::ignore) =
+ std::tie(ThisPtr, std::ignore, std::ignore) =
performBaseAdjustment(CGF, ThisPtr, SrcRecordTy);
auto Typeid = emitRTtypeidCall(CGF, ThisPtr.getPointer()).getInstruction();
return CGF.Builder.CreateBitCast(Typeid, StdTypeInfoPtrTy);
@@ -1011,7 +1016,8 @@
CGF.CGM.GetAddrOfRTTIDescriptor(DestRecordTy.getUnqualifiedType());
llvm::Value *Offset;
- std::tie(This, Offset) = performBaseAdjustment(CGF, This, SrcRecordTy);
+ std::tie(This, Offset, std::ignore) =
+ performBaseAdjustment(CGF, This, SrcRecordTy);
llvm::Value *ThisPtr = This.getPointer();
Offset = CGF.Builder.CreateTrunc(Offset, CGF.Int32Ty);
@@ -1037,7 +1043,8 @@
MicrosoftCXXABI::EmitDynamicCastToVoid(CodeGenFunction &CGF, Address Value,
QualType SrcRecordTy,
QualType DestTy) {
- std::tie(Value, std::ignore) = performBaseAdjustment(CGF, Value, SrcRecordTy);
+ std::tie(Value, std::ignore, std::ignore) =
+ performBaseAdjustment(CGF, Value, SrcRecordTy);
// PVOID __RTCastToVoid(
// PVOID inptr)
@@ -4244,3 +4251,11 @@
};
CGF.EmitNoreturnRuntimeCallOrInvoke(getThrowFn(), Args);
}
+
+std::pair<llvm::Value *, const CXXRecordDecl *>
+MicrosoftCXXABI::LoadVTablePtr(CodeGenFunction &CGF, Address This,
+ const CXXRecordDecl *RD) {
+ std::tie(This, std::ignore, RD) =
+ performBaseAdjustment(CGF, This, QualType(RD->getTypeForDecl(), 0));
+ return {CGF.GetVTablePtr(This, CGM.Int8PtrTy, RD), RD};
+}
Index: cfe/trunk/lib/CodeGen/CGCXXABI.h
===================================================================
--- cfe/trunk/lib/CodeGen/CGCXXABI.h
+++ cfe/trunk/lib/CodeGen/CGCXXABI.h
@@ -582,6 +582,13 @@
/// Emit a single constructor/destructor with the given type from a C++
/// constructor Decl.
virtual void emitCXXStructor(const CXXMethodDecl *MD, StructorType Type) = 0;
+
+ /// Load a vtable from This, an object of polymorphic type RD, or from one of
+ /// its virtual bases if it does not have its own vtable. Returns the vtable
+ /// and the class from which the vtable was loaded.
+ virtual std::pair<llvm::Value *, const CXXRecordDecl *>
+ LoadVTablePtr(CodeGenFunction &CGF, Address This,
+ const CXXRecordDecl *RD) = 0;
};
// Create an instance of a C++ ABI class:
Index: cfe/trunk/lib/CodeGen/CGClass.cpp
===================================================================
--- cfe/trunk/lib/CodeGen/CGClass.cpp
+++ cfe/trunk/lib/CodeGen/CGClass.cpp
@@ -2627,8 +2627,9 @@
EmitBlock(CheckBlock);
}
- llvm::Value *VTable =
- GetVTablePtr(Address(Derived, getPointerAlign()), Int8PtrTy, ClassDecl);
+ llvm::Value *VTable;
+ std::tie(VTable, ClassDecl) = CGM.getCXXABI().LoadVTablePtr(
+ *this, Address(Derived, getPointerAlign()), ClassDecl);
EmitVTablePtrCheck(ClassDecl, VTable, TCK, Loc);
Index: cfe/trunk/lib/CodeGen/CGExprCXX.cpp
===================================================================
--- cfe/trunk/lib/CodeGen/CGExprCXX.cpp
+++ cfe/trunk/lib/CodeGen/CGExprCXX.cpp
@@ -368,9 +368,11 @@
} else {
if (SanOpts.has(SanitizerKind::CFINVCall) &&
MD->getParent()->isDynamicClass()) {
- llvm::Value *VTable = GetVTablePtr(This, Int8PtrTy, MD->getParent());
- EmitVTablePtrCheckForCall(MD->getParent(), VTable, CFITCK_NVCall,
- CE->getLocStart());
+ llvm::Value *VTable;
+ const CXXRecordDecl *RD;
+ std::tie(VTable, RD) =
+ CGM.getCXXABI().LoadVTablePtr(*this, This, MD->getParent());
+ EmitVTablePtrCheckForCall(RD, VTable, CFITCK_NVCall, CE->getLocStart());
}
if (getLangOpts().AppleKext && MD->isVirtual() && HasQualifier)
_______________________________________________
cfe-commits mailing list
[email protected]
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits