File: | lib/Transforms/Instrumentation/SanitizerCoverage.cpp |
Location: | line 254, column 13 |
Description: | Function call argument is an uninitialized value |
1 | //===-- SanitizerCoverage.cpp - coverage instrumentation for sanitizers ---===// | |||
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 | // Coverage instrumentation that works with AddressSanitizer | |||
11 | // and potentially with other Sanitizers. | |||
12 | // | |||
13 | // We create a Guard variable with the same linkage | |||
14 | // as the function and inject this code into the entry block (CoverageLevel=1) | |||
15 | // or all blocks (CoverageLevel>=2): | |||
16 | // if (Guard < 0) { | |||
17 | // __sanitizer_cov(&Guard); | |||
18 | // } | |||
19 | // The accesses to Guard are atomic. The rest of the logic is | |||
20 | // in __sanitizer_cov (it's fine to call it more than once). | |||
21 | // | |||
22 | // With CoverageLevel>=3 we also split critical edges this effectively | |||
23 | // instrumenting all edges. | |||
24 | // | |||
25 | // CoverageLevel>=4 add indirect call profiling implented as a function call. | |||
26 | // | |||
27 | // This coverage implementation provides very limited data: | |||
28 | // it only tells if a given function (block) was ever executed. No counters. | |||
29 | // But for many use cases this is what we need and the added slowdown small. | |||
30 | // | |||
31 | //===----------------------------------------------------------------------===// | |||
32 | ||||
33 | #include "llvm/Transforms/Instrumentation.h" | |||
34 | #include "llvm/ADT/ArrayRef.h" | |||
35 | #include "llvm/ADT/SmallVector.h" | |||
36 | #include "llvm/IR/CallSite.h" | |||
37 | #include "llvm/IR/DataLayout.h" | |||
38 | #include "llvm/IR/Function.h" | |||
39 | #include "llvm/IR/IRBuilder.h" | |||
40 | #include "llvm/IR/InlineAsm.h" | |||
41 | #include "llvm/IR/LLVMContext.h" | |||
42 | #include "llvm/IR/MDBuilder.h" | |||
43 | #include "llvm/IR/Module.h" | |||
44 | #include "llvm/IR/Type.h" | |||
45 | #include "llvm/Support/CommandLine.h" | |||
46 | #include "llvm/Support/Debug.h" | |||
47 | #include "llvm/Support/raw_ostream.h" | |||
48 | #include "llvm/Transforms/Scalar.h" | |||
49 | #include "llvm/Transforms/Utils/BasicBlockUtils.h" | |||
50 | #include "llvm/Transforms/Utils/ModuleUtils.h" | |||
51 | ||||
52 | using namespace llvm; | |||
53 | ||||
54 | #define DEBUG_TYPE"sancov" "sancov" | |||
55 | ||||
56 | static const char *const kSanCovModuleInitName = "__sanitizer_cov_module_init"; | |||
57 | static const char *const kSanCovName = "__sanitizer_cov"; | |||
58 | static const char *const kSanCovWithCheckName = "__sanitizer_cov_with_check"; | |||
59 | static const char *const kSanCovIndirCallName = "__sanitizer_cov_indir_call16"; | |||
60 | static const char *const kSanCovTraceEnter = "__sanitizer_cov_trace_func_enter"; | |||
61 | static const char *const kSanCovTraceBB = "__sanitizer_cov_trace_basic_block"; | |||
62 | static const char *const kSanCovTraceCmp = "__sanitizer_cov_trace_cmp"; | |||
63 | static const char *const kSanCovModuleCtorName = "sancov.module_ctor"; | |||
64 | static const uint64_t kSanCtorAndDtorPriority = 2; | |||
65 | ||||
66 | static cl::opt<int> ClCoverageLevel("sanitizer-coverage-level", | |||
67 | cl::desc("Sanitizer Coverage. 0: none, 1: entry block, 2: all blocks, " | |||
68 | "3: all blocks and critical edges, " | |||
69 | "4: above plus indirect calls"), | |||
70 | cl::Hidden, cl::init(0)); | |||
71 | ||||
72 | static cl::opt<unsigned> ClCoverageBlockThreshold( | |||
73 | "sanitizer-coverage-block-threshold", | |||
74 | cl::desc("Use a callback with a guard check inside it if there are" | |||
75 | " more than this number of blocks."), | |||
76 | cl::Hidden, cl::init(500)); | |||
77 | ||||
78 | static cl::opt<bool> | |||
79 | ClExperimentalTracing("sanitizer-coverage-experimental-tracing", | |||
80 | cl::desc("Experimental basic-block tracing: insert " | |||
81 | "callbacks at every basic block"), | |||
82 | cl::Hidden, cl::init(false)); | |||
83 | ||||
84 | static cl::opt<bool> | |||
85 | ClExperimentalCMPTracing("sanitizer-coverage-experimental-trace-compares", | |||
86 | cl::desc("Experimental tracing of CMP and similar " | |||
87 | "instructions"), | |||
88 | cl::Hidden, cl::init(false)); | |||
89 | ||||
90 | // Experimental 8-bit counters used as an additional search heuristic during | |||
91 | // coverage-guided fuzzing. | |||
92 | // The counters are not thread-friendly: | |||
93 | // - contention on these counters may cause significant slowdown; | |||
94 | // - the counter updates are racy and the results may be inaccurate. | |||
95 | // They are also inaccurate due to 8-bit integer overflow. | |||
96 | static cl::opt<bool> ClUse8bitCounters("sanitizer-coverage-8bit-counters", | |||
97 | cl::desc("Experimental 8-bit counters"), | |||
98 | cl::Hidden, cl::init(false)); | |||
99 | ||||
100 | namespace { | |||
101 | ||||
102 | class SanitizerCoverageModule : public ModulePass { | |||
103 | public: | |||
104 | SanitizerCoverageModule(int CoverageLevel = 0) | |||
105 | : ModulePass(ID), | |||
106 | CoverageLevel(std::max(CoverageLevel, (int)ClCoverageLevel)) {} | |||
107 | bool runOnModule(Module &M) override; | |||
108 | bool runOnFunction(Function &F); | |||
109 | static char ID; // Pass identification, replacement for typeid | |||
110 | const char *getPassName() const override { | |||
111 | return "SanitizerCoverageModule"; | |||
112 | } | |||
113 | ||||
114 | private: | |||
115 | void InjectCoverageForIndirectCalls(Function &F, | |||
116 | ArrayRef<Instruction *> IndirCalls); | |||
117 | void InjectTraceForCmp(Function &F, ArrayRef<Instruction *> CmpTraceTargets); | |||
118 | bool InjectCoverage(Function &F, ArrayRef<BasicBlock *> AllBlocks); | |||
119 | void SetNoSanitizeMetada(Instruction *I); | |||
120 | void InjectCoverageAtBlock(Function &F, BasicBlock &BB, bool UseCalls); | |||
121 | unsigned NumberOfInstrumentedBlocks() { | |||
122 | return SanCovFunction->getNumUses() + SanCovWithCheckFunction->getNumUses(); | |||
123 | } | |||
124 | Function *SanCovFunction; | |||
125 | Function *SanCovWithCheckFunction; | |||
126 | Function *SanCovIndirCallFunction; | |||
127 | Function *SanCovModuleInit; | |||
128 | Function *SanCovTraceEnter, *SanCovTraceBB; | |||
129 | Function *SanCovTraceCmpFunction; | |||
130 | InlineAsm *EmptyAsm; | |||
131 | Type *IntptrTy, *Int64Ty; | |||
132 | LLVMContext *C; | |||
133 | const DataLayout *DL; | |||
134 | ||||
135 | GlobalVariable *GuardArray; | |||
136 | GlobalVariable *EightBitCounterArray; | |||
137 | ||||
138 | int CoverageLevel; | |||
139 | }; | |||
140 | ||||
141 | } // namespace | |||
142 | ||||
143 | static Function *checkInterfaceFunction(Constant *FuncOrBitcast) { | |||
144 | if (Function *F = dyn_cast<Function>(FuncOrBitcast)) | |||
145 | return F; | |||
146 | std::string Err; | |||
147 | raw_string_ostream Stream(Err); | |||
148 | Stream << "SanitizerCoverage interface function redefined: " | |||
149 | << *FuncOrBitcast; | |||
150 | report_fatal_error(Err); | |||
151 | } | |||
152 | ||||
153 | bool SanitizerCoverageModule::runOnModule(Module &M) { | |||
154 | if (!CoverageLevel) return false; | |||
| ||||
155 | C = &(M.getContext()); | |||
156 | DL = &M.getDataLayout(); | |||
157 | IntptrTy = Type::getIntNTy(*C, DL->getPointerSizeInBits()); | |||
158 | Type *VoidTy = Type::getVoidTy(*C); | |||
159 | IRBuilder<> IRB(*C); | |||
160 | Type *Int8PtrTy = PointerType::getUnqual(IRB.getInt8Ty()); | |||
161 | Type *Int32PtrTy = PointerType::getUnqual(IRB.getInt32Ty()); | |||
162 | Int64Ty = IRB.getInt64Ty(); | |||
163 | ||||
164 | Function *CtorFunc = | |||
165 | Function::Create(FunctionType::get(VoidTy, false), | |||
166 | GlobalValue::InternalLinkage, kSanCovModuleCtorName, &M); | |||
167 | ReturnInst::Create(*C, BasicBlock::Create(*C, "", CtorFunc)); | |||
168 | appendToGlobalCtors(M, CtorFunc, kSanCtorAndDtorPriority); | |||
169 | ||||
170 | SanCovFunction = checkInterfaceFunction( | |||
171 | M.getOrInsertFunction(kSanCovName, VoidTy, Int32PtrTy, nullptr)); | |||
172 | SanCovWithCheckFunction = checkInterfaceFunction( | |||
173 | M.getOrInsertFunction(kSanCovWithCheckName, VoidTy, Int32PtrTy, nullptr)); | |||
174 | SanCovIndirCallFunction = checkInterfaceFunction(M.getOrInsertFunction( | |||
175 | kSanCovIndirCallName, VoidTy, IntptrTy, IntptrTy, nullptr)); | |||
176 | SanCovTraceCmpFunction = checkInterfaceFunction(M.getOrInsertFunction( | |||
177 | kSanCovTraceCmp, VoidTy, Int64Ty, Int64Ty, Int64Ty, nullptr)); | |||
178 | ||||
179 | SanCovModuleInit = checkInterfaceFunction(M.getOrInsertFunction( | |||
180 | kSanCovModuleInitName, Type::getVoidTy(*C), Int32PtrTy, IntptrTy, | |||
181 | Int8PtrTy, Int8PtrTy, nullptr)); | |||
182 | SanCovModuleInit->setLinkage(Function::ExternalLinkage); | |||
183 | // We insert an empty inline asm after cov callbacks to avoid callback merge. | |||
184 | EmptyAsm = InlineAsm::get(FunctionType::get(IRB.getVoidTy(), false), | |||
185 | StringRef(""), StringRef(""), | |||
186 | /*hasSideEffects=*/true); | |||
187 | ||||
188 | if (ClExperimentalTracing) { | |||
189 | SanCovTraceEnter = checkInterfaceFunction( | |||
190 | M.getOrInsertFunction(kSanCovTraceEnter, VoidTy, Int32PtrTy, nullptr)); | |||
191 | SanCovTraceBB = checkInterfaceFunction( | |||
192 | M.getOrInsertFunction(kSanCovTraceBB, VoidTy, Int32PtrTy, nullptr)); | |||
193 | } | |||
194 | ||||
195 | // At this point we create a dummy array of guards because we don't | |||
196 | // know how many elements we will need. | |||
197 | Type *Int32Ty = IRB.getInt32Ty(); | |||
198 | Type *Int8Ty = IRB.getInt8Ty(); | |||
199 | ||||
200 | GuardArray = | |||
201 | new GlobalVariable(M, Int32Ty, false, GlobalValue::ExternalLinkage, | |||
202 | nullptr, "__sancov_gen_cov_tmp"); | |||
203 | if (ClUse8bitCounters) | |||
204 | EightBitCounterArray = | |||
205 | new GlobalVariable(M, Int8Ty, false, GlobalVariable::ExternalLinkage, | |||
206 | nullptr, "__sancov_gen_cov_tmp"); | |||
207 | ||||
208 | for (auto &F : M) | |||
209 | runOnFunction(F); | |||
210 | ||||
211 | auto N = NumberOfInstrumentedBlocks(); | |||
212 | ||||
213 | // Now we know how many elements we need. Create an array of guards | |||
214 | // with one extra element at the beginning for the size. | |||
215 | Type *Int32ArrayNTy = ArrayType::get(Int32Ty, N + 1); | |||
216 | GlobalVariable *RealGuardArray = new GlobalVariable( | |||
217 | M, Int32ArrayNTy, false, GlobalValue::PrivateLinkage, | |||
218 | Constant::getNullValue(Int32ArrayNTy), "__sancov_gen_cov"); | |||
219 | ||||
220 | ||||
221 | // Replace the dummy array with the real one. | |||
222 | GuardArray->replaceAllUsesWith( | |||
223 | IRB.CreatePointerCast(RealGuardArray, Int32PtrTy)); | |||
224 | GuardArray->eraseFromParent(); | |||
225 | ||||
226 | GlobalVariable *RealEightBitCounterArray; | |||
227 | if (ClUse8bitCounters) { | |||
228 | // Make sure the array is 16-aligned. | |||
229 | static const int kCounterAlignment = 16; | |||
230 | Type *Int8ArrayNTy = | |||
231 | ArrayType::get(Int8Ty, RoundUpToAlignment(N, kCounterAlignment)); | |||
232 | RealEightBitCounterArray = new GlobalVariable( | |||
233 | M, Int8ArrayNTy, false, GlobalValue::PrivateLinkage, | |||
234 | Constant::getNullValue(Int8ArrayNTy), "__sancov_gen_cov_counter"); | |||
235 | RealEightBitCounterArray->setAlignment(kCounterAlignment); | |||
236 | EightBitCounterArray->replaceAllUsesWith( | |||
237 | IRB.CreatePointerCast(RealEightBitCounterArray, Int8PtrTy)); | |||
238 | EightBitCounterArray->eraseFromParent(); | |||
239 | } | |||
240 | ||||
241 | // Create variable for module (compilation unit) name | |||
242 | Constant *ModNameStrConst = | |||
243 | ConstantDataArray::getString(M.getContext(), M.getName(), true); | |||
244 | GlobalVariable *ModuleName = | |||
245 | new GlobalVariable(M, ModNameStrConst->getType(), true, | |||
246 | GlobalValue::PrivateLinkage, ModNameStrConst); | |||
247 | ||||
248 | // Call __sanitizer_cov_module_init | |||
249 | IRB.SetInsertPoint(CtorFunc->getEntryBlock().getTerminator()); | |||
250 | IRB.CreateCall4( | |||
251 | SanCovModuleInit, IRB.CreatePointerCast(RealGuardArray, Int32PtrTy), | |||
252 | ConstantInt::get(IntptrTy, N), | |||
253 | ClUse8bitCounters | |||
254 | ? IRB.CreatePointerCast(RealEightBitCounterArray, Int8PtrTy) | |||
| ||||
255 | : Constant::getNullValue(Int8PtrTy), | |||
256 | IRB.CreatePointerCast(ModuleName, Int8PtrTy)); | |||
257 | return true; | |||
258 | } | |||
259 | ||||
260 | bool SanitizerCoverageModule::runOnFunction(Function &F) { | |||
261 | if (F.empty()) return false; | |||
262 | if (F.getName().find(".module_ctor") != std::string::npos) | |||
263 | return false; // Should not instrument sanitizer init functions. | |||
264 | if (CoverageLevel >= 3) | |||
265 | SplitAllCriticalEdges(F); | |||
266 | SmallVector<Instruction*, 8> IndirCalls; | |||
267 | SmallVector<BasicBlock*, 16> AllBlocks; | |||
268 | SmallVector<Instruction*, 8> CmpTraceTargets; | |||
269 | for (auto &BB : F) { | |||
270 | AllBlocks.push_back(&BB); | |||
271 | for (auto &Inst : BB) { | |||
272 | if (CoverageLevel >= 4) { | |||
273 | CallSite CS(&Inst); | |||
274 | if (CS && !CS.getCalledFunction()) | |||
275 | IndirCalls.push_back(&Inst); | |||
276 | } | |||
277 | if (ClExperimentalCMPTracing) | |||
278 | if (isa<ICmpInst>(&Inst)) | |||
279 | CmpTraceTargets.push_back(&Inst); | |||
280 | } | |||
281 | } | |||
282 | InjectCoverage(F, AllBlocks); | |||
283 | InjectCoverageForIndirectCalls(F, IndirCalls); | |||
284 | InjectTraceForCmp(F, CmpTraceTargets); | |||
285 | return true; | |||
286 | } | |||
287 | ||||
288 | bool SanitizerCoverageModule::InjectCoverage(Function &F, | |||
289 | ArrayRef<BasicBlock *> AllBlocks) { | |||
290 | if (!CoverageLevel) return false; | |||
291 | ||||
292 | if (CoverageLevel == 1) { | |||
293 | InjectCoverageAtBlock(F, F.getEntryBlock(), false); | |||
294 | } else { | |||
295 | for (auto BB : AllBlocks) | |||
296 | InjectCoverageAtBlock(F, *BB, | |||
297 | ClCoverageBlockThreshold < AllBlocks.size()); | |||
298 | } | |||
299 | return true; | |||
300 | } | |||
301 | ||||
302 | // On every indirect call we call a run-time function | |||
303 | // __sanitizer_cov_indir_call* with two parameters: | |||
304 | // - callee address, | |||
305 | // - global cache array that contains kCacheSize pointers (zero-initialized). | |||
306 | // The cache is used to speed up recording the caller-callee pairs. | |||
307 | // The address of the caller is passed implicitly via caller PC. | |||
308 | // kCacheSize is encoded in the name of the run-time function. | |||
309 | void SanitizerCoverageModule::InjectCoverageForIndirectCalls( | |||
310 | Function &F, ArrayRef<Instruction *> IndirCalls) { | |||
311 | if (IndirCalls.empty()) return; | |||
312 | const int kCacheSize = 16; | |||
313 | const int kCacheAlignment = 64; // Align for better performance. | |||
314 | Type *Ty = ArrayType::get(IntptrTy, kCacheSize); | |||
315 | for (auto I : IndirCalls) { | |||
316 | IRBuilder<> IRB(I); | |||
317 | CallSite CS(I); | |||
318 | Value *Callee = CS.getCalledValue(); | |||
319 | if (dyn_cast<InlineAsm>(Callee)) continue; | |||
320 | GlobalVariable *CalleeCache = new GlobalVariable( | |||
321 | *F.getParent(), Ty, false, GlobalValue::PrivateLinkage, | |||
322 | Constant::getNullValue(Ty), "__sancov_gen_callee_cache"); | |||
323 | CalleeCache->setAlignment(kCacheAlignment); | |||
324 | IRB.CreateCall2(SanCovIndirCallFunction, | |||
325 | IRB.CreatePointerCast(Callee, IntptrTy), | |||
326 | IRB.CreatePointerCast(CalleeCache, IntptrTy)); | |||
327 | } | |||
328 | } | |||
329 | ||||
330 | void SanitizerCoverageModule::InjectTraceForCmp( | |||
331 | Function &F, ArrayRef<Instruction *> CmpTraceTargets) { | |||
332 | if (!ClExperimentalCMPTracing) return; | |||
333 | for (auto I : CmpTraceTargets) { | |||
334 | if (ICmpInst *ICMP = dyn_cast<ICmpInst>(I)) { | |||
335 | IRBuilder<> IRB(ICMP); | |||
336 | Value *A0 = ICMP->getOperand(0); | |||
337 | Value *A1 = ICMP->getOperand(1); | |||
338 | if (!A0->getType()->isIntegerTy()) continue; | |||
339 | uint64_t TypeSize = DL->getTypeStoreSizeInBits(A0->getType()); | |||
340 | // __sanitizer_cov_indir_call((type_size << 32) | predicate, A0, A1); | |||
341 | IRB.CreateCall3( | |||
342 | SanCovTraceCmpFunction, | |||
343 | ConstantInt::get(Int64Ty, (TypeSize << 32) | ICMP->getPredicate()), | |||
344 | IRB.CreateIntCast(A0, Int64Ty, true), | |||
345 | IRB.CreateIntCast(A1, Int64Ty, true)); | |||
346 | } | |||
347 | } | |||
348 | } | |||
349 | ||||
350 | void SanitizerCoverageModule::SetNoSanitizeMetada(Instruction *I) { | |||
351 | I->setMetadata( | |||
352 | I->getParent()->getParent()->getParent()->getMDKindID("nosanitize"), | |||
353 | MDNode::get(*C, None)); | |||
354 | } | |||
355 | ||||
356 | void SanitizerCoverageModule::InjectCoverageAtBlock(Function &F, BasicBlock &BB, | |||
357 | bool UseCalls) { | |||
358 | BasicBlock::iterator IP = BB.getFirstInsertionPt(), BE = BB.end(); | |||
359 | // Skip static allocas at the top of the entry block so they don't become | |||
360 | // dynamic when we split the block. If we used our optimized stack layout, | |||
361 | // then there will only be one alloca and it will come first. | |||
362 | for (; IP != BE; ++IP) { | |||
363 | AllocaInst *AI = dyn_cast<AllocaInst>(IP); | |||
364 | if (!AI || !AI->isStaticAlloca()) | |||
365 | break; | |||
366 | } | |||
367 | ||||
368 | bool IsEntryBB = &BB == &F.getEntryBlock(); | |||
369 | DebugLoc EntryLoc = IsEntryBB && IP->getDebugLoc() | |||
370 | ? IP->getDebugLoc().getFnDebugLoc() | |||
371 | : IP->getDebugLoc(); | |||
372 | IRBuilder<> IRB(IP); | |||
373 | IRB.SetCurrentDebugLocation(EntryLoc); | |||
374 | SmallVector<Value *, 1> Indices; | |||
375 | Value *GuardP = IRB.CreateAdd( | |||
376 | IRB.CreatePointerCast(GuardArray, IntptrTy), | |||
377 | ConstantInt::get(IntptrTy, (1 + NumberOfInstrumentedBlocks()) * 4)); | |||
378 | Type *Int32PtrTy = PointerType::getUnqual(IRB.getInt32Ty()); | |||
379 | GuardP = IRB.CreateIntToPtr(GuardP, Int32PtrTy); | |||
380 | if (UseCalls) { | |||
381 | IRB.CreateCall(SanCovWithCheckFunction, GuardP); | |||
382 | } else { | |||
383 | LoadInst *Load = IRB.CreateLoad(GuardP); | |||
384 | Load->setAtomic(Monotonic); | |||
385 | Load->setAlignment(4); | |||
386 | SetNoSanitizeMetada(Load); | |||
387 | Value *Cmp = IRB.CreateICmpSGE(Constant::getNullValue(Load->getType()), Load); | |||
388 | Instruction *Ins = SplitBlockAndInsertIfThen( | |||
389 | Cmp, IP, false, MDBuilder(*C).createBranchWeights(1, 100000)); | |||
390 | IRB.SetInsertPoint(Ins); | |||
391 | IRB.SetCurrentDebugLocation(EntryLoc); | |||
392 | // __sanitizer_cov gets the PC of the instruction using GET_CALLER_PC. | |||
393 | IRB.CreateCall(SanCovFunction, GuardP); | |||
394 | IRB.CreateCall(EmptyAsm); // Avoids callback merge. | |||
395 | } | |||
396 | ||||
397 | if(ClUse8bitCounters) { | |||
398 | IRB.SetInsertPoint(IP); | |||
399 | Value *P = IRB.CreateAdd( | |||
400 | IRB.CreatePointerCast(EightBitCounterArray, IntptrTy), | |||
401 | ConstantInt::get(IntptrTy, NumberOfInstrumentedBlocks() - 1)); | |||
402 | P = IRB.CreateIntToPtr(P, IRB.getInt8PtrTy()); | |||
403 | LoadInst *LI = IRB.CreateLoad(P); | |||
404 | Value *Inc = IRB.CreateAdd(LI, ConstantInt::get(IRB.getInt8Ty(), 1)); | |||
405 | StoreInst *SI = IRB.CreateStore(Inc, P); | |||
406 | SetNoSanitizeMetada(LI); | |||
407 | SetNoSanitizeMetada(SI); | |||
408 | } | |||
409 | ||||
410 | if (ClExperimentalTracing) { | |||
411 | // Experimental support for tracing. | |||
412 | // Insert a callback with the same guard variable as used for coverage. | |||
413 | IRB.SetInsertPoint(IP); | |||
414 | IRB.CreateCall(IsEntryBB ? SanCovTraceEnter : SanCovTraceBB, GuardP); | |||
415 | } | |||
416 | } | |||
417 | ||||
418 | char SanitizerCoverageModule::ID = 0; | |||
419 | INITIALIZE_PASS(SanitizerCoverageModule, "sancov",static void* initializeSanitizerCoverageModulePassOnce(PassRegistry &Registry) { PassInfo *PI = new PassInfo("SanitizerCoverage: TODO." "ModulePass", "sancov", & SanitizerCoverageModule ::ID, PassInfo ::NormalCtor_t(callDefaultCtor< SanitizerCoverageModule > ), false, false); Registry.registerPass(*PI, true); return PI ; } void llvm::initializeSanitizerCoverageModulePass(PassRegistry &Registry) { static volatile sys::cas_flag initialized = 0; sys::cas_flag old_val = sys::CompareAndSwap(&initialized , 1, 0); if (old_val == 0) { initializeSanitizerCoverageModulePassOnce (Registry); sys::MemoryFence(); AnnotateIgnoreWritesBegin("/tmp/buildd/llvm-toolchain-snapshot-3.7~svn233676/lib/Transforms/Instrumentation/SanitizerCoverage.cpp" , 421); AnnotateHappensBefore("/tmp/buildd/llvm-toolchain-snapshot-3.7~svn233676/lib/Transforms/Instrumentation/SanitizerCoverage.cpp" , 421, &initialized); initialized = 2; AnnotateIgnoreWritesEnd ("/tmp/buildd/llvm-toolchain-snapshot-3.7~svn233676/lib/Transforms/Instrumentation/SanitizerCoverage.cpp" , 421); } else { sys::cas_flag tmp = initialized; sys::MemoryFence (); while (tmp != 2) { tmp = initialized; sys::MemoryFence(); } } AnnotateHappensAfter("/tmp/buildd/llvm-toolchain-snapshot-3.7~svn233676/lib/Transforms/Instrumentation/SanitizerCoverage.cpp" , 421, &initialized); } | |||
420 | "SanitizerCoverage: TODO."static void* initializeSanitizerCoverageModulePassOnce(PassRegistry &Registry) { PassInfo *PI = new PassInfo("SanitizerCoverage: TODO." "ModulePass", "sancov", & SanitizerCoverageModule ::ID, PassInfo ::NormalCtor_t(callDefaultCtor< SanitizerCoverageModule > ), false, false); Registry.registerPass(*PI, true); return PI ; } void llvm::initializeSanitizerCoverageModulePass(PassRegistry &Registry) { static volatile sys::cas_flag initialized = 0; sys::cas_flag old_val = sys::CompareAndSwap(&initialized , 1, 0); if (old_val == 0) { initializeSanitizerCoverageModulePassOnce (Registry); sys::MemoryFence(); AnnotateIgnoreWritesBegin("/tmp/buildd/llvm-toolchain-snapshot-3.7~svn233676/lib/Transforms/Instrumentation/SanitizerCoverage.cpp" , 421); AnnotateHappensBefore("/tmp/buildd/llvm-toolchain-snapshot-3.7~svn233676/lib/Transforms/Instrumentation/SanitizerCoverage.cpp" , 421, &initialized); initialized = 2; AnnotateIgnoreWritesEnd ("/tmp/buildd/llvm-toolchain-snapshot-3.7~svn233676/lib/Transforms/Instrumentation/SanitizerCoverage.cpp" , 421); } else { sys::cas_flag tmp = initialized; sys::MemoryFence (); while (tmp != 2) { tmp = initialized; sys::MemoryFence(); } } AnnotateHappensAfter("/tmp/buildd/llvm-toolchain-snapshot-3.7~svn233676/lib/Transforms/Instrumentation/SanitizerCoverage.cpp" , 421, &initialized); } | |||
421 | "ModulePass", false, false)static void* initializeSanitizerCoverageModulePassOnce(PassRegistry &Registry) { PassInfo *PI = new PassInfo("SanitizerCoverage: TODO." "ModulePass", "sancov", & SanitizerCoverageModule ::ID, PassInfo ::NormalCtor_t(callDefaultCtor< SanitizerCoverageModule > ), false, false); Registry.registerPass(*PI, true); return PI ; } void llvm::initializeSanitizerCoverageModulePass(PassRegistry &Registry) { static volatile sys::cas_flag initialized = 0; sys::cas_flag old_val = sys::CompareAndSwap(&initialized , 1, 0); if (old_val == 0) { initializeSanitizerCoverageModulePassOnce (Registry); sys::MemoryFence(); AnnotateIgnoreWritesBegin("/tmp/buildd/llvm-toolchain-snapshot-3.7~svn233676/lib/Transforms/Instrumentation/SanitizerCoverage.cpp" , 421); AnnotateHappensBefore("/tmp/buildd/llvm-toolchain-snapshot-3.7~svn233676/lib/Transforms/Instrumentation/SanitizerCoverage.cpp" , 421, &initialized); initialized = 2; AnnotateIgnoreWritesEnd ("/tmp/buildd/llvm-toolchain-snapshot-3.7~svn233676/lib/Transforms/Instrumentation/SanitizerCoverage.cpp" , 421); } else { sys::cas_flag tmp = initialized; sys::MemoryFence (); while (tmp != 2) { tmp = initialized; sys::MemoryFence(); } } AnnotateHappensAfter("/tmp/buildd/llvm-toolchain-snapshot-3.7~svn233676/lib/Transforms/Instrumentation/SanitizerCoverage.cpp" , 421, &initialized); } | |||
422 | ModulePass *llvm::createSanitizerCoverageModulePass(int CoverageLevel) { | |||
423 | return new SanitizerCoverageModule(CoverageLevel); | |||
424 | } |