Index: llvm/trunk/lib/Transforms/Instrumentation/SanitizerCoverage.cpp =================================================================== --- llvm/trunk/lib/Transforms/Instrumentation/SanitizerCoverage.cpp +++ llvm/trunk/lib/Transforms/Instrumentation/SanitizerCoverage.cpp @@ -219,6 +219,8 @@ MDNode::get(*C, None)); } + Comdat *GetOrCreateFunctionComdat(Function &F); + std::string getSectionName(const std::string &Section) const; std::string getSectionStart(const std::string &Section) const; std::string getSectionEnd(const std::string &Section) const; @@ -234,6 +236,7 @@ Type *IntptrTy, *IntptrPtrTy, *Int64Ty, *Int64PtrTy, *Int32Ty, *Int32PtrTy, *Int16Ty, *Int8Ty, *Int8PtrTy; Module *CurModule; + std::string CurModuleUniqueId; Triple TargetTriple; LLVMContext *C; const DataLayout *DL; @@ -304,6 +307,7 @@ C = &(M.getContext()); DL = &M.getDataLayout(); CurModule = &M; + CurModuleUniqueId = getUniqueModuleId(CurModule); TargetTriple = Triple(M.getTargetTriple()); FunctionGuardArray = nullptr; Function8bitCounterArray = nullptr; @@ -565,17 +569,35 @@ return true; } +Comdat *SanitizerCoverageModule::GetOrCreateFunctionComdat(Function &F) { + if (auto Comdat = F.getComdat()) return Comdat; + if (!TargetTriple.isOSBinFormatELF()) return nullptr; + assert(F.hasName()); + std::string Name = F.getName(); + if (F.hasLocalLinkage()) { + if (CurModuleUniqueId.empty()) return nullptr; + Name += CurModuleUniqueId; + } + auto Comdat = CurModule->getOrInsertComdat(Name); + F.setComdat(Comdat); + return Comdat; +} + GlobalVariable *SanitizerCoverageModule::CreateFunctionLocalArrayInSection( size_t NumElements, Function &F, Type *Ty, const char *Section) { ArrayType *ArrayTy = ArrayType::get(Ty, NumElements); auto Array = new GlobalVariable( *CurModule, ArrayTy, false, GlobalVariable::PrivateLinkage, Constant::getNullValue(ArrayTy), "__sancov_gen_"); - if (auto Comdat = F.getComdat()) + if (auto Comdat = GetOrCreateFunctionComdat(F)) Array->setComdat(Comdat); Array->setSection(getSectionName(Section)); Array->setAlignment(Ty->isPointerTy() ? DL->getPointerSize() : Ty->getPrimitiveSizeInBits() / 8); + GlobalsToAppendToCompilerUsed.push_back(Array); + MDNode *MD = MDNode::get(F.getContext(), ValueAsMetadata::get(&F)); + Array->addMetadata(LLVMContext::MD_associated, *MD); + return Array; } @@ -613,23 +635,12 @@ FunctionGuardArray = CreateFunctionLocalArrayInSection( AllBlocks.size(), F, Int32Ty, SanCovGuardsSectionName); GlobalsToAppendToUsed.push_back(FunctionGuardArray); - GlobalsToAppendToCompilerUsed.push_back(FunctionGuardArray); - MDNode *MD = MDNode::get(F.getContext(), ValueAsMetadata::get(&F)); - FunctionGuardArray->addMetadata(LLVMContext::MD_associated, *MD); } - if (Options.Inline8bitCounters) { + if (Options.Inline8bitCounters) Function8bitCounterArray = CreateFunctionLocalArrayInSection( AllBlocks.size(), F, Int8Ty, SanCovCountersSectionName); - GlobalsToAppendToCompilerUsed.push_back(Function8bitCounterArray); - MDNode *MD = MDNode::get(F.getContext(), ValueAsMetadata::get(&F)); - Function8bitCounterArray->addMetadata(LLVMContext::MD_associated, *MD); - } - if (Options.PCTable) { + if (Options.PCTable) FunctionPCsArray = CreatePCArray(F, AllBlocks); - GlobalsToAppendToCompilerUsed.push_back(FunctionPCsArray); - MDNode *MD = MDNode::get(F.getContext(), ValueAsMetadata::get(&F)); - FunctionPCsArray->addMetadata(LLVMContext::MD_associated, *MD); - } } bool SanitizerCoverageModule::InjectCoverage(Function &F, Index: llvm/trunk/test/Instrumentation/SanitizerCoverage/div-tracing.ll =================================================================== --- llvm/trunk/test/Instrumentation/SanitizerCoverage/div-tracing.ll +++ llvm/trunk/test/Instrumentation/SanitizerCoverage/div-tracing.ll @@ -10,7 +10,7 @@ ret i32 %div } -; CHECK-LABEL: div_a_b +; CHECK-LABEL: @div_a_b ; CHECK: call void @__sanitizer_cov_trace_div4(i32 %b) ; CHECK: ret @@ -21,7 +21,7 @@ ret i32 %div } -; CHECK-LABEL: div_a_10 +; CHECK-LABEL: @div_a_10 ; CHECK-NOT: __sanitizer_cov_trace_div ; CHECK: ret @@ -31,7 +31,7 @@ ret i64 %div } -; CHECK-LABEL: div_a_b +; CHECK-LABEL: @div_a_b_64 ; CHECK: call void @__sanitizer_cov_trace_div8(i64 %b) ; CHECK: ret Index: llvm/trunk/test/Instrumentation/SanitizerCoverage/gep-tracing.ll =================================================================== --- llvm/trunk/test/Instrumentation/SanitizerCoverage/gep-tracing.ll +++ llvm/trunk/test/Instrumentation/SanitizerCoverage/gep-tracing.ll @@ -26,7 +26,7 @@ ret void } -; CHECK-LABEL: define void @gep_2([1000 x i32]* nocapture %a, i32 %i, i32 %j) { +; CHECK-LABEL: define void @gep_2([1000 x i32]* nocapture %a, i32 %i, i32 %j) ; CHECK: call void @__sanitizer_cov_trace_gep(i64 %idxprom1) ; CHECK: call void @__sanitizer_cov_trace_gep(i64 %idxprom) ; CHECK: ret void Index: llvm/trunk/test/Instrumentation/SanitizerCoverage/inline-8bit-counters.ll =================================================================== --- llvm/trunk/test/Instrumentation/SanitizerCoverage/inline-8bit-counters.ll +++ llvm/trunk/test/Instrumentation/SanitizerCoverage/inline-8bit-counters.ll @@ -5,7 +5,7 @@ target triple = "x86_64-unknown-linux-gnu" define void @foo() { entry: -; CHECK: section "__sancov_cntrs", align 1 +; CHECK: section "__sancov_cntrs", comdat($foo), align 1 ; CHECK: %0 = load i8, i8* getelementptr inbounds ([1 x i8], [1 x i8]* @__sancov_gen_, i64 0, i64 0), !nosanitize ; CHECK: %1 = add i8 %0, 1 ; CHECK: store i8 %1, i8* getelementptr inbounds ([1 x i8], [1 x i8]* @__sancov_gen_, i64 0, i64 0), !nosanitize Index: llvm/trunk/test/Instrumentation/SanitizerCoverage/pc-table.ll =================================================================== --- llvm/trunk/test/Instrumentation/SanitizerCoverage/pc-table.ll +++ llvm/trunk/test/Instrumentation/SanitizerCoverage/pc-table.ll @@ -17,7 +17,7 @@ ret void } -; CHECK: private constant [6 x i64*] [{{.*}}@foo{{.*}}blockaddress{{.*}}blockaddress{{.*}}], section "__sancov_pcs", align 8 +; CHECK: private constant [6 x i64*] [{{.*}}@foo{{.*}}blockaddress{{.*}}blockaddress{{.*}}], section "__sancov_pcs", comdat($foo), align 8 ; CHECK: define internal void @sancov.module_ctor ; CHECK: call void @__sanitizer_cov ; CHECK: call void @__sanitizer_cov_pcs_init Index: llvm/trunk/test/Instrumentation/SanitizerCoverage/tracing.ll =================================================================== --- llvm/trunk/test/Instrumentation/SanitizerCoverage/tracing.ll +++ llvm/trunk/test/Instrumentation/SanitizerCoverage/tracing.ll @@ -32,7 +32,7 @@ ; CHECK_PC: ret void ; CHECK_PC-NOT: call void @__sanitizer_cov_module_init -; CHECK_PC_GUARD: section "__sancov_guards", align 4 +; CHECK_PC_GUARD: section "__sancov_guards", comdat($foo), align 4 ; CHECK_PC_GUARD-LABEL: define void @foo ; CHECK_PC_GUARD: call void @__sanitizer_cov_trace_pc_guard ; CHECK_PC_GUARD: call void @__sanitizer_cov_trace_pc_guard