diff options
-rw-r--r-- | clang/lib/CodeGen/CGDecl.cpp | 2 | ||||
-rw-r--r-- | clang/lib/CodeGen/CGExpr.cpp | 6 | ||||
-rw-r--r-- | clang/lib/CodeGen/CMakeLists.txt | 1 | ||||
-rw-r--r-- | clang/lib/CodeGen/CodeGenModule.cpp | 73 | ||||
-rw-r--r-- | clang/lib/CodeGen/CodeGenModule.h | 14 | ||||
-rw-r--r-- | clang/lib/CodeGen/SanitizerMetadata.cpp | 88 | ||||
-rw-r--r-- | clang/lib/CodeGen/SanitizerMetadata.h | 47 |
7 files changed, 150 insertions, 81 deletions
diff --git a/clang/lib/CodeGen/CGDecl.cpp b/clang/lib/CodeGen/CGDecl.cpp index b42a44342c4..7caa4b241e3 100644 --- a/clang/lib/CodeGen/CGDecl.cpp +++ b/clang/lib/CodeGen/CGDecl.cpp @@ -345,7 +345,7 @@ void CodeGenFunction::EmitStaticVarDecl(const VarDecl &D, DMEntry = castedAddr; CGM.setStaticLocalDeclAddress(&D, castedAddr); - CGM.reportGlobalToASan(var, D); + CGM.getSanitizerMetadata()->reportGlobalToASan(var, D); // Emit global variable debug descriptor for static vars. CGDebugInfo *DI = getDebugInfo(); diff --git a/clang/lib/CodeGen/CGExpr.cpp b/clang/lib/CodeGen/CGExpr.cpp index 512b323ba10..c83cc0ad970 100644 --- a/clang/lib/CodeGen/CGExpr.cpp +++ b/clang/lib/CodeGen/CGExpr.cpp @@ -2127,7 +2127,7 @@ llvm::Constant *CodeGenFunction::EmitCheckTypeDescriptor(QualType T) { CGM.getModule(), Descriptor->getType(), /*isConstant=*/true, llvm::GlobalVariable::PrivateLinkage, Descriptor); GV->setUnnamedAddr(true); - CGM.disableSanitizerForGlobal(GV); + CGM.getSanitizerMetadata()->disableSanitizerForGlobal(GV); // Remember the descriptor for this type. CGM.setTypeDescriptorInMap(T, GV); @@ -2177,7 +2177,7 @@ llvm::Constant *CodeGenFunction::EmitCheckSourceLocation(SourceLocation Loc) { PresumedLoc PLoc = getContext().getSourceManager().getPresumedLoc(Loc); if (PLoc.isValid()) { auto FilenameGV = CGM.GetAddrOfConstantCString(PLoc.getFilename(), ".src"); - CGM.disableSanitizerForGlobal(FilenameGV); + CGM.getSanitizerMetadata()->disableSanitizerForGlobal(FilenameGV); Filename = FilenameGV; Line = PLoc.getLine(); Column = PLoc.getColumn(); @@ -2224,7 +2224,7 @@ void CodeGenFunction::EmitCheck(llvm::Value *Checked, StringRef CheckName, new llvm::GlobalVariable(CGM.getModule(), Info->getType(), false, llvm::GlobalVariable::PrivateLinkage, Info); InfoPtr->setUnnamedAddr(true); - CGM.disableSanitizerForGlobal(InfoPtr); + CGM.getSanitizerMetadata()->disableSanitizerForGlobal(InfoPtr); SmallVector<llvm::Value *, 4> Args; SmallVector<llvm::Type *, 4> ArgTypes; diff --git a/clang/lib/CodeGen/CMakeLists.txt b/clang/lib/CodeGen/CMakeLists.txt index 00a87d87a29..1adba48aada 100644 --- a/clang/lib/CodeGen/CMakeLists.txt +++ b/clang/lib/CodeGen/CMakeLists.txt @@ -61,6 +61,7 @@ add_clang_library(clangCodeGen MicrosoftCXXABI.cpp ModuleBuilder.cpp SanitizerBlacklist.cpp + SanitizerMetadata.cpp TargetInfo.cpp DEPENDS diff --git a/clang/lib/CodeGen/CodeGenModule.cpp b/clang/lib/CodeGen/CodeGenModule.cpp index 55d47060ff9..33325b24e5a 100644 --- a/clang/lib/CodeGen/CodeGenModule.cpp +++ b/clang/lib/CodeGen/CodeGenModule.cpp @@ -88,7 +88,8 @@ CodeGenModule::CodeGenModule(ASTContext &C, const CodeGenOptions &CGO, BlockObjectDispose(nullptr), BlockDescriptorType(nullptr), GenericBlockLiteralType(nullptr), LifetimeStartFn(nullptr), LifetimeEndFn(nullptr), SanitizerBL(llvm::SpecialCaseList::createOrDie( - CGO.SanitizerBlacklistFile)) { + CGO.SanitizerBlacklistFile)), + SanitizerMD(new SanitizerMetadata(*this)) { // Initialize the type cache. llvm::LLVMContext &LLVMContext = M.getContext(); @@ -1933,7 +1934,7 @@ void CodeGenModule::EmitGlobalVarDefinition(const VarDecl *D) { if (NeedsGlobalCtor || NeedsGlobalDtor) EmitCXXGlobalVarDeclInitFunc(D, GV, NeedsGlobalCtor); - reportGlobalToASan(GV, *D, NeedsGlobalCtor); + SanitizerMD->reportGlobalToASan(GV, *D, NeedsGlobalCtor); // Emit global variable debug information. if (CGDebugInfo *DI = getModuleDebugInfo()) @@ -1941,72 +1942,6 @@ void CodeGenModule::EmitGlobalVarDefinition(const VarDecl *D) { DI->EmitGlobalVariable(GV, D); } -void CodeGenModule::reportGlobalToASan(llvm::GlobalVariable *GV, - SourceLocation Loc, StringRef Name, - bool IsDynInit, bool IsBlacklisted) { - if (!LangOpts.Sanitize.Address) - return; - IsDynInit &= !SanitizerBL.isIn(*GV, "init"); - IsBlacklisted |= SanitizerBL.isIn(*GV); - - llvm::GlobalVariable *LocDescr = nullptr; - llvm::GlobalVariable *GlobalName = nullptr; - if (!IsBlacklisted) { - // Don't generate source location and global name if it is blacklisted - - // it won't be instrumented anyway. - PresumedLoc PLoc = Context.getSourceManager().getPresumedLoc(Loc); - if (PLoc.isValid()) { - llvm::Constant *LocData[] = { - GetAddrOfConstantCString(PLoc.getFilename()), - llvm::ConstantInt::get(llvm::Type::getInt32Ty(VMContext), - PLoc.getLine()), - llvm::ConstantInt::get(llvm::Type::getInt32Ty(VMContext), - PLoc.getColumn()), - }; - auto LocStruct = llvm::ConstantStruct::getAnon(LocData); - LocDescr = new llvm::GlobalVariable(TheModule, LocStruct->getType(), true, - llvm::GlobalValue::PrivateLinkage, - LocStruct, ".asan_loc_descr"); - LocDescr->setUnnamedAddr(true); - // Add LocDescr to llvm.compiler.used, so that it won't be removed by - // the optimizer before the ASan instrumentation pass. - addCompilerUsedGlobal(LocDescr); - } - if (!Name.empty()) { - GlobalName = GetAddrOfConstantCString(Name); - // GlobalName shouldn't be removed by the optimizer. - addCompilerUsedGlobal(GlobalName); - } - } - - llvm::Value *GlobalMetadata[] = { - GV, LocDescr, GlobalName, - llvm::ConstantInt::get(llvm::Type::getInt1Ty(VMContext), IsDynInit), - llvm::ConstantInt::get(llvm::Type::getInt1Ty(VMContext), IsBlacklisted)}; - - llvm::MDNode *ThisGlobal = llvm::MDNode::get(VMContext, GlobalMetadata); - llvm::NamedMDNode *AsanGlobals = - TheModule.getOrInsertNamedMetadata("llvm.asan.globals"); - AsanGlobals->addOperand(ThisGlobal); -} - -void CodeGenModule::reportGlobalToASan(llvm::GlobalVariable *GV, - const VarDecl &D, bool IsDynInit) { - if (!LangOpts.Sanitize.Address) - return; - std::string QualName; - llvm::raw_string_ostream OS(QualName); - D.printQualifiedName(OS); - 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) { // Don't give variables common linkage if -fno-common was specified unless it // was overridden by a NoCommon attribute. @@ -2800,7 +2735,7 @@ CodeGenModule::GetAddrOfConstantStringFromLiteral(const StringLiteral *S) { if (Entry) *Entry = GV; - reportGlobalToASan(GV, S->getStrTokenLoc(0), "<string literal>"); + SanitizerMD->reportGlobalToASan(GV, S->getStrTokenLoc(0), "<string literal>"); return GV; } diff --git a/clang/lib/CodeGen/CodeGenModule.h b/clang/lib/CodeGen/CodeGenModule.h index 9533a8dabb2..326e4c7a290 100644 --- a/clang/lib/CodeGen/CodeGenModule.h +++ b/clang/lib/CodeGen/CodeGenModule.h @@ -17,6 +17,7 @@ #include "CGVTables.h" #include "CodeGenTypes.h" #include "SanitizerBlacklist.h" +#include "SanitizerMetadata.h" #include "clang/AST/Attr.h" #include "clang/AST/DeclCXX.h" #include "clang/AST/DeclObjC.h" @@ -473,6 +474,8 @@ class CodeGenModule : public CodeGenTypeCache { SanitizerBlacklist SanitizerBL; + std::unique_ptr<SanitizerMetadata> SanitizerMD; + /// @} public: CodeGenModule(ASTContext &C, const CodeGenOptions &CodeGenOpts, @@ -1013,14 +1016,9 @@ public: return SanitizerBL; } - void reportGlobalToASan(llvm::GlobalVariable *GV, const VarDecl &D, - bool IsDynInit = false); - void reportGlobalToASan(llvm::GlobalVariable *GV, SourceLocation Loc, - StringRef Name, bool IsDynInit = false, - bool IsBlacklisted = false); - - /// Disable sanitizer instrumentation for this global. - void disableSanitizerForGlobal(llvm::GlobalVariable *GV); + SanitizerMetadata *getSanitizerMetadata() { + return SanitizerMD.get(); + } void addDeferredVTable(const CXXRecordDecl *RD) { DeferredVTables.push_back(RD); diff --git a/clang/lib/CodeGen/SanitizerMetadata.cpp b/clang/lib/CodeGen/SanitizerMetadata.cpp new file mode 100644 index 00000000000..46191523c8b --- /dev/null +++ b/clang/lib/CodeGen/SanitizerMetadata.cpp @@ -0,0 +1,88 @@ +//===--- SanitizerMetadata.cpp - Blacklist for sanitizers -----------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +// +// Class which emits metadata consumed by sanitizer instrumentation passes. +// +//===----------------------------------------------------------------------===// +#include "SanitizerMetadata.h" +#include "CodeGenModule.h" +#include "llvm/ADT/StringRef.h" +#include "llvm/IR/Constants.h" + +using namespace clang; +using namespace CodeGen; + +SanitizerMetadata::SanitizerMetadata(CodeGenModule &CGM) : CGM(CGM) {} + +void SanitizerMetadata::reportGlobalToASan(llvm::GlobalVariable *GV, + SourceLocation Loc, StringRef Name, + bool IsDynInit, bool IsBlacklisted) { + if (!CGM.getLangOpts().Sanitize.Address) + return; + IsDynInit &= !CGM.getSanitizerBlacklist().isIn(*GV, "init"); + IsBlacklisted |= CGM.getSanitizerBlacklist().isIn(*GV); + + llvm::GlobalVariable *LocDescr = nullptr; + llvm::GlobalVariable *GlobalName = nullptr; + llvm::LLVMContext &VMContext = CGM.getLLVMContext(); + if (!IsBlacklisted) { + // Don't generate source location and global name if it is blacklisted - + // it won't be instrumented anyway. + PresumedLoc PLoc = CGM.getContext().getSourceManager().getPresumedLoc(Loc); + if (PLoc.isValid()) { + llvm::Constant *LocData[] = { + CGM.GetAddrOfConstantCString(PLoc.getFilename()), + llvm::ConstantInt::get(llvm::Type::getInt32Ty(VMContext), + PLoc.getLine()), + llvm::ConstantInt::get(llvm::Type::getInt32Ty(VMContext), + PLoc.getColumn()), + }; + auto LocStruct = llvm::ConstantStruct::getAnon(LocData); + LocDescr = new llvm::GlobalVariable( + CGM.getModule(), LocStruct->getType(), true, + llvm::GlobalValue::PrivateLinkage, LocStruct, ".asan_loc_descr"); + LocDescr->setUnnamedAddr(true); + // Add LocDescr to llvm.compiler.used, so that it won't be removed by + // the optimizer before the ASan instrumentation pass. + CGM.addCompilerUsedGlobal(LocDescr); + } + if (!Name.empty()) { + GlobalName = CGM.GetAddrOfConstantCString(Name); + // GlobalName shouldn't be removed by the optimizer. + CGM.addCompilerUsedGlobal(GlobalName); + } + } + + llvm::Value *GlobalMetadata[] = { + GV, LocDescr, GlobalName, + llvm::ConstantInt::get(llvm::Type::getInt1Ty(VMContext), IsDynInit), + llvm::ConstantInt::get(llvm::Type::getInt1Ty(VMContext), IsBlacklisted)}; + + llvm::MDNode *ThisGlobal = llvm::MDNode::get(VMContext, GlobalMetadata); + llvm::NamedMDNode *AsanGlobals = + CGM.getModule().getOrInsertNamedMetadata("llvm.asan.globals"); + AsanGlobals->addOperand(ThisGlobal); +} + +void SanitizerMetadata::reportGlobalToASan(llvm::GlobalVariable *GV, + const VarDecl &D, bool IsDynInit) { + if (!CGM.getLangOpts().Sanitize.Address) + return; + std::string QualName; + llvm::raw_string_ostream OS(QualName); + D.printQualifiedName(OS); + reportGlobalToASan(GV, D.getLocation(), OS.str(), IsDynInit); +} + +void SanitizerMetadata::disableSanitizerForGlobal(llvm::GlobalVariable *GV) { + // For now, just make sure the global is not modified by the ASan + // instrumentation. + if (CGM.getLangOpts().Sanitize.Address) + reportGlobalToASan(GV, SourceLocation(), "", false, true); +} diff --git a/clang/lib/CodeGen/SanitizerMetadata.h b/clang/lib/CodeGen/SanitizerMetadata.h new file mode 100644 index 00000000000..3062b4a62ed --- /dev/null +++ b/clang/lib/CodeGen/SanitizerMetadata.h @@ -0,0 +1,47 @@ +//===--- SanitizerMetadata.h - Metadata for sanitizers ----------*- C++ -*-===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +// +// Class which emits metadata consumed by sanitizer instrumentation passes. +// +//===----------------------------------------------------------------------===// +#ifndef CLANG_CODEGEN_SANITIZERMETADATA_H +#define CLANG_CODEGEN_SANITIZERMETADATA_H + +#include "clang/Basic/LLVM.h" +#include "clang/Basic/SourceLocation.h" + +namespace llvm { +class GlobalVariable; +} + +namespace clang { +class VarDecl; + +namespace CodeGen { + +class CodeGenModule; + +class SanitizerMetadata { + SanitizerMetadata(const SanitizerMetadata &) LLVM_DELETED_FUNCTION; + void operator=(const SanitizerMetadata &) LLVM_DELETED_FUNCTION; + + CodeGenModule &CGM; +public: + SanitizerMetadata(CodeGenModule &CGM); + void reportGlobalToASan(llvm::GlobalVariable *GV, const VarDecl &D, + bool IsDynInit = false); + void reportGlobalToASan(llvm::GlobalVariable *GV, SourceLocation Loc, + StringRef Name, bool IsDynInit = false, + bool IsBlacklisted = false); + void disableSanitizerForGlobal(llvm::GlobalVariable *GV); +}; +} // end namespace CodeGen +} // end namespace clang + +#endif |