[Sanitizer] Reduce the usage of sanitizer blacklist in CodeGenModule

Get rid of cached CodeGenModule::SanOpts, which was used to turn off
sanitizer codegen options if current LLVM Module is blacklisted, and use
plain LangOpts.Sanitize instead.

1) Some codegen decisions (turning TBAA or writable strings on/off)
   shouldn't depend on the contents of blacklist.

2) llvm.asan.globals should *always* be created, even if the module
   is blacklisted - soon Clang's CodeGen where we read sanitizer
   blacklist files, so we should properly report which globals are
   blacklisted to the backend.

llvm-svn: 212499
This commit is contained in:
Alexey Samsonov 2014-07-07 23:34:34 +00:00
parent 2620b877b6
commit e7a8ccfaad
4 changed files with 28 additions and 19 deletions

View File

@ -245,12 +245,14 @@ CreateGlobalInitOrDestructFunction(CodeGenModule &CGM,
if (!CGM.getLangOpts().Exceptions) if (!CGM.getLangOpts().Exceptions)
Fn->setDoesNotThrow(); Fn->setDoesNotThrow();
if (CGM.getSanOpts().Address) if (!CGM.getSanitizerBlacklist().isIn(*Fn)) {
Fn->addFnAttr(llvm::Attribute::SanitizeAddress); if (CGM.getLangOpts().Sanitize.Address)
if (CGM.getSanOpts().Thread) Fn->addFnAttr(llvm::Attribute::SanitizeAddress);
Fn->addFnAttr(llvm::Attribute::SanitizeThread); if (CGM.getLangOpts().Sanitize.Thread)
if (CGM.getSanOpts().Memory) Fn->addFnAttr(llvm::Attribute::SanitizeThread);
Fn->addFnAttr(llvm::Attribute::SanitizeMemory); if (CGM.getLangOpts().Sanitize.Memory)
Fn->addFnAttr(llvm::Attribute::SanitizeMemory);
}
return Fn; return Fn;
} }

View File

