summaryrefslogtreecommitdiffstats
path: root/llvm/lib
diff options
context:
space:
mode:
authorReid Kleckner <rnk@google.com>2018-08-20 23:35:45 +0000
committerReid Kleckner <rnk@google.com>2018-08-20 23:35:45 +0000
commit85a8c12db89a3b4178da29392d8191a590bfa23f (patch)
tree2448de5a74ee359f2ce53c29d057105bcbbcbc4c /llvm/lib
parentbee74793a3227cd62b4208aab08faa9631506d5c (diff)
downloadbcm5719-llvm-85a8c12db89a3b4178da29392d8191a590bfa23f.tar.gz
bcm5719-llvm-85a8c12db89a3b4178da29392d8191a590bfa23f.zip
Re-land r334313 "[asan] Instrument comdat globals on COFF targets"
If we can use comdats, then we can make it so that the global metadata is thrown away if the prevailing definition of the global was uninstrumented. I have only tested this on COFF targets, but in theory, there is no reason that we cannot also do this for ELF. This will allow us to re-enable string merging with ASan on Windows, reducing the binary size cost of ASan on Windows. I tested this change with ASan+PGO, and I fixed an issue with the __llvm_profile_raw_version symbol. With the old version of my patch, we would attempt to instrument that symbol on ELF because it had a comdat with external linkage. If we had been using the linker GC-friendly metadata scheme, everything would have worked, but clang does not enable it by default. llvm-svn: 340232
Diffstat (limited to 'llvm/lib')
-rw-r--r--llvm/lib/Transforms/Instrumentation/AddressSanitizer.cpp40
1 files changed, 32 insertions, 8 deletions
diff --git a/llvm/lib/Transforms/Instrumentation/AddressSanitizer.cpp b/llvm/lib/Transforms/Instrumentation/AddressSanitizer.cpp
index ec72e834059..15eba9089cb 100644
--- a/llvm/lib/Transforms/Instrumentation/AddressSanitizer.cpp
+++ b/llvm/lib/Transforms/Instrumentation/AddressSanitizer.cpp
@@ -1132,6 +1132,10 @@ static GlobalVariable *createPrivateGlobalForSourceLoc(Module &M,
/// Check if \p G has been created by a trusted compiler pass.
static bool GlobalWasGeneratedByCompiler(GlobalVariable *G) {
+ // Do not instrument @llvm.global_ctors, @llvm.used, etc.
+ if (G->getName().startswith("llvm."))
+ return true;
+
// Do not instrument asan globals.
if (G->getName().startswith(kAsanGenPrefix) ||
G->getName().startswith(kSanCovGenPrefix) ||
@@ -1653,14 +1657,6 @@ bool AddressSanitizerModule::ShouldInstrumentGlobal(GlobalVariable *G) {
if (!Ty->isSized()) return false;
if (!G->hasInitializer()) return false;
if (GlobalWasGeneratedByCompiler(G)) return false; // Our own globals.
- // Touch only those globals that will not be defined in other modules.
- // Don't handle ODR linkage types and COMDATs since other modules may be built
- // without ASan.
- if (G->getLinkage() != GlobalVariable::ExternalLinkage &&
- G->getLinkage() != GlobalVariable::PrivateLinkage &&
- G->getLinkage() != GlobalVariable::InternalLinkage)
- return false;
- if (G->hasComdat()) return false;
// Two problems with thread-locals:
// - The address of the main thread's copy can't be computed at link-time.
// - Need to poison all copies, not just the main thread's one.
@@ -1668,6 +1664,33 @@ bool AddressSanitizerModule::ShouldInstrumentGlobal(GlobalVariable *G) {
// For now, just ignore this Global if the alignment is large.
if (G->getAlignment() > MinRedzoneSizeForGlobal()) return false;
+ // For non-COFF targets, only instrument globals known to be defined by this
+ // TU.
+ // FIXME: We can instrument comdat globals on ELF if we are using the
+ // GC-friendly metadata scheme.
+ if (!TargetTriple.isOSBinFormatCOFF()) {
+ if (!G->hasExactDefinition() || G->hasComdat())
+ return false;
+ } else {
+ // On COFF, don't instrument non-ODR linkages.
+ if (G->isInterposable())
+ return false;
+ }
+
+ // If a comdat is present, it must have a selection kind that implies ODR
+ // semantics: no duplicates, any, or exact match.
+ if (Comdat *C = G->getComdat()) {
+ switch (C->getSelectionKind()) {
+ case Comdat::Any:
+ case Comdat::ExactMatch:
+ case Comdat::NoDuplicates:
+ break;
+ case Comdat::Largest:
+ case Comdat::SameSize:
+ return false;
+ }
+ }
+
if (G->hasSection()) {
StringRef Section = G->getSection();
@@ -2121,6 +2144,7 @@ bool AddressSanitizerModule::InstrumentGlobals(IRBuilder<> &IRB, Module &M, bool
new GlobalVariable(M, NewTy, G->isConstant(), Linkage, NewInitializer,
"", G, G->getThreadLocalMode());
NewGlobal->copyAttributesFrom(G);
+ NewGlobal->setComdat(G->getComdat());
NewGlobal->setAlignment(MinRZ);
// Move null-terminated C strings to "__asan_cstring" section on Darwin.
OpenPOWER on IntegriCloud