forked from OSchip/llvm-project
Make sure globals created by UBSan are not instrumented by ASan.
Summary: This change adds description of globals created by UBSan instrumentation (UBSan handlers, type descriptors, filenames) to llvm.asan.globals metadata, effectively "blacklisting" them. This can dramatically decrease the data section in binaries built with UBSan+ASan, as UBSan tends to create a lot of handlers, and ASan instrumentation increases the global size to at least 64 bytes. Test Plan: clang regression test suite Reviewers: rsmith Reviewed By: rsmith Subscribers: cfe-commits, byoungyoung, kcc Differential Revision: http://reviews.llvm.org/D4575 llvm-svn: 213392
This commit is contained in:
parent
5450240219
commit
6c12414358
|
@ -2127,6 +2127,7 @@ llvm::Constant *CodeGenFunction::EmitCheckTypeDescriptor(QualType T) {
|
||||||
CGM.getModule(), Descriptor->getType(),
|
CGM.getModule(), Descriptor->getType(),
|
||||||
/*isConstant=*/true, llvm::GlobalVariable::PrivateLinkage, Descriptor);
|
/*isConstant=*/true, llvm::GlobalVariable::PrivateLinkage, Descriptor);
|
||||||
GV->setUnnamedAddr(true);
|
GV->setUnnamedAddr(true);
|
||||||
|
CGM.disableSanitizerForGlobal(GV);
|
||||||
|
|
||||||
// Remember the descriptor for this type.
|
// Remember the descriptor for this type.
|
||||||
CGM.setTypeDescriptorInMap(T, GV);
|
CGM.setTypeDescriptorInMap(T, GV);
|
||||||
|
@ -2170,14 +2171,23 @@ llvm::Value *CodeGenFunction::EmitCheckValue(llvm::Value *V) {
|
||||||
/// \endcode
|
/// \endcode
|
||||||
/// For an invalid SourceLocation, the Filename pointer is null.
|
/// For an invalid SourceLocation, the Filename pointer is null.
|
||||||
llvm::Constant *CodeGenFunction::EmitCheckSourceLocation(SourceLocation Loc) {
|
llvm::Constant *CodeGenFunction::EmitCheckSourceLocation(SourceLocation Loc) {
|
||||||
PresumedLoc PLoc = getContext().getSourceManager().getPresumedLoc(Loc);
|
llvm::Constant *Filename;
|
||||||
|
int Line, Column;
|
||||||
|
|
||||||
llvm::Constant *Data[] = {
|
PresumedLoc PLoc = getContext().getSourceManager().getPresumedLoc(Loc);
|
||||||
PLoc.isValid() ? CGM.GetAddrOfConstantCString(PLoc.getFilename(), ".src")
|
if (PLoc.isValid()) {
|
||||||
: llvm::Constant::getNullValue(Int8PtrTy),
|
auto FilenameGV = CGM.GetAddrOfConstantCString(PLoc.getFilename(), ".src");
|
||||||
Builder.getInt32(PLoc.isValid() ? PLoc.getLine() : 0),
|
CGM.disableSanitizerForGlobal(FilenameGV);
|
||||||
Builder.getInt32(PLoc.isValid() ? PLoc.getColumn() : 0)
|
Filename = FilenameGV;
|
||||||
};
|
Line = PLoc.getLine();
|
||||||
|
Column = PLoc.getColumn();
|
||||||
|
} else {
|
||||||
|
Filename = llvm::Constant::getNullValue(Int8PtrTy);
|
||||||
|
Line = Column = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
llvm::Constant *Data[] = {Filename, Builder.getInt32(Line),
|
||||||
|
Builder.getInt32(Column)};
|
||||||
|
|
||||||
return llvm::ConstantStruct::getAnon(Data);
|
return llvm::ConstantStruct::getAnon(Data);
|
||||||
}
|
}
|
||||||
|
@ -2214,6 +2224,7 @@ void CodeGenFunction::EmitCheck(llvm::Value *Checked, StringRef CheckName,
|
||||||
new llvm::GlobalVariable(CGM.getModule(), Info->getType(), false,
|
new llvm::GlobalVariable(CGM.getModule(), Info->getType(), false,
|
||||||
llvm::GlobalVariable::PrivateLinkage, Info);
|
llvm::GlobalVariable::PrivateLinkage, Info);
|
||||||
InfoPtr->setUnnamedAddr(true);
|
InfoPtr->setUnnamedAddr(true);
|
||||||
|
CGM.disableSanitizerForGlobal(InfoPtr);
|
||||||
|
|
||||||
SmallVector<llvm::Value *, 4> Args;
|
SmallVector<llvm::Value *, 4> Args;
|
||||||
SmallVector<llvm::Type *, 4> ArgTypes;
|
SmallVector<llvm::Type *, 4> ArgTypes;
|
||||||
|
|
|
@ -1951,11 +1951,11 @@ void CodeGenModule::EmitGlobalVarDefinition(const VarDecl *D) {
|
||||||
|
|
||||||
void CodeGenModule::reportGlobalToASan(llvm::GlobalVariable *GV,
|
void CodeGenModule::reportGlobalToASan(llvm::GlobalVariable *GV,
|
||||||
SourceLocation Loc, StringRef Name,
|
SourceLocation Loc, StringRef Name,
|
||||||
bool IsDynInit) {
|
bool IsDynInit, bool IsBlacklisted) {
|
||||||
if (!LangOpts.Sanitize.Address)
|
if (!LangOpts.Sanitize.Address)
|
||||||
return;
|
return;
|
||||||
IsDynInit &= !SanitizerBL.isIn(*GV, "init");
|
IsDynInit &= !SanitizerBL.isIn(*GV, "init");
|
||||||
bool IsBlacklisted = SanitizerBL.isIn(*GV);
|
IsBlacklisted |= SanitizerBL.isIn(*GV);
|
||||||
|
|
||||||
llvm::GlobalVariable *LocDescr = nullptr;
|
llvm::GlobalVariable *LocDescr = nullptr;
|
||||||
llvm::GlobalVariable *GlobalName = nullptr;
|
llvm::GlobalVariable *GlobalName = nullptr;
|
||||||
|
@ -2008,6 +2008,13 @@ void CodeGenModule::reportGlobalToASan(llvm::GlobalVariable *GV,
|
||||||
reportGlobalToASan(GV, D.getLocation(), OS.str(), IsDynInit);
|
reportGlobalToASan(GV, D.getLocation(), OS.str(), IsDynInit);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void CodeGenModule::disableSanitizerForGlobal(llvm::GlobalVariable *GV) {
|
||||||
|
// For now, just make sure the global is not modified by the ASan
|
||||||
|
// instrumentation.
|
||||||
|
if (LangOpts.Sanitize.Address)
|
||||||
|
reportGlobalToASan(GV, SourceLocation(), "", false, true);
|
||||||
|
}
|
||||||
|
|
||||||
static bool isVarDeclStrongDefinition(const VarDecl *D, bool NoCommon) {
|
static bool isVarDeclStrongDefinition(const VarDecl *D, bool NoCommon) {
|
||||||
// Don't give variables common linkage if -fno-common was specified unless it
|
// Don't give variables common linkage if -fno-common was specified unless it
|
||||||
// was overridden by a NoCommon attribute.
|
// was overridden by a NoCommon attribute.
|
||||||
|
|
|
@ -1018,7 +1018,11 @@ public:
|
||||||
void reportGlobalToASan(llvm::GlobalVariable *GV, const VarDecl &D,
|
void reportGlobalToASan(llvm::GlobalVariable *GV, const VarDecl &D,
|
||||||
bool IsDynInit = false);
|
bool IsDynInit = false);
|
||||||
void reportGlobalToASan(llvm::GlobalVariable *GV, SourceLocation Loc,
|
void reportGlobalToASan(llvm::GlobalVariable *GV, SourceLocation Loc,
|
||||||
StringRef Name, bool IsDynInit = false);
|
StringRef Name, bool IsDynInit = false,
|
||||||
|
bool IsBlacklisted = false);
|
||||||
|
|
||||||
|
/// Disable sanitizer instrumentation for this global.
|
||||||
|
void disableSanitizerForGlobal(llvm::GlobalVariable *GV);
|
||||||
|
|
||||||
void addDeferredVTable(const CXXRecordDecl *RD) {
|
void addDeferredVTable(const CXXRecordDecl *RD) {
|
||||||
DeferredVTables.push_back(RD);
|
DeferredVTables.push_back(RD);
|
||||||
|
|
|
@ -1,4 +1,5 @@
|
||||||
// RUN: %clang_cc1 -std=c++11 -fsanitize=signed-integer-overflow,integer-divide-by-zero,float-divide-by-zero,shift,unreachable,return,vla-bound,alignment,null,vptr,object-size,float-cast-overflow,bool,enum,array-bounds,function -emit-llvm %s -o - -triple x86_64-linux-gnu | FileCheck %s
|
// RUN: %clang_cc1 -std=c++11 -fsanitize=signed-integer-overflow,integer-divide-by-zero,float-divide-by-zero,shift,unreachable,return,vla-bound,alignment,null,vptr,object-size,float-cast-overflow,bool,enum,array-bounds,function -emit-llvm %s -o - -triple x86_64-linux-gnu | FileCheck %s
|
||||||
|
// RUN: %clang_cc1 -std=c++11 -fsanitize=vptr,address -emit-llvm %s -o - -triple x86_64-linux-gnu | FileCheck %s --check-prefix=CHECK-ASAN
|
||||||
|
|
||||||
struct S {
|
struct S {
|
||||||
double d;
|
double d;
|
||||||
|
@ -6,6 +7,12 @@ struct S {
|
||||||
virtual int f();
|
virtual int f();
|
||||||
};
|
};
|
||||||
|
|
||||||
|
// Check that type descriptor global is not modified by ASan.
|
||||||
|
// CHECK-ASAN: [[TYPE_DESCR:@[0-9]+]] = private unnamed_addr constant { i16, i16, [4 x i8] } { i16 -1, i16 0, [4 x i8] c"'S'\00" }
|
||||||
|
|
||||||
|
// Check that type mismatch handler is not modified by ASan.
|
||||||
|
// CHECK-ASAN: private unnamed_addr global { { [{{.*}} x i8]*, i32, i32 }, { i16, i16, [4 x i8] }*, i8*, i8 } { {{.*}}, { i16, i16, [4 x i8] }* [[TYPE_DESCR]], {{.*}} }
|
||||||
|
|
||||||
struct T : S {};
|
struct T : S {};
|
||||||
|
|
||||||
// CHECK-LABEL: @_Z17reference_binding
|
// CHECK-LABEL: @_Z17reference_binding
|
||||||
|
@ -31,6 +38,7 @@ void reference_binding(int *p, S *q) {
|
||||||
}
|
}
|
||||||
|
|
||||||
// CHECK-LABEL: @_Z13member_access
|
// CHECK-LABEL: @_Z13member_access
|
||||||
|
// CHECK-ASAN-LABEL: @_Z13member_access
|
||||||
void member_access(S *p) {
|
void member_access(S *p) {
|
||||||
// (1a) Check 'p' is appropriately sized and aligned for member access.
|
// (1a) Check 'p' is appropriately sized and aligned for member access.
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue