Index: lib/Transforms/Instrumentation/AddressSanitizer.cpp =================================================================== --- lib/Transforms/Instrumentation/AddressSanitizer.cpp +++ lib/Transforms/Instrumentation/AddressSanitizer.cpp @@ -80,6 +80,7 @@ static const char *const kAsanPoisonGlobalsName = "__asan_before_dynamic_init"; static const char *const kAsanUnpoisonGlobalsName = "__asan_after_dynamic_init"; static const char *const kAsanInitName = "__asan_init_v3"; +static const char *const kAsanCovModuleInitName = "__sanitizer_cov_module_init"; static const char *const kAsanCovName = "__sanitizer_cov"; static const char *const kAsanPtrCmp = "__sanitizer_ptr_cmp"; static const char *const kAsanPtrSub = "__sanitizer_ptr_sub"; @@ -408,6 +409,7 @@ Function *AsanUnpoisonGlobals; Function *AsanRegisterGlobals; Function *AsanUnregisterGlobals; + Function *AsanCovModuleInit; }; // Stack poisoning does not play well with exception handling. @@ -981,6 +983,10 @@ kAsanUnregisterGlobalsName, IRB.getVoidTy(), IntptrTy, IntptrTy, NULL)); AsanUnregisterGlobals->setLinkage(Function::ExternalLinkage); + AsanCovModuleInit = checkInterfaceFunction(M.getOrInsertFunction( + kAsanCovModuleInitName, + IRB.getVoidTy(), IntptrTy, NULL)); + AsanCovModuleInit->setLinkage(Function::ExternalLinkage); } // This function replaces all global variables with new variables that have @@ -1011,6 +1017,14 @@ GlobalsToChange.push_back(G); } + Function *CtorFunc = M.getFunction(kAsanModuleCtorName); + assert(CtorFunc); + IRBuilder<> IRB(CtorFunc->getEntryBlock().getTerminator()); + + Function *CovFunc = M.getFunction(kAsanCovName); + int nCov = CovFunc ? CovFunc->getNumUses() : 0; + IRB.CreateCall(AsanCovModuleInit, ConstantInt::get(IntptrTy, nCov)); + size_t n = GlobalsToChange.size(); if (n == 0) return false; @@ -1027,10 +1041,6 @@ IntptrTy, IntptrTy, NULL); SmallVector Initializers(n); - Function *CtorFunc = M.getFunction(kAsanModuleCtorName); - assert(CtorFunc); - IRBuilder<> IRB(CtorFunc->getEntryBlock().getTerminator()); - bool HasDynamicallyInitializedGlobals = false; // We shouldn't merge same module names, as this string serves as unique Index: test/Instrumentation/AddressSanitizer/coverage.ll =================================================================== --- test/Instrumentation/AddressSanitizer/coverage.ll +++ test/Instrumentation/AddressSanitizer/coverage.ll @@ -16,6 +16,7 @@ if.end: ; preds = %entry, %if.then ret void } + ; CHECK1-LABEL: define void @foo ; CHECK1: %0 = load atomic i8* @__asan_gen_cov_foo monotonic, align 1 ; CHECK1: %1 = icmp eq i8 0, %0 @@ -24,9 +25,20 @@ ; CHECK1-NOT: call void @__sanitizer_cov ; CHECK1: store atomic i8 1, i8* @__asan_gen_cov_foo monotonic, align 1 +; CHECK1-LABEL: define internal void @asan.module_ctor +; CHECK1-NOT: ret +; CHECK1: call void @__sanitizer_cov_module_init(i64 1) +; CHECK1: ret + + ; CHECK2-LABEL: define void @foo ; CHECK2: call void @__sanitizer_cov ; CHECK2: call void @__sanitizer_cov ; CHECK2: call void @__sanitizer_cov ; CHECK2-NOT: call void @__sanitizer_cov ; CHECK2: ret void + +; CHECK2-LABEL: define internal void @asan.module_ctor +; CHECK2-NOT: ret +; CHECK2: call void @__sanitizer_cov_module_init(i64 3) +; CHECK2: ret