summaryrefslogtreecommitdiffstats
path: root/llvm/lib/Transforms
diff options
context:
space:
mode:
authorJonathan Metzman <metzman@chromium.org>2018-10-12 18:11:47 +0000
committerJonathan Metzman <metzman@chromium.org>2018-10-12 18:11:47 +0000
commit0b94e880073e3f37fb1df2b31733b2b45b2d8670 (patch)
tree541888adeb4229e555c4fb56fc73b038e1289d2d /llvm/lib/Transforms
parentf45bbd4c1275fd33427c3e9a966b9e41bb173514 (diff)
downloadbcm5719-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.cpp21
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;
}
OpenPOWER on IntegriCloud