llvm.org GIT mirror llvm / 2475da8
Revert "[asan] Poor man's coverage that works with ASan" This reverts commit 194701. Apple's bootstrapped LTO builds have been failing, and this change (along with compiler-rt 194702-194704) is the only thing on the blamelist. I will either reappy these changes or help debug the problem, depending on whether this fixes the buildbots. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@194780 91177308-0d34-0410-b5e6-96231b3b80d8 Bob Wilson 7 years ago
2 changed file(s) with 0 addition(s) and 65 deletion(s). Raw diff Collapse all Expand all
7676 static const char *const kAsanPoisonGlobalsName = "__asan_before_dynamic_init";
7777 static const char *const kAsanUnpoisonGlobalsName = "__asan_after_dynamic_init";
7878 static const char *const kAsanInitName = "__asan_init_v3";
79 static const char *const kAsanCovName = "__sanitizer_cov";
8079 static const char *const kAsanHandleNoReturnName = "__asan_handle_no_return";
8180 static const char *const kAsanMappingOffsetName = "__asan_mapping_offset";
8281 static const char *const kAsanMappingScaleName = "__asan_mapping_scale";
134133 // This flag may need to be replaced with -f[no]asan-globals.
135134 static cl::opt ClGlobals("asan-globals",
136135 cl::desc("Handle global objects"), cl::Hidden, cl::init(true));
137 static cl::opt ClCoverage("asan-coverage",
138 cl::desc("ASan coverage"), cl::Hidden, cl::init(false));
139136 static cl::opt ClInitializers("asan-initialization-order",
140137 cl::desc("Handle C++ initializer order"), cl::Hidden, cl::init(false));
141138 static cl::opt ClMemIntrin("asan-memintrin",
326323 bool LooksLikeCodeInBug11395(Instruction *I);
327324 void FindDynamicInitializers(Module &M);
328325 bool GlobalIsLinkerInitialized(GlobalVariable *G);
329 bool InjectCoverage(Function &F);
330326
331327 bool CheckInitOrder;
332328 bool CheckUseAfterReturn;
342338 Function *AsanCtorFunction;
343339 Function *AsanInitFunction;
344340 Function *AsanHandleNoReturnFunc;
345 Function *AsanCovFunction;
346341 OwningPtr BL;
347342 // This array is indexed by AccessIsWrite and log2(AccessSize).
348343 Function *AsanErrorCallback[2][kNumberOfAccessSizes];
10891084
10901085 AsanHandleNoReturnFunc = checkInterfaceFunction(M.getOrInsertFunction(
10911086 kAsanHandleNoReturnName, IRB.getVoidTy(), NULL));
1092 AsanCovFunction = checkInterfaceFunction(M.getOrInsertFunction(
1093 kAsanCovName, IRB.getVoidTy(), IntptrTy, NULL));
10941087 // We insert an empty inline asm after __asan_report* to avoid callback merge.
10951088 EmptyAsm = InlineAsm::get(FunctionType::get(IRB.getVoidTy(), false),
10961089 StringRef(""), StringRef(""),
11601153 return true;
11611154 }
11621155 return false;
1163 }
1164
1165 // Poor man's coverage that works with ASan.
1166 // We create a Guard boolean variable with the same linkage
1167 // as the function and inject this code into the entry block:
1168 // if (*Guard) {
1169 // __sanitizer_cov(&F);
1170 // *Guard = 1;
1171 // }
1172 // The accesses to Guard are atomic. The rest of the logic is
1173 // in __sanitizer_cov (it's fine to call it more than once).
1174 //
1175 // This coverage implementation provides very limited data:
1176 // it only tells if a given function was ever executed.
1177 // No counters, no per-basic-block or per-edge data.
1178 // But for many use cases this is what we need and the added slowdown
1179 // is negligible. This simple implementation will probably be obsoleted
1180 // by the upcoming Clang-based coverage implementation.
1181 // By having it here and now we hope to
1182 // a) get the functionality to users earlier and
1183 // b) collect usage statistics to help improve Clang coverage design.
1184 bool AddressSanitizer::InjectCoverage(Function &F) {
1185 if (!ClCoverage) return false;
1186 IRBuilder<> IRB(F.getEntryBlock().getFirstInsertionPt());
1187 Type *Int8Ty = IRB.getInt8Ty();
1188 GlobalVariable *Guard = new GlobalVariable(
1189 *F.getParent(), Int8Ty, false, F.getLinkage(),
1190 Constant::getNullValue(Int8Ty), "__asan_gen_cov_" + F.getName());
1191 LoadInst *Load = IRB.CreateLoad(Guard);
1192 Load->setAtomic(Monotonic);
1193 Load->setAlignment(1);
1194 Value *Cmp = IRB.CreateICmpEQ(Constant::getNullValue(Int8Ty), Load);
1195 Instruction *Ins = SplitBlockAndInsertIfThen(cast(Cmp), false);
1196 IRB.SetInsertPoint(Ins);
1197 // We pass &F to __sanitizer_cov. We could avoid this and rely on
1198 // GET_CALLER_PC, but having the PC of the first instruction is just nice.
1199 IRB.CreateCall(AsanCovFunction, IRB.CreatePointerCast(&F, IntptrTy));
1200 StoreInst *Store = IRB.CreateStore(ConstantInt::get(Int8Ty, 1), Guard);
1201 Store->setAtomic(Monotonic);
1202 Store->setAlignment(1);
1203 return true;
12041156 }
12051157
12061158 bool AddressSanitizer::runOnFunction(Function &F) {
12981250 }
12991251
13001252 bool res = NumInstrumented > 0 || ChangedStack || !NoReturnCalls.empty();
1301
1302 if (InjectCoverage(F))
1303 res = true;
1304
13051253 DEBUG(dbgs() << "ASAN done instrumenting: " << res << " " << F << "\n");
13061254
13071255 if (ClKeepUninstrumented) {
+0
-13
test/Instrumentation/AddressSanitizer/coverage.ll less more
None ; RUN: opt < %s -asan -asan-coverage=1 -S | FileCheck %s
1 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"
2 target triple = "x86_64-unknown-linux-gnu"
3 define i32 @foo(i32* %a) sanitize_address {
4 entry:
5 ret i32 0
6 }
7 ; CHECK: define i32 @foo(i32* %a) #0 {
8 ; CHECK: %0 = load atomic i8* @__asan_gen_cov_foo monotonic, align 1
9 ; CHECK: %1 = icmp eq i8 0, %0
10 ; CHECK: br i1 %1, label %2, label %3
11 ; CHECK: call void @__sanitizer_cov(i64 ptrtoint (i32 (i32*)* @foo to i64))
12 ; CHECK: store atomic i8 1, i8* @__asan_gen_cov_foo monotonic, align 1