Index: llvm/lib/Transforms/Instrumentation/SanitizerCoverage.cpp =================================================================== --- llvm/lib/Transforms/Instrumentation/SanitizerCoverage.cpp +++ llvm/lib/Transforms/Instrumentation/SanitizerCoverage.cpp @@ -571,8 +571,28 @@ auto Array = new GlobalVariable( *CurModule, ArrayTy, false, GlobalVariable::PrivateLinkage, Constant::getNullValue(ArrayTy), "__sancov_gen_"); - if (auto Comdat = F.getComdat()) + if (auto Comdat = F.getComdat()) { Array->setComdat(Comdat); + } else if (TargetTriple.isOSBinFormatELF()) { + // TODO: Refactor into a helper function and use it in ASan. + assert(F.hasName()); + std::string Name = F.getName(); + if (F.hasLocalLinkage()) { + std::string ModuleId = getUniqueModuleId(CurModule); + Name += ModuleId.empty() ? CurModule->getModuleIdentifier() : ModuleId; + } + Comdat = CurModule->getOrInsertComdat(Name); + // Make this IMAGE_COMDAT_SELECT_NODUPLICATES on COFF. Also upgrade private + // linkage to internal linkage so that a symbol table entry is emitted. This + // is necessary in order to create the comdat group. + if (TargetTriple.isOSBinFormatCOFF()) { + Comdat->setSelectionKind(Comdat::NoDuplicates); + if (F.hasPrivateLinkage()) + F.setLinkage(GlobalValue::InternalLinkage); + } + F.setComdat(Comdat); + Array->setComdat(Comdat); + } Array->setSection(getSectionName(Section)); Array->setAlignment(Ty->isPointerTy() ? DL->getPointerSize() : Ty->getPrimitiveSizeInBits() / 8);