From b49d1c1b41a5a918f0cf99b57a9c464698595397 Mon Sep 17 00:00:00 2001 From: Leonard Chan Date: Fri, 26 Oct 2018 22:51:51 +0000 Subject: [PATCH] Revert "[PassManager/Sanitizer] Enable usage of ported AddressSanitizer passes with -fsanitize=address" This reverts commit 8d6af840396f2da2e4ed6aab669214ae25443204 and commit b78d19c287b6e4a9abc9fb0545de9a3106d38d3d which causes slower build times by initializing the AddressSanitizer on every function run. The corresponding revisions are https://reviews.llvm.org/D52814 and https://reviews.llvm.org/D52739. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@345433 91177308-0d34-0410-b5e6-96231b3b80d8 --- include/llvm/InitializePasses.h | 4 +- .../Instrumentation/AddressSanitizerPass.h | 41 ----- lib/Passes/PassBuilder.cpp | 3 +- lib/Passes/PassRegistry.def | 2 - .../Instrumentation/AddressSanitizer.cpp | 180 ++++++++------------- lib/Transforms/Instrumentation/Instrumentation.cpp | 4 +- test/Instrumentation/AddressSanitizer/basic.ll | 2 - 7 files changed, 68 insertions(+), 168 deletions(-) delete mode 100644 include/llvm/Transforms/Instrumentation/AddressSanitizerPass.h diff --git a/include/llvm/InitializePasses.h b/include/llvm/InitializePasses.h index 42bfc55b1aa..1a9c6f82bfd 100644 --- a/include/llvm/InitializePasses.h +++ b/include/llvm/InitializePasses.h @@ -65,8 +65,8 @@ void initializeAAEvalLegacyPassPass(PassRegistry&); void initializeAAResultsWrapperPassPass(PassRegistry&); void initializeADCELegacyPassPass(PassRegistry&); void initializeAddDiscriminatorsLegacyPassPass(PassRegistry&); -void initializeAddressSanitizerModuleLegacyPassPass(PassRegistry &); -void initializeAddressSanitizerLegacyPassPass(PassRegistry &); +void initializeAddressSanitizerModulePass(PassRegistry&); +void initializeAddressSanitizerPass(PassRegistry&); void initializeAggressiveInstCombinerLegacyPassPass(PassRegistry&); void initializeAliasSetPrinterPass(PassRegistry&); void initializeAlignmentFromAssumptionsPass(PassRegistry&); diff --git a/include/llvm/Transforms/Instrumentation/AddressSanitizerPass.h b/include/llvm/Transforms/Instrumentation/AddressSanitizerPass.h deleted file mode 100644 index 021e1bd4c24..00000000000 --- a/include/llvm/Transforms/Instrumentation/AddressSanitizerPass.h +++ /dev/null @@ -1,41 +0,0 @@ -//===--------- Definition of the AddressSanitizer class ---------*- C++ -*-===// -// -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. -// -//===----------------------------------------------------------------------===// -// -// This file declares the AddressSanitizer class which is a port of the legacy -// AddressSanitizer pass to use the new PassManager infrastructure. -// -//===----------------------------------------------------------------------===// -#ifndef LLVM_TRANSFORMS_INSTRUMENTATION_ADDRESSSANITIZERPASS_H -#define LLVM_TRANSFORMS_INSTRUMENTATION_ADDRESSSANITIZERPASS_H - -#include "llvm/IR/Function.h" -#include "llvm/IR/Module.h" -#include "llvm/IR/PassManager.h" - -namespace llvm { - -/// Public interface to the address sanitizer pass for instrumenting code to -/// check for various memory bugs. -class AddressSanitizerPass : public PassInfoMixin { -public: - explicit AddressSanitizerPass(bool CompileKernel = false, - bool Recover = false, - bool UseAfterScope = false); - PreservedAnalyses run(Function &F, FunctionAnalysisManager &AM); - PreservedAnalyses run(Module &M, ModuleAnalysisManager &AM); - -private: - bool CompileKernel; - bool Recover; - bool UseAfterScope; -}; - -} // namespace llvm - -#endif diff --git a/lib/Passes/PassBuilder.cpp b/lib/Passes/PassBuilder.cpp index 90561b05e62..c23c8c8d47a 100644 --- a/lib/Passes/PassBuilder.cpp +++ b/lib/Passes/PassBuilder.cpp @@ -62,6 +62,7 @@ #include "llvm/Support/Regex.h" #include "llvm/Target/TargetMachine.h" #include "llvm/Transforms/AggressiveInstCombine/AggressiveInstCombine.h" +#include "llvm/Transforms/Instrumentation/CGProfile.h" #include "llvm/Transforms/IPO/AlwaysInliner.h" #include "llvm/Transforms/IPO/ArgumentPromotion.h" #include "llvm/Transforms/IPO/CalledValuePropagation.h" @@ -87,9 +88,7 @@ #include "llvm/Transforms/IPO/SyntheticCountsPropagation.h" #include "llvm/Transforms/IPO/WholeProgramDevirt.h" #include "llvm/Transforms/InstCombine/InstCombine.h" -#include "llvm/Transforms/Instrumentation/AddressSanitizerPass.h" #include "llvm/Transforms/Instrumentation/BoundsChecking.h" -#include "llvm/Transforms/Instrumentation/CGProfile.h" #include "llvm/Transforms/Instrumentation/ControlHeightReduction.h" #include "llvm/Transforms/Instrumentation/GCOVProfiler.h" #include "llvm/Transforms/Instrumentation/InstrProfiling.h" diff --git a/lib/Passes/PassRegistry.def b/lib/Passes/PassRegistry.def index ad03942fb9a..8de4541a772 100644 --- a/lib/Passes/PassRegistry.def +++ b/lib/Passes/PassRegistry.def @@ -40,7 +40,6 @@ MODULE_ALIAS_ANALYSIS("globals-aa", GlobalsAA()) #define MODULE_PASS(NAME, CREATE_PASS) #endif MODULE_PASS("always-inline", AlwaysInlinerPass()) -MODULE_PASS("asan", AddressSanitizerPass(false, false, true)) MODULE_PASS("called-value-propagation", CalledValuePropagationPass()) MODULE_PASS("cg-profile", CGProfilePass()) MODULE_PASS("constmerge", ConstantMergePass()) @@ -148,7 +147,6 @@ FUNCTION_PASS("adce", ADCEPass()) FUNCTION_PASS("add-discriminators", AddDiscriminatorsPass()) FUNCTION_PASS("aggressive-instcombine", AggressiveInstCombinePass()) FUNCTION_PASS("alignment-from-assumptions", AlignmentFromAssumptionsPass()) -FUNCTION_PASS("asan", AddressSanitizerPass(false, false, false)) FUNCTION_PASS("bdce", BDCEPass()) FUNCTION_PASS("bounds-checking", BoundsCheckingPass()) FUNCTION_PASS("break-crit-edges", BreakCriticalEdgesPass()) diff --git a/lib/Transforms/Instrumentation/AddressSanitizer.cpp b/lib/Transforms/Instrumentation/AddressSanitizer.cpp index dcbaf7a62f2..42b8179f800 100644 --- a/lib/Transforms/Instrumentation/AddressSanitizer.cpp +++ b/lib/Transforms/Instrumentation/AddressSanitizer.cpp @@ -25,6 +25,7 @@ #include "llvm/ADT/Twine.h" #include "llvm/Analysis/MemoryBuiltins.h" #include "llvm/Analysis/TargetLibraryInfo.h" +#include "llvm/Transforms/Utils/Local.h" #include "llvm/Analysis/ValueTracking.h" #include "llvm/BinaryFormat/MachO.h" #include "llvm/IR/Argument.h" @@ -69,10 +70,8 @@ #include "llvm/Support/ScopedPrinter.h" #include "llvm/Support/raw_ostream.h" #include "llvm/Transforms/Instrumentation.h" -#include "llvm/Transforms/Instrumentation/AddressSanitizerPass.h" #include "llvm/Transforms/Utils/ASanStackFrameLayout.h" #include "llvm/Transforms/Utils/BasicBlockUtils.h" -#include "llvm/Transforms/Utils/Local.h" #include "llvm/Transforms/Utils/ModuleUtils.h" #include "llvm/Transforms/Utils/PromoteMemToReg.h" #include @@ -598,22 +597,26 @@ static size_t RedzoneSizeForScale(int MappingScale) { namespace { /// AddressSanitizer: instrument the code in module to find memory bugs. -struct AddressSanitizer { - explicit AddressSanitizer(Module &M, DominatorTree *DT, - bool CompileKernel = false, bool Recover = false, +struct AddressSanitizer : public FunctionPass { + // Pass identification, replacement for typeid + static char ID; + + explicit AddressSanitizer(bool CompileKernel = false, bool Recover = false, bool UseAfterScope = false) - : UseAfterScope(UseAfterScope || ClUseAfterScope), DT(DT) { + : FunctionPass(ID), UseAfterScope(UseAfterScope || ClUseAfterScope) { this->Recover = ClRecover.getNumOccurrences() > 0 ? ClRecover : Recover; this->CompileKernel = ClEnableKasan.getNumOccurrences() > 0 ? ClEnableKasan : CompileKernel; + initializeAddressSanitizerPass(*PassRegistry::getPassRegistry()); + } + + StringRef getPassName() const override { + return "AddressSanitizerFunctionPass"; + } - // Initialize the private fields. No one has accessed them before. - GlobalsMD.init(M); - C = &(M.getContext()); - LongSize = M.getDataLayout().getPointerSizeInBits(); - IntptrTy = Type::getIntNTy(*C, LongSize); - TargetTriple = Triple(M.getTargetTriple()); - Mapping = getShadowMapping(TargetTriple, LongSize, CompileKernel); + void getAnalysisUsage(AnalysisUsage &AU) const override { + AU.addRequired(); + AU.addRequired(); } uint64_t getAllocaSizeInBytes(const AllocaInst &AI) const { @@ -658,12 +661,12 @@ struct AddressSanitizer { Value *SizeArgument, uint32_t Exp); void instrumentMemIntrinsic(MemIntrinsic *MI); Value *memToShadow(Value *Shadow, IRBuilder<> &IRB); + bool runOnFunction(Function &F) override; bool maybeInsertAsanInitAtFunctionEntry(Function &F); void maybeInsertDynamicShadowAtFunctionEntry(Function &F); void markEscapedLocalAllocas(Function &F); - - /// Return true if the function changed. - bool instrument(Function &F, const TargetLibraryInfo *TLI); + bool doInitialization(Module &M) override; + bool doFinalization(Module &M) override; DominatorTree &getDominatorTree() const { return *DT; } @@ -721,12 +724,16 @@ private: DenseMap ProcessedAllocas; }; -class AddressSanitizerModule { +class AddressSanitizerModule : public ModulePass { public: + // Pass identification, replacement for typeid + static char ID; + explicit AddressSanitizerModule(bool CompileKernel = false, bool Recover = false, bool UseGlobalsGC = true) - : UseGlobalsGC(UseGlobalsGC && ClUseGlobalsGC), + : ModulePass(ID), + UseGlobalsGC(UseGlobalsGC && ClUseGlobalsGC), // Not a typo: ClWithComdat is almost completely pointless without // ClUseGlobalsGC (because then it only works on modules without // globals, which are rare); it is a prerequisite for ClUseGlobalsGC; @@ -735,12 +742,14 @@ public: // ClWithComdat and ClUseGlobalsGC unless the frontend says it's ok to // do globals-gc. UseCtorComdat(UseGlobalsGC && ClWithComdat) { - this->Recover = ClRecover.getNumOccurrences() > 0 ? ClRecover : Recover; - this->CompileKernel = - ClEnableKasan.getNumOccurrences() > 0 ? ClEnableKasan : CompileKernel; - } + this->Recover = ClRecover.getNumOccurrences() > 0 ? + ClRecover : Recover; + this->CompileKernel = ClEnableKasan.getNumOccurrences() > 0 ? + ClEnableKasan : CompileKernel; + } - bool instrument(Module &M); + bool runOnModule(Module &M) override; + StringRef getPassName() const override { return "AddressSanitizerModule"; } private: void initializeCallbacks(Module &M); @@ -1048,102 +1057,18 @@ struct FunctionStackPoisoner : public InstVisitor { Instruction *ThenTerm, Value *ValueIfFalse); }; -class AddressSanitizerLegacyPass : public FunctionPass { -public: - static char ID; - - explicit AddressSanitizerLegacyPass(bool CompileKernel = false, - bool Recover = false, - bool UseAfterScope = false) - : FunctionPass(ID), CompileKernel(CompileKernel), Recover(Recover), - UseAfterScope(UseAfterScope) { - initializeAddressSanitizerLegacyPassPass(*PassRegistry::getPassRegistry()); - } - - StringRef getPassName() const override { - return "AddressSanitizerFunctionPass"; - } - - void getAnalysisUsage(AnalysisUsage &AU) const override { - AU.addRequired(); - AU.addRequired(); - } - - bool runOnFunction(Function &F) override { - DominatorTree *DTree = - &getAnalysis().getDomTree(); - const TargetLibraryInfo *TLI = - &getAnalysis().getTLI(); - AddressSanitizer Sanitizer(*F.getParent(), DTree, CompileKernel, Recover, - UseAfterScope); - return Sanitizer.instrument(F, TLI); - } - -private: - bool CompileKernel; - bool Recover; - bool UseAfterScope; -}; - -class AddressSanitizerModuleLegacyPass : public ModulePass { -public: - static char ID; - - explicit AddressSanitizerModuleLegacyPass(bool CompileKernel = false, - bool Recover = false, - bool UseAfterScope = true) - : ModulePass(ID), CompileKernel(CompileKernel), Recover(Recover), - UseAfterScope(UseAfterScope) {} - - StringRef getPassName() const override { return "AddressSanitizerModule"; } - - bool runOnModule(Module &M) override { - AddressSanitizerModule Sanitizer(CompileKernel, Recover, UseAfterScope); - return Sanitizer.instrument(M); - } - -private: - bool CompileKernel; - bool Recover; - bool UseAfterScope; -}; - } // end anonymous namespace -AddressSanitizerPass::AddressSanitizerPass(bool CompileKernel, bool Recover, - bool UseAfterScope) - : CompileKernel(CompileKernel), Recover(Recover), - UseAfterScope(UseAfterScope) {} - -PreservedAnalyses AddressSanitizerPass::run(Function &F, - AnalysisManager &AM) { - DominatorTree *DT = &AM.getResult(F); - const TargetLibraryInfo *TLI = &AM.getResult(F); - AddressSanitizer Sanitizer(*F.getParent(), DT, CompileKernel, Recover, - UseAfterScope); - if (Sanitizer.instrument(F, TLI)) - return PreservedAnalyses::none(); - return PreservedAnalyses::all(); -} - -PreservedAnalyses AddressSanitizerPass::run(Module &M, - AnalysisManager &AM) { - AddressSanitizerModule Sanitizer(CompileKernel, Recover, UseAfterScope); - if (Sanitizer.instrument(M)) - return PreservedAnalyses::none(); - return PreservedAnalyses::all(); -} - -char AddressSanitizerLegacyPass::ID = 0; +char AddressSanitizer::ID = 0; INITIALIZE_PASS_BEGIN( - AddressSanitizerLegacyPass, "asan", + AddressSanitizer, "asan", "AddressSanitizer: detects use-after-free and out-of-bounds bugs.", false, false) INITIALIZE_PASS_DEPENDENCY(DominatorTreeWrapperPass) INITIALIZE_PASS_DEPENDENCY(TargetLibraryInfoWrapperPass) INITIALIZE_PASS_END( - AddressSanitizerLegacyPass, "asan", + AddressSanitizer, "asan", "AddressSanitizer: detects use-after-free and out-of-bounds bugs.", false, false) @@ -1151,13 +1076,13 @@ FunctionPass *llvm::createAddressSanitizerFunctionPass(bool CompileKernel, bool Recover, bool UseAfterScope) { assert(!CompileKernel || Recover); - return new AddressSanitizerLegacyPass(CompileKernel, Recover, UseAfterScope); + return new AddressSanitizer(CompileKernel, Recover, UseAfterScope); } -char AddressSanitizerModuleLegacyPass::ID = 0; +char AddressSanitizerModule::ID = 0; INITIALIZE_PASS( - AddressSanitizerModuleLegacyPass, "asan-module", + AddressSanitizerModule, "asan-module", "AddressSanitizer: detects use-after-free and out-of-bounds bugs." "ModulePass", false, false) @@ -1166,8 +1091,7 @@ ModulePass *llvm::createAddressSanitizerModulePass(bool CompileKernel, bool Recover, bool UseGlobalsGC) { assert(!CompileKernel || Recover); - return new AddressSanitizerModuleLegacyPass(CompileKernel, Recover, - UseGlobalsGC); + return new AddressSanitizerModule(CompileKernel, Recover, UseGlobalsGC); } static size_t TypeSizeToSizeIndex(uint32_t TypeSize) { @@ -2331,7 +2255,7 @@ int AddressSanitizerModule::GetAsanVersion(const Module &M) const { return Version; } -bool AddressSanitizerModule::instrument(Module &M) { +bool AddressSanitizerModule::runOnModule(Module &M) { C = &(M.getContext()); int LongSize = M.getDataLayout().getPointerSizeInBits(); IntptrTy = Type::getIntNTy(*C, LongSize); @@ -2450,6 +2374,25 @@ void AddressSanitizer::initializeCallbacks(Module &M) { ArrayType::get(IRB.getInt8Ty(), 0)); } +// virtual +bool AddressSanitizer::doInitialization(Module &M) { + // Initialize the private fields. No one has accessed them before. + GlobalsMD.init(M); + + C = &(M.getContext()); + LongSize = M.getDataLayout().getPointerSizeInBits(); + IntptrTy = Type::getIntNTy(*C, LongSize); + TargetTriple = Triple(M.getTargetTriple()); + + Mapping = getShadowMapping(TargetTriple, LongSize, CompileKernel); + return true; +} + +bool AddressSanitizer::doFinalization(Module &M) { + GlobalsMD.reset(); + return false; +} + bool AddressSanitizer::maybeInsertAsanInitAtFunctionEntry(Function &F) { // For each NSObject descendant having a +load method, this method is invoked // by the ObjC runtime before any of the static constructors is called. @@ -2523,7 +2466,7 @@ void AddressSanitizer::markEscapedLocalAllocas(Function &F) { } } -bool AddressSanitizer::instrument(Function &F, const TargetLibraryInfo *TLI) { +bool AddressSanitizer::runOnFunction(Function &F) { if (F.getLinkage() == GlobalValue::AvailableExternallyLinkage) return false; if (!ClDebugFunc.empty() && ClDebugFunc == F.getName()) return false; if (F.getName().startswith("__asan_")) return false; @@ -2542,6 +2485,7 @@ bool AddressSanitizer::instrument(Function &F, const TargetLibraryInfo *TLI) { LLVM_DEBUG(dbgs() << "ASAN instrumenting:\n" << F << "\n"); initializeCallbacks(*F.getParent()); + DT = &getAnalysis().getDomTree(); FunctionStateRAII CleanupObj(this); @@ -2562,6 +2506,8 @@ bool AddressSanitizer::instrument(Function &F, const TargetLibraryInfo *TLI) { bool IsWrite; unsigned Alignment; uint64_t TypeSize; + const TargetLibraryInfo *TLI = + &getAnalysis().getTLI(); // Fill the set of memory operations to instrument. for (auto &BB : F) { diff --git a/lib/Transforms/Instrumentation/Instrumentation.cpp b/lib/Transforms/Instrumentation/Instrumentation.cpp index 55b449ffca1..16976ef90ce 100644 --- a/lib/Transforms/Instrumentation/Instrumentation.cpp +++ b/lib/Transforms/Instrumentation/Instrumentation.cpp @@ -88,8 +88,8 @@ Comdat *llvm::GetOrCreateFunctionComdat(Function &F, /// initializeInstrumentation - Initialize all passes in the TransformUtils /// library. void llvm::initializeInstrumentation(PassRegistry &Registry) { - initializeAddressSanitizerLegacyPassPass(Registry); - initializeAddressSanitizerModuleLegacyPassPass(Registry); + initializeAddressSanitizerPass(Registry); + initializeAddressSanitizerModulePass(Registry); initializeBoundsCheckingLegacyPassPass(Registry); initializeControlHeightReductionLegacyPassPass(Registry); initializeGCOVProfilerLegacyPassPass(Registry); diff --git a/test/Instrumentation/AddressSanitizer/basic.ll b/test/Instrumentation/AddressSanitizer/basic.ll index be80a89392c..099965348eb 100644 --- a/test/Instrumentation/AddressSanitizer/basic.ll +++ b/test/Instrumentation/AddressSanitizer/basic.ll @@ -1,9 +1,7 @@ ; Test basic address sanitizer instrumentation. ; ; RUN: opt < %s -asan -asan-module -S | FileCheck --check-prefixes=CHECK,CHECK-S3 %s -; RUN: opt < %s -passes='function(asan),module(asan)' -S | FileCheck --check-prefixes=CHECK,CHECK-S3 %s ; RUN: opt < %s -asan -asan-module -asan-mapping-scale=5 -S | FileCheck --check-prefixes=CHECK,CHECK-S5 %s -; RUN: opt < %s -passes='function(asan),module(asan)' -asan-mapping-scale=5 -S | FileCheck --check-prefixes=CHECK,CHECK-S5 %s target datalayout = "e-p:64:64:64-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:64:64-f32:32:32-f64:64:64-v64:64:64-v128:128:128-a0:0:64-s0:64:64-f80:128:128-n8:16:32:64" target triple = "x86_64-unknown-linux-gnu" -- 2.11.0