Index: cfe/trunk/lib/CodeGen/BackendUtil.cpp =================================================================== --- cfe/trunk/lib/CodeGen/BackendUtil.cpp +++ cfe/trunk/lib/CodeGen/BackendUtil.cpp @@ -967,17 +967,6 @@ if (LangOpts.Sanitize.has(SanitizerKind::Thread)) { MPM.addPass(createModuleToFunctionPassAdaptor(ThreadSanitizerPass())); } - - if (LangOpts.Sanitize.has(SanitizerKind::HWAddress)) { - bool Recover = CodeGenOpts.SanitizeRecover.has(SanitizerKind::HWAddress); - MPM.addPass(createModuleToFunctionPassAdaptor( - HWAddressSanitizerPass(/*CompileKernel=*/false, Recover))); - } - - if (LangOpts.Sanitize.has(SanitizerKind::KernelHWAddress)) { - MPM.addPass(createModuleToFunctionPassAdaptor( - HWAddressSanitizerPass(/*CompileKernel=*/true, /*Recover=*/true))); - } } /// A clean version of `EmitAssembly` that uses the new pass manager. @@ -1176,23 +1165,6 @@ UseOdrIndicator)); }); } - if (LangOpts.Sanitize.has(SanitizerKind::HWAddress)) { - bool Recover = - CodeGenOpts.SanitizeRecover.has(SanitizerKind::HWAddress); - PB.registerOptimizerLastEPCallback( - [Recover](FunctionPassManager &FPM, - PassBuilder::OptimizationLevel Level) { - FPM.addPass(HWAddressSanitizerPass( - /*CompileKernel=*/false, Recover)); - }); - } - if (LangOpts.Sanitize.has(SanitizerKind::KernelHWAddress)) { - PB.registerOptimizerLastEPCallback( - [](FunctionPassManager &FPM, PassBuilder::OptimizationLevel Level) { - FPM.addPass(HWAddressSanitizerPass( - /*CompileKernel=*/true, /*Recover=*/true)); - }); - } if (Optional Options = getGCOVOptions(CodeGenOpts)) PB.registerPipelineStartEPCallback([Options](ModulePassManager &MPM) { MPM.addPass(GCOVProfilerPass(*Options)); @@ -1219,6 +1191,16 @@ } } + if (LangOpts.Sanitize.has(SanitizerKind::HWAddress)) { + bool Recover = CodeGenOpts.SanitizeRecover.has(SanitizerKind::HWAddress); + MPM.addPass(HWAddressSanitizerPass( + /*CompileKernel=*/false, Recover)); + } + if (LangOpts.Sanitize.has(SanitizerKind::KernelHWAddress)) { + MPM.addPass(HWAddressSanitizerPass( + /*CompileKernel=*/true, /*Recover=*/true)); + } + if (CodeGenOpts.OptimizationLevel == 0) addSanitizersAtO0(MPM, TargetTriple, LangOpts, CodeGenOpts); } Index: llvm/trunk/include/llvm/Transforms/Instrumentation/HWAddressSanitizer.h =================================================================== --- llvm/trunk/include/llvm/Transforms/Instrumentation/HWAddressSanitizer.h +++ llvm/trunk/include/llvm/Transforms/Instrumentation/HWAddressSanitizer.h @@ -26,7 +26,7 @@ public: explicit HWAddressSanitizerPass(bool CompileKernel = false, bool Recover = false); - PreservedAnalyses run(Function &F, FunctionAnalysisManager &FAM); + PreservedAnalyses run(Module &M, ModuleAnalysisManager &MAM); private: bool CompileKernel; Index: llvm/trunk/lib/Passes/PassRegistry.def =================================================================== --- llvm/trunk/lib/Passes/PassRegistry.def +++ llvm/trunk/lib/Passes/PassRegistry.def @@ -55,6 +55,8 @@ MODULE_PASS("globalopt", GlobalOptPass()) MODULE_PASS("globalsplit", GlobalSplitPass()) MODULE_PASS("hotcoldsplit", HotColdSplittingPass()) +MODULE_PASS("hwasan", HWAddressSanitizerPass(false, false)) +MODULE_PASS("khwasan", HWAddressSanitizerPass(true, true)) MODULE_PASS("inferattrs", InferFunctionAttrsPass()) MODULE_PASS("insert-gcov-profiling", GCOVProfilerPass()) MODULE_PASS("instrorderfile", InstrOrderFilePass()) @@ -240,8 +242,6 @@ FUNCTION_PASS("transform-warning", WarnMissedTransformationsPass()) FUNCTION_PASS("asan", AddressSanitizerPass(false, false, false)) FUNCTION_PASS("kasan", AddressSanitizerPass(true, false, false)) -FUNCTION_PASS("hwasan", HWAddressSanitizerPass(false, false)) -FUNCTION_PASS("khwasan", HWAddressSanitizerPass(true, true)) FUNCTION_PASS("msan", MemorySanitizerPass({})) FUNCTION_PASS("kmsan", MemorySanitizerPass({0, false, /*Kernel=*/true})) FUNCTION_PASS("tsan", ThreadSanitizerPass()) Index: llvm/trunk/lib/Transforms/Instrumentation/HWAddressSanitizer.cpp =================================================================== --- llvm/trunk/lib/Transforms/Instrumentation/HWAddressSanitizer.cpp +++ llvm/trunk/lib/Transforms/Instrumentation/HWAddressSanitizer.cpp @@ -277,12 +277,22 @@ StringRef getPassName() const override { return "HWAddressSanitizer"; } + bool doInitialization(Module &M) override { + HWASan = llvm::make_unique(M, CompileKernel, Recover); + return true; + } + bool runOnFunction(Function &F) override { - HWAddressSanitizer HWASan(*F.getParent(), CompileKernel, Recover); - return HWASan.sanitizeFunction(F); + return HWASan->sanitizeFunction(F); + } + + bool doFinalization(Module &M) override { + HWASan.reset(); + return false; } private: + std::unique_ptr HWASan; bool CompileKernel; bool Recover; }; @@ -309,10 +319,13 @@ HWAddressSanitizerPass::HWAddressSanitizerPass(bool CompileKernel, bool Recover) : CompileKernel(CompileKernel), Recover(Recover) {} -PreservedAnalyses HWAddressSanitizerPass::run(Function &F, - FunctionAnalysisManager &FAM) { - HWAddressSanitizer HWASan(*F.getParent(), CompileKernel, Recover); - if (HWASan.sanitizeFunction(F)) +PreservedAnalyses HWAddressSanitizerPass::run(Module &M, + ModuleAnalysisManager &MAM) { + HWAddressSanitizer HWASan(M, CompileKernel, Recover); + bool Modified = false; + for (Function &F : M) + Modified |= HWASan.sanitizeFunction(F); + if (Modified) return PreservedAnalyses::none(); return PreservedAnalyses::all(); } Index: llvm/trunk/test/Instrumentation/HWAddressSanitizer/basic.ll =================================================================== --- llvm/trunk/test/Instrumentation/HWAddressSanitizer/basic.ll +++ llvm/trunk/test/Instrumentation/HWAddressSanitizer/basic.ll @@ -6,10 +6,10 @@ ; RUN: opt < %s -hwasan -hwasan-recover=1 -hwasan-mapping-offset=0 -S | FileCheck %s --check-prefixes=CHECK,RECOVER,RECOVER-ZERO-BASED-SHADOW ; Ensure than hwasan runs with the new PM pass -; RUN: opt < %s -passes='function(hwasan)' -hwasan-recover=0 -hwasan-with-ifunc=1 -hwasan-with-tls=0 -S | FileCheck %s --check-prefixes=CHECK,ABORT,ABORT-DYNAMIC-SHADOW -; RUN: opt < %s -passes='function(hwasan)' -hwasan-recover=1 -hwasan-with-ifunc=1 -hwasan-with-tls=0 -S | FileCheck %s --check-prefixes=CHECK,RECOVER,RECOVER-DYNAMIC-SHADOW -; RUN: opt < %s -passes='function(hwasan)' -hwasan-recover=0 -hwasan-mapping-offset=0 -S | FileCheck %s --check-prefixes=CHECK,ABORT,ABORT-ZERO-BASED-SHADOW -; RUN: opt < %s -passes='function(hwasan)' -hwasan-recover=1 -hwasan-mapping-offset=0 -S | FileCheck %s --check-prefixes=CHECK,RECOVER,RECOVER-ZERO-BASED-SHADOW +; RUN: opt < %s -passes=hwasan -hwasan-recover=0 -hwasan-with-ifunc=1 -hwasan-with-tls=0 -S | FileCheck %s --check-prefixes=CHECK,ABORT,ABORT-DYNAMIC-SHADOW +; RUN: opt < %s -passes=hwasan -hwasan-recover=1 -hwasan-with-ifunc=1 -hwasan-with-tls=0 -S | FileCheck %s --check-prefixes=CHECK,RECOVER,RECOVER-DYNAMIC-SHADOW +; RUN: opt < %s -passes=hwasan -hwasan-recover=0 -hwasan-mapping-offset=0 -S | FileCheck %s --check-prefixes=CHECK,ABORT,ABORT-ZERO-BASED-SHADOW +; RUN: opt < %s -passes=hwasan -hwasan-recover=1 -hwasan-mapping-offset=0 -S | FileCheck %s --check-prefixes=CHECK,RECOVER,RECOVER-ZERO-BASED-SHADOW ; CHECK: @llvm.global_ctors = appending global [1 x { i32, void ()*, i8* }] [{ i32, void ()*, i8* } { i32 0, void ()* @hwasan.module_ctor, i8* bitcast (void ()* @hwasan.module_ctor to i8*) }]