diff --git a/clang/lib/CodeGen/BackendUtil.cpp b/clang/lib/CodeGen/BackendUtil.cpp --- a/clang/lib/CodeGen/BackendUtil.cpp +++ b/clang/lib/CodeGen/BackendUtil.cpp @@ -350,7 +350,8 @@ const PassManagerBuilderWrapper &BuilderWrapper = static_cast(Builder); const LangOptions &LangOpts = BuilderWrapper.getLangOpts(); - PM.add(createDataFlowSanitizerPass(LangOpts.SanitizerBlacklistFiles)); + PM.add( + createDataFlowSanitizerLegacyPassPass(LangOpts.SanitizerBlacklistFiles)); } static TargetLibraryInfoImpl *createTLII(llvm::Triple &TargetTriple, diff --git a/llvm/bindings/go/llvm/InstrumentationBindings.cpp b/llvm/bindings/go/llvm/InstrumentationBindings.cpp --- a/llvm/bindings/go/llvm/InstrumentationBindings.cpp +++ b/llvm/bindings/go/llvm/InstrumentationBindings.cpp @@ -44,5 +44,5 @@ for (int i = 0; i != ABIListFilesNum; ++i) { ABIListFilesVec.push_back(ABIListFiles[i]); } - unwrap(PM)->add(createDataFlowSanitizerPass(ABIListFilesVec)); + unwrap(PM)->add(createDataFlowSanitizerLegacyPassPass(ABIListFilesVec)); } diff --git a/llvm/include/llvm/InitializePasses.h b/llvm/include/llvm/InitializePasses.h --- a/llvm/include/llvm/InitializePasses.h +++ b/llvm/include/llvm/InitializePasses.h @@ -122,7 +122,7 @@ void initializeDAHPass(PassRegistry&); void initializeDCELegacyPassPass(PassRegistry&); void initializeDSELegacyPassPass(PassRegistry&); -void initializeDataFlowSanitizerPass(PassRegistry&); +void initializeDataFlowSanitizerLegacyPassPass(PassRegistry &); void initializeDeadInstEliminationPass(PassRegistry&); void initializeDeadMachineInstructionElimPass(PassRegistry&); void initializeDebugifyMachineModulePass(PassRegistry &); diff --git a/llvm/include/llvm/Transforms/Instrumentation.h b/llvm/include/llvm/Transforms/Instrumentation.h --- a/llvm/include/llvm/Transforms/Instrumentation.h +++ b/llvm/include/llvm/Transforms/Instrumentation.h @@ -143,7 +143,7 @@ ModulePass *createInstrOrderFilePass(); // Insert DataFlowSanitizer (dynamic data flow analysis) instrumentation -ModulePass *createDataFlowSanitizerPass( +ModulePass *createDataFlowSanitizerLegacyPassPass( const std::vector &ABIListFiles = std::vector()); // Options for sanitizer coverage instrumentation. diff --git a/llvm/include/llvm/Transforms/Instrumentation/DataFlowSanitizer.h b/llvm/include/llvm/Transforms/Instrumentation/DataFlowSanitizer.h new file mode 100644 --- /dev/null +++ b/llvm/include/llvm/Transforms/Instrumentation/DataFlowSanitizer.h @@ -0,0 +1,32 @@ +//===- DataFlowSanitizer.h - dynamic data flow analysis -------------------===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// +#ifndef LLVM_TRANSFORMS_INSTRUMENTATION_DATAFLOWSANITIZERPASS_H +#define LLVM_TRANSFORMS_INSTRUMENTATION_DATAFLOWSANITIZERPASS_H + +#include "llvm/IR/Function.h" +#include "llvm/IR/Module.h" +#include "llvm/IR/PassManager.h" +#include +#include + +namespace llvm { + +class DataFlowSanitizerPass : public PassInfoMixin { +private: + std::vector ABIListFiles; + +public: + DataFlowSanitizerPass( + const std::vector &ABIListFiles = std::vector()) + : ABIListFiles(ABIListFiles) {} + PreservedAnalyses run(Module &M, ModuleAnalysisManager &AM); +}; + +} // namespace llvm + +#endif diff --git a/llvm/lib/Passes/PassBuilder.cpp b/llvm/lib/Passes/PassBuilder.cpp --- a/llvm/lib/Passes/PassBuilder.cpp +++ b/llvm/lib/Passes/PassBuilder.cpp @@ -106,6 +106,7 @@ #include "llvm/Transforms/Instrumentation/BoundsChecking.h" #include "llvm/Transforms/Instrumentation/CGProfile.h" #include "llvm/Transforms/Instrumentation/ControlHeightReduction.h" +#include "llvm/Transforms/Instrumentation/DataFlowSanitizer.h" #include "llvm/Transforms/Instrumentation/GCOVProfiler.h" #include "llvm/Transforms/Instrumentation/HWAddressSanitizer.h" #include "llvm/Transforms/Instrumentation/InstrOrderFile.h" diff --git a/llvm/lib/Passes/PassRegistry.def b/llvm/lib/Passes/PassRegistry.def --- a/llvm/lib/Passes/PassRegistry.def +++ b/llvm/lib/Passes/PassRegistry.def @@ -89,6 +89,7 @@ MODULE_PASS("synthetic-counts-propagation", SyntheticCountsPropagation()) MODULE_PASS("wholeprogramdevirt", WholeProgramDevirtPass(nullptr, nullptr)) MODULE_PASS("verify", VerifierPass()) +MODULE_PASS("dfsan", DataFlowSanitizerPass()) MODULE_PASS("asan-module", ModuleAddressSanitizerPass(/*CompileKernel=*/false, false, true, false)) MODULE_PASS("msan-module", MemorySanitizerPass({})) MODULE_PASS("tsan-module", ThreadSanitizerPass()) diff --git a/llvm/lib/Transforms/Instrumentation/DataFlowSanitizer.cpp b/llvm/lib/Transforms/Instrumentation/DataFlowSanitizer.cpp --- a/llvm/lib/Transforms/Instrumentation/DataFlowSanitizer.cpp +++ b/llvm/lib/Transforms/Instrumentation/DataFlowSanitizer.cpp @@ -46,6 +46,7 @@ // //===----------------------------------------------------------------------===// +#include "llvm/Transforms/Instrumentation/DataFlowSanitizer.h" #include "llvm/ADT/DenseMap.h" #include "llvm/ADT/DenseSet.h" #include "llvm/ADT/DepthFirstIterator.h" @@ -78,6 +79,7 @@ #include "llvm/IR/LLVMContext.h" #include "llvm/IR/MDBuilder.h" #include "llvm/IR/Module.h" +#include "llvm/IR/PassManager.h" #include "llvm/IR/Type.h" #include "llvm/IR/User.h" #include "llvm/IR/Value.h" @@ -292,7 +294,7 @@ llvm::makeArrayRef(ArgumentAttributes)); } -class DataFlowSanitizer : public ModulePass { +class DataFlowSanitizer { friend struct DFSanFunction; friend class DFSanVisitor; @@ -390,14 +392,12 @@ void initializeCallbackFunctions(Module &M); void initializeRuntimeFunctions(Module &M); -public: - static char ID; + bool init(Module &M); - DataFlowSanitizer(const std::vector &ABIListFiles = - std::vector()); +public: + DataFlowSanitizer(const std::vector &ABIListFiles); - bool doInitialization(Module &M) override; - bool runOnModule(Module &M) override; + bool runImpl(Module &M); }; struct DFSanFunction { @@ -482,19 +482,8 @@ } // end anonymous namespace -char DataFlowSanitizer::ID; - -INITIALIZE_PASS(DataFlowSanitizer, "dfsan", - "DataFlowSanitizer: dynamic data flow analysis.", false, false) - -ModulePass *llvm::createDataFlowSanitizerPass( - const std::vector &ABIListFiles) { - return new DataFlowSanitizer(ABIListFiles); -} - DataFlowSanitizer::DataFlowSanitizer( - const std::vector &ABIListFiles) - : ModulePass(ID) { + const std::vector &ABIListFiles) { std::vector AllABIListFiles(std::move(ABIListFiles)); AllABIListFiles.insert(AllABIListFiles.end(), ClABIListFiles.begin(), ClABIListFiles.end()); @@ -559,7 +548,7 @@ ArgumentIndexMapping); } -bool DataFlowSanitizer::doInitialization(Module &M) { +bool DataFlowSanitizer::init(Module &M) { Triple TargetTriple(M.getTargetTriple()); bool IsX86_64 = TargetTriple.getArch() == Triple::x86_64; bool IsMIPS64 = TargetTriple.isMIPS64(); @@ -785,7 +774,9 @@ DFSanLoadStoreCmpCallbackFnTy); } -bool DataFlowSanitizer::runOnModule(Module &M) { +bool DataFlowSanitizer::runImpl(Module &M) { + init(M); + if (ABIList.isIn(M, "skip")) return false; @@ -1817,3 +1808,37 @@ DFSF.PHIFixups.push_back(std::make_pair(&PN, ShadowPN)); DFSF.setShadow(&PN, ShadowPN); } + +class DataFlowSanitizerLegacyPass : public ModulePass { +private: + std::vector ABIListFiles; + +public: + static char ID; + + DataFlowSanitizerLegacyPass( + const std::vector &ABIListFiles = std::vector()) + : ModulePass(ID), ABIListFiles(ABIListFiles) {} + + bool runOnModule(Module &M) override { + return DataFlowSanitizer(ABIListFiles).runImpl(M); + } +}; + +char DataFlowSanitizerLegacyPass::ID; + +INITIALIZE_PASS(DataFlowSanitizerLegacyPass, "dfsan", + "DataFlowSanitizer: dynamic data flow analysis.", false, false) + +ModulePass *llvm::createDataFlowSanitizerLegacyPassPass( + const std::vector &ABIListFiles) { + return new DataFlowSanitizerLegacyPass(ABIListFiles); +} + +PreservedAnalyses DataFlowSanitizerPass::run(Module &M, + ModuleAnalysisManager &AM) { + if (DataFlowSanitizer(ABIListFiles).runImpl(M)) { + return PreservedAnalyses::none(); + } + return PreservedAnalyses::all(); +} diff --git a/llvm/lib/Transforms/Instrumentation/Instrumentation.cpp b/llvm/lib/Transforms/Instrumentation/Instrumentation.cpp --- a/llvm/lib/Transforms/Instrumentation/Instrumentation.cpp +++ b/llvm/lib/Transforms/Instrumentation/Instrumentation.cpp @@ -119,7 +119,7 @@ initializeHWAddressSanitizerLegacyPassPass(Registry); initializeThreadSanitizerLegacyPassPass(Registry); initializeModuleSanitizerCoverageLegacyPassPass(Registry); - initializeDataFlowSanitizerPass(Registry); + initializeDataFlowSanitizerLegacyPassPass(Registry); } /// LLVMInitializeInstrumentation - C binding for diff --git a/llvm/test/Instrumentation/DataFlowSanitizer/call.ll b/llvm/test/Instrumentation/DataFlowSanitizer/call.ll --- a/llvm/test/Instrumentation/DataFlowSanitizer/call.ll +++ b/llvm/test/Instrumentation/DataFlowSanitizer/call.ll @@ -1,4 +1,5 @@ ; RUN: opt < %s -dfsan -S | FileCheck %s +; RUN: opt < %s -passes=dfsan -S | FileCheck %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-S128" target triple = "x86_64-unknown-linux-gnu"