Modified to be compatible with r212643, and thus dropping the dependency with
http://reviews.llvm.org/D4406.
http://reviews.llvm.org/D4407
Files:
lib/CodeGen/CGExpr.cpp
lib/CodeGen/SanitizerBlacklist.cpp
lib/CodeGen/SanitizerBlacklist.h
test/CodeGen/ubsan-type-blacklist.cpp
Index: lib/CodeGen/CGExpr.cpp
===================================================================
--- lib/CodeGen/CGExpr.cpp
+++ lib/CodeGen/CGExpr.cpp
@@ -544,44 +544,48 @@
llvm::raw_svector_ostream Out(MangledName);
CGM.getCXXABI().getMangleContext().mangleCXXRTTI(Ty.getUnqualifiedType(),
Out);
- llvm::hash_code TypeHash = hash_value(Out.str());
- // Load the vptr, and compute hash_16_bytes(TypeHash, vptr).
- llvm::Value *Low = llvm::ConstantInt::get(Int64Ty, TypeHash);
- llvm::Type *VPtrTy = llvm::PointerType::get(IntPtrTy, 0);
- llvm::Value *VPtrAddr = Builder.CreateBitCast(Address, VPtrTy);
- llvm::Value *VPtrVal = Builder.CreateLoad(VPtrAddr);
- llvm::Value *High = Builder.CreateZExt(VPtrVal, Int64Ty);
-
- llvm::Value *Hash = emitHash16Bytes(Builder, Low, High);
- Hash = Builder.CreateTrunc(Hash, IntPtrTy);
-
- // Look the hash up in our cache.
- const int CacheSize = 128;
- llvm::Type *HashTable = llvm::ArrayType::get(IntPtrTy, CacheSize);
- llvm::Value *Cache = CGM.CreateRuntimeVariable(HashTable,
- "__ubsan_vptr_type_cache");
- llvm::Value *Slot = Builder.CreateAnd(Hash,
- llvm::ConstantInt::get(IntPtrTy,
- CacheSize-1));
- llvm::Value *Indices[] = { Builder.getInt32(0), Slot };
- llvm::Value *CacheVal =
- Builder.CreateLoad(Builder.CreateInBoundsGEP(Cache, Indices));
-
- // If the hash isn't in the cache, call a runtime handler to perform the
- // hard work of checking whether the vptr is for an object of the right
- // type. This will either fill in the cache and return, or produce a
- // diagnostic.
- llvm::Constant *StaticData[] = {
- EmitCheckSourceLocation(Loc),
- EmitCheckTypeDescriptor(Ty),
- CGM.GetAddrOfRTTIDescriptor(Ty.getUnqualifiedType()),
- llvm::ConstantInt::get(Int8Ty, TCK)
- };
- llvm::Value *DynamicData[] = { Address, Hash };
- EmitCheck(Builder.CreateICmpEQ(CacheVal, Hash),
- "dynamic_type_cache_miss", StaticData, DynamicData,
- CRK_AlwaysRecoverable);
+ // Blacklist based on the mangled type.
+ if (!CGM.getSanitizerBlacklist().isBlacklistedType(Out.str())) {
+ llvm::hash_code TypeHash = hash_value(Out.str());
+
+ // Load the vptr, and compute hash_16_bytes(TypeHash, vptr).
+ llvm::Value *Low = llvm::ConstantInt::get(Int64Ty, TypeHash);
+ llvm::Type *VPtrTy = llvm::PointerType::get(IntPtrTy, 0);
+ llvm::Value *VPtrAddr = Builder.CreateBitCast(Address, VPtrTy);
+ llvm::Value *VPtrVal = Builder.CreateLoad(VPtrAddr);
+ llvm::Value *High = Builder.CreateZExt(VPtrVal, Int64Ty);
+
+ llvm::Value *Hash = emitHash16Bytes(Builder, Low, High);
+ Hash = Builder.CreateTrunc(Hash, IntPtrTy);
+
+ // Look the hash up in our cache.
+ const int CacheSize = 128;
+ llvm::Type *HashTable = llvm::ArrayType::get(IntPtrTy, CacheSize);
+ llvm::Value *Cache = CGM.CreateRuntimeVariable(HashTable,
+ "__ubsan_vptr_type_cache");
+ llvm::Value *Slot = Builder.CreateAnd(Hash,
+ llvm::ConstantInt::get(IntPtrTy,
+ CacheSize-1));
+ llvm::Value *Indices[] = { Builder.getInt32(0), Slot };
+ llvm::Value *CacheVal =
+ Builder.CreateLoad(Builder.CreateInBoundsGEP(Cache, Indices));
+
+ // If the hash isn't in the cache, call a runtime handler to perform the
+ // hard work of checking whether the vptr is for an object of the right
+ // type. This will either fill in the cache and return, or produce a
+ // diagnostic.
+ llvm::Constant *StaticData[] = {
+ EmitCheckSourceLocation(Loc),
+ EmitCheckTypeDescriptor(Ty),
+ CGM.GetAddrOfRTTIDescriptor(Ty.getUnqualifiedType()),
+ llvm::ConstantInt::get(Int8Ty, TCK)
+ };
+ llvm::Value *DynamicData[] = { Address, Hash };
+ EmitCheck(Builder.CreateICmpEQ(CacheVal, Hash),
+ "dynamic_type_cache_miss", StaticData, DynamicData,
+ CRK_AlwaysRecoverable);
+ }
}
if (Done) {
Index: lib/CodeGen/SanitizerBlacklist.h
===================================================================
--- lib/CodeGen/SanitizerBlacklist.h
+++ lib/CodeGen/SanitizerBlacklist.h
@@ -38,6 +38,7 @@
bool isIn(const llvm::Function &F) const;
bool isIn(const llvm::GlobalVariable &G,
const StringRef Category = StringRef()) const;
+ bool isBlacklistedType(StringRef MangledTypeName) const;
};
} // end namespace CodeGen
} // end namespace clang
Index: lib/CodeGen/SanitizerBlacklist.cpp
===================================================================
--- lib/CodeGen/SanitizerBlacklist.cpp
+++ lib/CodeGen/SanitizerBlacklist.cpp
@@ -46,3 +46,7 @@
SCL->inSection("global", G.getName(), Category) ||
SCL->inSection("type", GetGlobalTypeString(G), Category);
}
+
+bool SanitizerBlacklist::isBlacklistedType(StringRef MangledTypeName) const {
+ return SCL->inSection("type", MangledTypeName);
+}
Index: test/CodeGen/ubsan-type-blacklist.cpp
===================================================================
--- test/CodeGen/ubsan-type-blacklist.cpp
+++ test/CodeGen/ubsan-type-blacklist.cpp
@@ -0,0 +1,23 @@
+// Verify ubsan vptr does not check down-casts on blacklisted types.
+// RUN: echo "type:_ZTI3Foo" > %t-type.blacklist
+// RUN: %clang_cc1 -fsanitize=vptr -emit-llvm %s -o - | FileCheck %s --check-prefix=DEFAULT
+// RUN: %clang_cc1 -fsanitize=vptr -fsanitize-blacklist=%t-type.blacklist -emit-llvm %s -o - | FileCheck %s --check-prefix=TYPE
+
+// REQUIRES: shell
+
+class Bar {
+public:
+ virtual ~Bar() {}
+};
+class Foo : public Bar {};
+
+Bar bar;
+
+// DEFAULT: @_Z7checkmev
+// TYPE: @_Z7checkmev
+void checkme() {
+// DEFAULT: call void @__ubsan_handle_dynamic_type_cache_miss({{.*}} (%class.Bar* @bar to
+// TYPE-NOT: call void @__ubsan_handle_dynamic_type_cache_miss({{.*}} (%class.Bar* @bar to
+ Foo* foo = static_cast<Foo*>(&bar); // down-casting
+ return;
+}
_______________________________________________
cfe-commits mailing list
[email protected]
http://lists.cs.uiuc.edu/mailman/listinfo/cfe-commits