Commit 3b82b92c authored by Peter Collingbourne's avatar Peter Collingbourne
Browse files

hwasan: Initialize the pass only once.

This will let us instrument globals during initialization. This required
making the new PM pass a module pass, which should still provide access to
analyses via the ModuleAnalysisManager.

Differential Revision: https://reviews.llvm.org/D64843

llvm-svn: 366379
parent be4be612
Loading
Loading
Loading
Loading
+10 −28
Original line number Diff line number Diff line
@@ -967,17 +967,6 @@ static void addSanitizersAtO0(ModulePassManager &MPM,
  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 @@ void EmitAssemblyHelper::EmitAssemblyWithNewPassManager(
                  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<GCOVOptions> Options = getGCOVOptions(CodeGenOpts))
        PB.registerPipelineStartEPCallback([Options](ModulePassManager &MPM) {
          MPM.addPass(GCOVProfilerPass(*Options));
@@ -1219,6 +1191,16 @@ void EmitAssemblyHelper::EmitAssemblyWithNewPassManager(
      }
    }

    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);
  }
+1 −1
Original line number Diff line number Diff line
@@ -26,7 +26,7 @@ class HWAddressSanitizerPass : public PassInfoMixin<HWAddressSanitizerPass> {
public:
  explicit HWAddressSanitizerPass(bool CompileKernel = false,
                                  bool Recover = false);
  PreservedAnalyses run(Function &F, FunctionAnalysisManager &FAM);
  PreservedAnalyses run(Module &M, ModuleAnalysisManager &MAM);

private:
  bool CompileKernel;
+2 −2
Original line number Diff line number Diff line
@@ -55,6 +55,8 @@ MODULE_PASS("globaldce", GlobalDCEPass())
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("view-cfg-only", CFGOnlyViewerPass())
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())
+19 −6
Original line number Diff line number Diff line
@@ -277,12 +277,22 @@ public:

  StringRef getPassName() const override { return "HWAddressSanitizer"; }

  bool doInitialization(Module &M) override {
    HWASan = llvm::make_unique<HWAddressSanitizer>(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<HWAddressSanitizer> HWASan;
  bool CompileKernel;
  bool Recover;
};
@@ -309,10 +319,13 @@ FunctionPass *llvm::createHWAddressSanitizerLegacyPassPass(bool CompileKernel,
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();
}
+4 −4
Original line number Diff line number Diff line
@@ -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*) }]