diff options
author | Jonathan Metzman <metzman@chromium.org> | 2018-10-12 18:11:47 +0000 |
---|---|---|
committer | Jonathan Metzman <metzman@chromium.org> | 2018-10-12 18:11:47 +0000 |
commit | 0b94e880073e3f37fb1df2b31733b2b45b2d8670 (patch) | |
tree | 541888adeb4229e555c4fb56fc73b038e1289d2d /llvm/lib/Transforms | |
parent | f45bbd4c1275fd33427c3e9a966b9e41bb173514 (diff) | |
download | bcm5719-llvm-0b94e880073e3f37fb1df2b31733b2b45b2d8670.tar.gz bcm5719-llvm-0b94e880073e3f37fb1df2b31733b2b45b2d8670.zip |
[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
Diffstat (limited to 'llvm/lib/Transforms')
-rw-r--r-- | llvm/lib/Transforms/Instrumentation/SanitizerCoverage.cpp | 21 |
1 files changed, 21 insertions, 0 deletions
diff --git a/llvm/lib/Transforms/Instrumentation/SanitizerCoverage.cpp b/llvm/lib/Transforms/Instrumentation/SanitizerCoverage.cpp index bf461c61ede..0bed4139518 100644 --- a/llvm/lib/Transforms/Instrumentation/SanitizerCoverage.cpp +++ b/llvm/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 @@ 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; } |