summaryrefslogtreecommitdiffstats
path: root/clang/lib
diff options
context:
space:
mode:
authorAlexey Samsonov <vonosmas@gmail.com>2014-10-17 00:20:19 +0000
committerAlexey Samsonov <vonosmas@gmail.com>2014-10-17 00:20:19 +0000
commit1444bb9fc8ff56ae7dc2f9f22fa3518f91dc8d1f (patch)
tree55d7e48eace738256a8fde191acbca84ff7b3514 /clang/lib
parent3514242a660c2a8cd7165ad1831a7c35d8ab9898 (diff)
downloadbcm5719-llvm-1444bb9fc8ff56ae7dc2f9f22fa3518f91dc8d1f.tar.gz
bcm5719-llvm-1444bb9fc8ff56ae7dc2f9f22fa3518f91dc8d1f.zip
SanitizerBlacklist: blacklist functions by their source location.
This commit changes the way we blacklist functions in ASan, TSan, MSan and UBSan. We used to treat function as "blacklisted" and turned off instrumentation in it in two cases: 1) Function is explicitly blacklisted by its mangled name. This part is not changed. 2) Function is located in llvm::Module, whose identifier is contained in the list of blacklisted sources. This is completely wrong, as llvm::Module may not correspond to the actual source file function is defined in. Also, function can be defined in a header, in which case user had to blacklist the .cpp file this header was #include'd into, not the header itself. Such functions could cause other problems - for instance, if the header was included in multiple source files, compiled separately and linked into a single executable, we could end up with both instrumented and non-instrumented version of the same function participating in the same link. After this change we will make blacklisting decision based on the SourceLocation of a function definition. If a function is not explicitly defined in the source file, (for example, the function is compiler-generated and responsible for initialization/destruction of a global variable), then it will be blacklisted if the corresponding global variable is defined in blacklisted source file, and will be instrumented otherwise. After this commit, the active users of blacklist files may have to revisit them. This is a backwards-incompatible change, but I don't think it's possible or makes sense to support the old incorrect behavior. I plan to make similar change for blacklisting GlobalVariables (which is ASan-specific). llvm-svn: 219997
Diffstat (limited to 'clang/lib')
-rw-r--r--clang/lib/Basic/SanitizerBlacklist.cpp6
-rw-r--r--clang/lib/CodeGen/CGDeclCXX.cpp17
-rw-r--r--clang/lib/CodeGen/CGExpr.cpp3
-rw-r--r--clang/lib/CodeGen/CodeGenFunction.cpp2
-rw-r--r--clang/lib/CodeGen/CodeGenModule.cpp20
-rw-r--r--clang/lib/CodeGen/CodeGenModule.h11
-rw-r--r--clang/lib/CodeGen/ItaniumCXXABI.cpp1
-rw-r--r--clang/lib/CodeGen/MicrosoftCXXABI.cpp6
-rw-r--r--clang/lib/CodeGen/SanitizerMetadata.cpp4
9 files changed, 42 insertions, 28 deletions
diff --git a/clang/lib/Basic/SanitizerBlacklist.cpp b/clang/lib/Basic/SanitizerBlacklist.cpp
index f0221331ed2..2f4bdb51138 100644
--- a/clang/lib/Basic/SanitizerBlacklist.cpp
+++ b/clang/lib/Basic/SanitizerBlacklist.cpp
@@ -12,7 +12,6 @@
//
//===----------------------------------------------------------------------===//
#include "clang/Basic/SanitizerBlacklist.h"
-#include "llvm/IR/Function.h"
#include "llvm/IR/GlobalValue.h"
#include "llvm/IR/Module.h"
@@ -33,11 +32,6 @@ SanitizerBlacklist::SanitizerBlacklist(StringRef BlacklistPath,
SourceManager &SM)
: SCL(llvm::SpecialCaseList::createOrDie(BlacklistPath)), SM(SM) {}
-bool SanitizerBlacklist::isIn(const llvm::Function &F) const {
- return isBlacklistedFile(F.getParent()->getModuleIdentifier()) ||
- isBlacklistedFunction(F.getName());
-}
-
bool SanitizerBlacklist::isIn(const llvm::GlobalVariable &G,
StringRef Category) const {
return isBlacklistedFile(G.getParent()->getModuleIdentifier(), Category) ||
diff --git a/clang/lib/CodeGen/CGDeclCXX.cpp b/clang/lib/CodeGen/CGDeclCXX.cpp
index dcfc45ff84f..0ba4ea5d335 100644
--- a/clang/lib/CodeGen/CGDeclCXX.cpp
+++ b/clang/lib/CodeGen/CGDeclCXX.cpp
@@ -167,7 +167,8 @@ llvm::Constant *CodeGenFunction::createAtExitStub(const VarDecl &VD,
llvm::raw_svector_ostream Out(FnName);
CGM.getCXXABI().getMangleContext().mangleDynamicAtExitDestructor(&VD, Out);
}
- llvm::Function *fn = CGM.CreateGlobalInitOrDestructFunction(ty, FnName.str());
+ llvm::Function *fn = CGM.CreateGlobalInitOrDestructFunction(ty, FnName.str(),
+ VD.getLocation());
CodeGenFunction CGF(CGM);
@@ -219,9 +220,8 @@ void CodeGenFunction::EmitCXXGuardedInit(const VarDecl &D,
CGM.getCXXABI().EmitGuardedInit(*this, D, DeclPtr, PerformInit);
}
-llvm::Function *
-CodeGenModule::CreateGlobalInitOrDestructFunction(llvm::FunctionType *FTy,
- const Twine &Name, bool TLS) {
+llvm::Function *CodeGenModule::CreateGlobalInitOrDestructFunction(
+ llvm::FunctionType *FTy, const Twine &Name, SourceLocation Loc, bool TLS) {
llvm::Function *Fn =
llvm::Function::Create(FTy, llvm::GlobalValue::InternalLinkage,
Name, &getModule());
@@ -236,7 +236,7 @@ CodeGenModule::CreateGlobalInitOrDestructFunction(llvm::FunctionType *FTy,
if (!getLangOpts().Exceptions)
Fn->setDoesNotThrow();
- if (!getSanitizerBlacklist().isIn(*Fn)) {
+ if (!isInSanitizerBlacklist(Fn, Loc)) {
if (getLangOpts().Sanitize.Address)
Fn->addFnAttr(llvm::Attribute::SanitizeAddress);
if (getLangOpts().Sanitize.Thread)
@@ -286,7 +286,8 @@ CodeGenModule::EmitCXXGlobalVarDeclInitFunc(const VarDecl *D,
}
// Create a variable initialization function.
- llvm::Function *Fn = CreateGlobalInitOrDestructFunction(FTy, FnName.str());
+ llvm::Function *Fn =
+ CreateGlobalInitOrDestructFunction(FTy, FnName.str(), D->getLocation());
auto *ISA = D->getAttr<InitSegAttr>();
CodeGenFunction(*this).GenerateCXXGlobalVarDeclInitFunc(Fn, D, Addr,
@@ -552,8 +553,8 @@ llvm::Function *CodeGenFunction::generateDestroyHelper(
const CGFunctionInfo &FI = CGM.getTypes().arrangeFreeFunctionDeclaration(
getContext().VoidTy, args, FunctionType::ExtInfo(), /*variadic=*/false);
llvm::FunctionType *FTy = CGM.getTypes().GetFunctionType(FI);
- llvm::Function *fn =
- CGM.CreateGlobalInitOrDestructFunction(FTy, "__cxx_global_array_dtor");
+ llvm::Function *fn = CGM.CreateGlobalInitOrDestructFunction(
+ FTy, "__cxx_global_array_dtor", VD->getLocation());
StartFunction(VD, getContext().VoidTy, fn, FI, args);
diff --git a/clang/lib/CodeGen/CGExpr.cpp b/clang/lib/CodeGen/CGExpr.cpp
index 927b163d605..32b2e2cc587 100644
--- a/clang/lib/CodeGen/CGExpr.cpp
+++ b/clang/lib/CodeGen/CGExpr.cpp
@@ -552,7 +552,8 @@ void CodeGenFunction::EmitTypeCheck(TypeCheckKind TCK, SourceLocation Loc,
Out);
// Blacklist based on the mangled type.
- if (!CGM.getSanitizerBlacklist().isBlacklistedType(Out.str())) {
+ if (!CGM.getContext().getSanitizerBlacklist().isBlacklistedType(
+ Out.str())) {
llvm::hash_code TypeHash = hash_value(Out.str());
// Load the vptr, and compute hash_16_bytes(TypeHash, vptr).
diff --git a/clang/lib/CodeGen/CodeGenFunction.cpp b/clang/lib/CodeGen/CodeGenFunction.cpp
index f9e6c397d93..1fc4571aadb 100644
--- a/clang/lib/CodeGen/CodeGenFunction.cpp
+++ b/clang/lib/CodeGen/CodeGenFunction.cpp
@@ -579,7 +579,7 @@ void CodeGenFunction::StartFunction(GlobalDecl GD,
CurFnInfo = &FnInfo;
assert(CurFn->isDeclaration() && "Function already has body?");
- if (CGM.getSanitizerBlacklist().isIn(*Fn))
+ if (CGM.isInSanitizerBlacklist(Fn, Loc))
SanOpts = &SanitizerOptions::Disabled;
// Pass inline keyword to optimizer if it appears explicitly on any
diff --git a/clang/lib/CodeGen/CodeGenModule.cpp b/clang/lib/CodeGen/CodeGenModule.cpp
index 78a2631a366..c5afaa19e9b 100644
--- a/clang/lib/CodeGen/CodeGenModule.cpp
+++ b/clang/lib/CodeGen/CodeGenModule.cpp
@@ -740,7 +740,7 @@ void CodeGenModule::SetLLVMFunctionAttributesForDefinition(const Decl *D,
B.addAttribute(llvm::Attribute::StackProtectReq);
// Add sanitizer attributes if function is not blacklisted.
- if (!getSanitizerBlacklist().isIn(*F)) {
+ if (!isInSanitizerBlacklist(F, D->getLocation())) {
// When AddressSanitizer is enabled, set SanitizeAddress attribute
// unless __attribute__((no_sanitize_address)) is used.
if (LangOpts.Sanitize.Address && !D->hasAttr<NoSanitizeAddressAttr>())
@@ -1168,6 +1168,24 @@ void CodeGenModule::AddGlobalAnnotations(const ValueDecl *D,
Annotations.push_back(EmitAnnotateAttr(GV, I, D->getLocation()));
}
+bool CodeGenModule::isInSanitizerBlacklist(llvm::Function *Fn,
+ SourceLocation Loc) const {
+ const auto &SanitizerBL = getContext().getSanitizerBlacklist();
+ // Blacklist by function name.
+ if (SanitizerBL.isBlacklistedFunction(Fn->getName()))
+ return true;
+ // Blacklist by location.
+ if (!Loc.isInvalid())
+ return SanitizerBL.isBlacklistedLocation(Loc);
+ // If location is unknown, this may be a compiler-generated function. Assume
+ // it's located in the main file.
+ auto &SM = Context.getSourceManager();
+ if (const auto *MainFile = SM.getFileEntryForID(SM.getMainFileID())) {
+ return SanitizerBL.isBlacklistedFile(MainFile->getName());
+ }
+ return false;
+}
+
bool CodeGenModule::MayDeferGeneration(const ValueDecl *Global) {
// Never defer when EmitAllDecls is specified.
if (LangOpts.EmitAllDecls)
diff --git a/clang/lib/CodeGen/CodeGenModule.h b/clang/lib/CodeGen/CodeGenModule.h
index a63b799baa7..546e59309e0 100644
--- a/clang/lib/CodeGen/CodeGenModule.h
+++ b/clang/lib/CodeGen/CodeGenModule.h
@@ -686,9 +686,10 @@ public:
CreateOrReplaceCXXRuntimeVariable(StringRef Name, llvm::Type *Ty,
llvm::GlobalValue::LinkageTypes Linkage);
- llvm::Function *CreateGlobalInitOrDestructFunction(llvm::FunctionType *ty,
- const Twine &name,
- bool TLS = false);
+ llvm::Function *
+ CreateGlobalInitOrDestructFunction(llvm::FunctionType *ty, const Twine &name,
+ SourceLocation Loc = SourceLocation(),
+ bool TLS = false);
/// Return the address space of the underlying global variable for D, as
/// determined by its declaration. Normally this is the same as the address
@@ -1045,9 +1046,7 @@ public:
/// annotations are emitted during finalization of the LLVM code.
void AddGlobalAnnotations(const ValueDecl *D, llvm::GlobalValue *GV);
- const SanitizerBlacklist &getSanitizerBlacklist() const {
- return Context.getSanitizerBlacklist();
- }
+ bool isInSanitizerBlacklist(llvm::Function *Fn, SourceLocation Loc) const;
SanitizerMetadata *getSanitizerMetadata() {
return SanitizerMD.get();
diff --git a/clang/lib/CodeGen/ItaniumCXXABI.cpp b/clang/lib/CodeGen/ItaniumCXXABI.cpp
index 824eba9fdb1..eb5fbab4381 100644
--- a/clang/lib/CodeGen/ItaniumCXXABI.cpp
+++ b/clang/lib/CodeGen/ItaniumCXXABI.cpp
@@ -1912,6 +1912,7 @@ void ItaniumCXXABI::EmitThreadLocalInitFuncs(
llvm::FunctionType *FTy =
llvm::FunctionType::get(CGM.VoidTy, /*isVarArg=*/false);
InitFunc = CGM.CreateGlobalInitOrDestructFunction(FTy, "__tls_init",
+ SourceLocation(),
/*TLS=*/true);
llvm::GlobalVariable *Guard = new llvm::GlobalVariable(
CGM.getModule(), CGM.Int8Ty, /*isConstant=*/false,
diff --git a/clang/lib/CodeGen/MicrosoftCXXABI.cpp b/clang/lib/CodeGen/MicrosoftCXXABI.cpp
index 9ea26336908..dd0846958fa 100644
--- a/clang/lib/CodeGen/MicrosoftCXXABI.cpp
+++ b/clang/lib/CodeGen/MicrosoftCXXABI.cpp
@@ -1796,9 +1796,9 @@ void MicrosoftCXXABI::EmitThreadLocalInitFuncs(
if (!NonComdatInits.empty()) {
llvm::FunctionType *FTy =
llvm::FunctionType::get(CGM.VoidTy, /*isVarArg=*/false);
- llvm::Function *InitFunc =
- CGM.CreateGlobalInitOrDestructFunction(FTy, "__tls_init",
- /*TLS=*/true);
+ llvm::Function *InitFunc = CGM.CreateGlobalInitOrDestructFunction(
+ FTy, "__tls_init", SourceLocation(),
+ /*TLS=*/true);
CodeGenFunction(CGM).GenerateCXXGlobalInitFunc(InitFunc, NonComdatInits);
AddToXDU(InitFunc);
diff --git a/clang/lib/CodeGen/SanitizerMetadata.cpp b/clang/lib/CodeGen/SanitizerMetadata.cpp
index 2a2b0ed9419..69c20b80a8e 100644
--- a/clang/lib/CodeGen/SanitizerMetadata.cpp
+++ b/clang/lib/CodeGen/SanitizerMetadata.cpp
@@ -25,8 +25,8 @@ void SanitizerMetadata::reportGlobalToASan(llvm::GlobalVariable *GV,
bool IsDynInit, bool IsBlacklisted) {
if (!CGM.getLangOpts().Sanitize.Address)
return;
- IsDynInit &= !CGM.getSanitizerBlacklist().isIn(*GV, "init");
- IsBlacklisted |= CGM.getSanitizerBlacklist().isIn(*GV);
+ IsDynInit &= !CGM.getContext().getSanitizerBlacklist().isIn(*GV, "init");
+ IsBlacklisted |= CGM.getContext().getSanitizerBlacklist().isIn(*GV);
llvm::Value *LocDescr = nullptr;
llvm::Value *GlobalName = nullptr;
OpenPOWER on IntegriCloud