1 //===--------- Definition of the AddressSanitizer class ---------*- C++ -*-===// 2 // 3 // The LLVM Compiler Infrastructure 4 // 5 // This file is distributed under the University of Illinois Open Source 6 // License. See LICENSE.TXT for details. 7 // 8 //===----------------------------------------------------------------------===// 9 // 10 // This file declares the AddressSanitizer class which is a port of the legacy 11 // AddressSanitizer pass to use the new PassManager infrastructure. 12 // 13 //===----------------------------------------------------------------------===// 14 #ifndef LLVM_TRANSFORMS_INSTRUMENTATION_ADDRESSSANITIZERPASS_H 15 #define LLVM_TRANSFORMS_INSTRUMENTATION_ADDRESSSANITIZERPASS_H 16 17 #include "llvm/IR/Function.h" 18 #include "llvm/IR/Module.h" 19 #include "llvm/IR/PassManager.h" 20 21 namespace llvm { 22 23 /// Frontend-provided metadata for source location. 24 struct LocationMetadata { 25 StringRef Filename; 26 int LineNo = 0; 27 int ColumnNo = 0; 28 29 LocationMetadata() = default; 30 31 bool empty() const { return Filename.empty(); } 32 void parse(MDNode *MDN); 33 }; 34 35 /// Frontend-provided metadata for global variables. 36 class GlobalsMetadata { 37 public: 38 struct Entry { 39 LocationMetadata SourceLoc; 40 StringRef Name; 41 bool IsDynInit = false; 42 bool IsBlacklisted = false; 43 44 Entry() = default; 45 }; 46 47 /// Create a default uninitialized GlobalsMetadata instance. 48 GlobalsMetadata() = default; 49 50 /// Create an initialized GlobalsMetadata instance. 51 GlobalsMetadata(Module &M); 52 53 /// Returns metadata entry for a given global. 54 Entry get(GlobalVariable *G) const { 55 auto Pos = Entries.find(G); 56 return (Pos != Entries.end()) ? Pos->second : Entry(); 57 } 58 59 /// Handle invalidation from the pass manager. 60 /// These results are never invalidated. 61 bool invalidate(Module &, const PreservedAnalyses &, 62 ModuleAnalysisManager::Invalidator &) { 63 return false; 64 } 65 bool invalidate(Function &, const PreservedAnalyses &, 66 FunctionAnalysisManager::Invalidator &) { 67 return false; 68 } 69 70 private: 71 DenseMap<GlobalVariable *, Entry> Entries; 72 }; 73 74 /// The ASanGlobalsMetadataAnalysis initializes and returns a GlobalsMetadata 75 /// object. More specifically, ASan requires looking at all globals registered 76 /// in 'llvm.asan.globals' before running, which only depends on reading module 77 /// level metadata. This analysis is required to run before running the 78 /// AddressSanitizerPass since it collects that metadata. 79 /// The legacy pass manager equivalent of this is ASanGlobalsMetadataLegacyPass. 80 class ASanGlobalsMetadataAnalysis 81 : public AnalysisInfoMixin<ASanGlobalsMetadataAnalysis> { 82 public: 83 using Result = GlobalsMetadata; 84 85 Result run(Module &, ModuleAnalysisManager &); 86 87 private: 88 friend AnalysisInfoMixin<ASanGlobalsMetadataAnalysis>; 89 static AnalysisKey Key; 90 }; 91 92 /// Public interface to the address sanitizer pass for instrumenting code to 93 /// check for various memory errors at runtime. 94 /// 95 /// The sanitizer itself is a function pass that works by inserting various 96 /// calls to the ASan runtime library functions. The runtime library essentially 97 /// replaces malloc() and free() with custom implementations that allow regions 98 /// surrounding requested memory to be checked for invalid accesses. 99 class AddressSanitizerPass : public PassInfoMixin<AddressSanitizerPass> { 100 public: 101 explicit AddressSanitizerPass(bool CompileKernel = false, 102 bool Recover = false, 103 bool UseAfterScope = false); 104 PreservedAnalyses run(Function &F, FunctionAnalysisManager &AM); 105 106 private: 107 bool CompileKernel; 108 bool Recover; 109 bool UseAfterScope; 110 }; 111 112 /// Public interface to the address sanitizer module pass for instrumenting code 113 /// to check for various memory errors. 114 /// 115 /// This adds 'asan.module_ctor' to 'llvm.global_ctors'. This pass may also 116 /// run intependently of the function address sanitizer. 117 class ModuleAddressSanitizerPass 118 : public PassInfoMixin<ModuleAddressSanitizerPass> { 119 public: 120 explicit ModuleAddressSanitizerPass(bool CompileKernel = false, 121 bool Recover = false, 122 bool UseGlobalGC = true, 123 bool UseOdrIndicator = false); 124 PreservedAnalyses run(Module &M, ModuleAnalysisManager &AM); 125 126 private: 127 bool CompileKernel; 128 bool Recover; 129 bool UseGlobalGC; 130 bool UseOdrIndicator; 131 }; 132 133 // Insert AddressSanitizer (address sanity checking) instrumentation 134 FunctionPass *createAddressSanitizerFunctionPass(bool CompileKernel = false, 135 bool Recover = false, 136 bool UseAfterScope = false); 137 ModulePass *createModuleAddressSanitizerLegacyPassPass( 138 bool CompileKernel = false, bool Recover = false, bool UseGlobalsGC = true, 139 bool UseOdrIndicator = true); 140 141 } // namespace llvm 142 143 #endif 144