Index: compiler-rt/trunk/test/fuzzer/windows-opt-ref.test =================================================================== --- compiler-rt/trunk/test/fuzzer/windows-opt-ref.test +++ compiler-rt/trunk/test/fuzzer/windows-opt-ref.test @@ -0,0 +1,9 @@ +REQUIRES: windows +// Verify that the linker eliminating unreferenced functions (/OPT:REF) does not +// strip sancov module constructor. +RUN: %cpp_compiler %S/SimpleCmpTest.cpp -o %t-SimpleCmpTest /link /OPT:REF + +RUN: not %run %t-SimpleCmpTest -seed=1 -runs=100000000 2>&1 | FileCheck %s + +CHECK-NOT: ERROR: no interesting inputs were found. Is the code instrumented for coverage? Exiting. +CHECK: BINGO Index: llvm/trunk/lib/Transforms/Instrumentation/SanitizerCoverage.cpp =================================================================== --- llvm/trunk/lib/Transforms/Instrumentation/SanitizerCoverage.cpp +++ llvm/trunk/lib/Transforms/Instrumentation/SanitizerCoverage.cpp @@ -29,6 +29,7 @@ #include "llvm/IR/Intrinsics.h" #include "llvm/IR/LLVMContext.h" #include "llvm/IR/MDBuilder.h" +#include "llvm/IR/Mangler.h" #include "llvm/IR/Module.h" #include "llvm/IR/Type.h" #include "llvm/Support/CommandLine.h" @@ -298,6 +299,26 @@ } else { appendToGlobalCtors(M, CtorFunc, SanCtorAndDtorPriority); } + + if (TargetTriple.getObjectFormat() == Triple::COFF) { + // In COFF files, if the contructors are set as COMDAT (they are because + // COFF supports COMDAT) and the linker flag /OPT:REF (strip unreferenced + // functions and data) is used, the constructors get stripped. To prevent + // this, give the constructors weak ODR linkage and tell the linker to + // always include the sancov constructor. This way the linker can + // deduplicate the constructors but always leave one copy. + CtorFunc->setLinkage(GlobalValue::WeakODRLinkage); + SmallString<20> PartialIncDirective("/include:"); + // Get constructor's mangled name in order to support i386. + SmallString<40> MangledName; + Mangler().getNameWithPrefix(MangledName, CtorFunc, true); + Twine IncDirective = PartialIncDirective + MangledName; + Metadata *Args[1] = {MDString::get(*C, IncDirective.str())}; + MDNode *MetadataNode = MDNode::get(*C, Args); + NamedMDNode *NamedMetadata = + M.getOrInsertNamedMetadata("llvm.linker.options"); + NamedMetadata->addOperand(MetadataNode); + } return CtorFunc; }