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