@ -89,9 +89,7 @@ CodeGenModule::CodeGenModule(ASTContext &C, const CodeGenOptions &CGO,
GenericBlockLiteralType(nullptr), LifetimeStartFn(nullptr), GenericBlockLiteralType(nullptr), LifetimeStartFn(nullptr),
LifetimeEndFn(nullptr), LifetimeEndFn(nullptr),
SanitizerBlacklist( SanitizerBlacklist(
llvm::SpecialCaseList::createOrDie(CGO.SanitizerBlacklistFile)), llvm::SpecialCaseList::createOrDie(CGO.SanitizerBlacklistFile)) {
SanOpts(SanitizerBlacklist->isIn(M) ? SanitizerOptions::Disabled
: LangOpts.Sanitize) {
// Initialize the type cache. // Initialize the type cache.
llvm::LLVMContext &LLVMContext = M.getContext(); llvm::LLVMContext &LLVMContext = M.getContext();
@ -122,7 +120,7 @@ CodeGenModule::CodeGenModule(ASTContext &C, const CodeGenOptions &CGO,
createCUDARuntime(); createCUDARuntime();
// Enable TBAA unless it's suppressed. ThreadSanitizer needs TBAA even at O0. // Enable TBAA unless it's suppressed. ThreadSanitizer needs TBAA even at O0.
if (SanOpts.Thread || if (LangOpts.Sanitize.Thread ||
(!CodeGenOpts.RelaxedAliasing && CodeGenOpts.OptimizationLevel > 0)) (!CodeGenOpts.RelaxedAliasing && CodeGenOpts.OptimizationLevel > 0))
TBAA = new CodeGenTBAA(Context, VMContext, CodeGenOpts, getLangOpts(), TBAA = new CodeGenTBAA(Context, VMContext, CodeGenOpts, getLangOpts(),
getCXXABI().getMangleContext()); getCXXABI().getMangleContext());
@ -735,14 +733,13 @@ void CodeGenModule::SetLLVMFunctionAttributesForDefinition(const Decl *D,
if (!SanitizerBlacklist->isIn(*F)) { if (!SanitizerBlacklist->isIn(*F)) {
// When AddressSanitizer is enabled, set SanitizeAddress attribute // When AddressSanitizer is enabled, set SanitizeAddress attribute
// unless __attribute__((no_sanitize_address)) is used. // unless __attribute__((no_sanitize_address)) is used.
if (SanOpts.Address && !D->hasAttr<NoSanitizeAddressAttr>()) if (LangOpts.Sanitize.Address && !D->hasAttr<NoSanitizeAddressAttr>())
B.addAttribute(llvm::Attribute::SanitizeAddress); B.addAttribute(llvm::Attribute::SanitizeAddress);
// Same for ThreadSanitizer and __attribute__((no_sanitize_thread)) // Same for ThreadSanitizer and __attribute__((no_sanitize_thread))
if (SanOpts.Thread && !D->hasAttr<NoSanitizeThreadAttr>()) { if (LangOpts.Sanitize.Thread && !D->hasAttr<NoSanitizeThreadAttr>())
B.addAttribute(llvm::Attribute::SanitizeThread); B.addAttribute(llvm::Attribute::SanitizeThread);
}
// Same for MemorySanitizer and __attribute__((no_sanitize_memory)) // Same for MemorySanitizer and __attribute__((no_sanitize_memory))
if (SanOpts.Memory && !D->hasAttr<NoSanitizeMemoryAttr>()) if (LangOpts.Sanitize.Memory && !D->hasAttr<NoSanitizeMemoryAttr>())
B.addAttribute(llvm::Attribute::SanitizeMemory); B.addAttribute(llvm::Attribute::SanitizeMemory);
} }
@ -1966,7 +1963,7 @@ void CodeGenModule::EmitGlobalVarDefinition(const VarDecl *D) {
void CodeGenModule::reportGlobalToASan(llvm::GlobalVariable *GV, void CodeGenModule::reportGlobalToASan(llvm::GlobalVariable *GV,
SourceLocation Loc, bool IsDynInit) { SourceLocation Loc, bool IsDynInit) {
if (!SanOpts.Address) if (!LangOpts.Sanitize.Address)
return; return;
IsDynInit &= !SanitizerBlacklist->isIn(*GV, "init"); IsDynInit &= !SanitizerBlacklist->isIn(*GV, "init");
bool IsBlacklisted = SanitizerBlacklist->isIn(*GV); bool IsBlacklisted = SanitizerBlacklist->isIn(*GV);
@ -2796,7 +2793,7 @@ CodeGenModule::GetAddrOfConstantStringFromLiteral(const StringLiteral *S) {
// Mangle the string literal if the ABI allows for it. However, we cannot // Mangle the string literal if the ABI allows for it. However, we cannot
// do this if we are compiling with ASan or -fwritable-strings because they // do this if we are compiling with ASan or -fwritable-strings because they
// rely on strings having normal linkage. // rely on strings having normal linkage.
if (!LangOpts.WritableStrings && !SanOpts.Address && if (!LangOpts.WritableStrings && !LangOpts.Sanitize.Address &&
getCXXABI().getMangleContext().shouldMangleStringLiteral(S)) { getCXXABI().getMangleContext().shouldMangleStringLiteral(S)) {
llvm::raw_svector_ostream Out(MangledNameBuffer); llvm::raw_svector_ostream Out(MangledNameBuffer);
getCXXABI().getMangleContext().mangleStringLiteral(S, Out); getCXXABI().getMangleContext().mangleStringLiteral(S, Out);

View File

@ -475,8 +475,6 @@ class CodeGenModule : public CodeGenTypeCache {
std::unique_ptr<llvm::SpecialCaseList> SanitizerBlacklist; std::unique_ptr<llvm::SpecialCaseList> SanitizerBlacklist;
const SanitizerOptions &SanOpts;
/// @} /// @}
public: public:
CodeGenModule(ASTContext &C, const CodeGenOptions &CodeGenOpts, CodeGenModule(ASTContext &C, const CodeGenOptions &CodeGenOpts,
@ -1014,7 +1012,10 @@ public:
return *SanitizerBlacklist; return *SanitizerBlacklist;
} }
const SanitizerOptions &getSanOpts() const { return SanOpts; } const SanitizerOptions &getSanOpts() const {
return SanitizerBlacklist->isIn(TheModule) ? SanitizerOptions::Disabled
: LangOpts.Sanitize;
}
void reportGlobalToASan(llvm::GlobalVariable *GV, SourceLocation Loc, void reportGlobalToASan(llvm::GlobalVariable *GV, SourceLocation Loc,
bool IsDynInit = false); bool IsDynInit = false);

View File

@ -1,5 +1,7 @@
// RUN: echo "global:*blacklisted_global*" > %t.blacklist // RUN: echo "global:*blacklisted_global*" > %t.blacklist
// RUN: %clang_cc1 -fsanitize=address -fsanitize-blacklist=%t.blacklist -emit-llvm -o - %s | FileCheck %s // RUN: %clang_cc1 -fsanitize=address -fsanitize-blacklist=%t.blacklist -emit-llvm -o - %s | FileCheck %s
// RUN: echo "src:%s" > %t.blacklist-src
// RUN: %clang_cc1 -fsanitize=address -fsanitize-blacklist=%t.blacklist-src -emit-llvm -o - %s | FileCheck %s --check-prefix=BLACKLIST-SRC
// REQUIRES: shell // REQUIRES: shell
int global; int global;
@ -21,3 +23,10 @@ void func() {
// CHECK: ![[BLACKLISTED_GLOBAL]] = metadata !{{{.*}}, null, i1 false, i1 true} // CHECK: ![[BLACKLISTED_GLOBAL]] = metadata !{{{.*}}, null, i1 false, i1 true}
// CHECK: ![[STATIC_VAR]] = metadata !{{{.*}} [[STATIC_LOC]], i1 false, i1 false} // CHECK: ![[STATIC_VAR]] = metadata !{{{.*}} [[STATIC_LOC]], i1 false, i1 false}
// CHECK: ![[LITERAL]] = metadata !{{{.*}} [[LITERAL_LOC]], i1 false, i1 false} // CHECK: ![[LITERAL]] = metadata !{{{.*}} [[LITERAL_LOC]], i1 false, i1 false}
// BLACKLIST-SRC: !llvm.asan.globals = !{![[GLOBAL:[0-9]+]], ![[DYN_INIT_GLOBAL:[0-9]+]], ![[BLACKLISTED_GLOBAL:[0-9]+]], ![[STATIC_VAR:[0-9]+]], ![[LITERAL:[0-9]+]]}
// BLACKLIST-SRC: ![[GLOBAL]] = metadata !{{{.*}} null, i1 false, i1 true}
// BLACKLIST-SRC: ![[DYN_INIT_GLOBAL]] = metadata !{{{.*}} null, i1 true, i1 true}
// BLACKLIST-SRC: ![[BLACKLISTED_GLOBAL]] = metadata !{{{.*}}, null, i1 false, i1 true}
// BLACKLIST-SRC: ![[STATIC_VAR]] = metadata !{{{.*}} null, i1 false, i1 true}
// BLACKLIST-SRC: ![[LITERAL]] = metadata !{{{.*}} null, i1 false, i1 true}