forked from OSchip/llvm-project
[SanitizerCoverage] Prevent /OPT:REF from stripping constructors
Summary: Linking with the /OPT:REF linker flag when building COFF files causes the linker to strip SanitizerCoverage's constructors. Prevent this by giving the constructors WeakODR linkage and by passing the linker a directive to include sancov.module_ctor. Include a test in compiler-rt to verify libFuzzer can be linked using /OPT:REF Reviewers: morehouse, rnk Reviewed By: morehouse, rnk Subscribers: rnk, morehouse, hiraditya Differential Revision: https://reviews.llvm.org/D52119 llvm-svn: 344391
This commit is contained in:
parent
f45bbd4c12
commit
0b94e88007
|
@ -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
|
|
@ -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 @@ Function *SanitizerCoverageModule::CreateInitCallsForSections(
|
|||
} 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;
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in New Issue