[sancov] Put .SCOV* sections into the right comdat groups on COFF
Avoids linker errors about relocations against discarded sections.
This was uncovered during the Chromium clang roll here:
https://chromium-review.googlesource.com/c/chromium/src/+/1321863#message-717516acfcf829176f6a2f50980f7a4bdd66469a
After this change, Chromium's libGLESv2 links successfully for me.
Reviewers: metzman, hans, morehouse
Differential Revision: https://reviews.llvm.org/D54232
llvm-svn: 346381
diff --git a/llvm/lib/Transforms/Instrumentation/HWAddressSanitizer.cpp b/llvm/lib/Transforms/Instrumentation/HWAddressSanitizer.cpp
index 34a6629..9102160 100644
--- a/llvm/lib/Transforms/Instrumentation/HWAddressSanitizer.cpp
+++ b/llvm/lib/Transforms/Instrumentation/HWAddressSanitizer.cpp
@@ -743,7 +743,8 @@
appendToCompilerUsed(M, GV);
// Put GV into the F's Comadat so that if F is deleted GV can be deleted too.
if (&F != HwasanCtorFunction)
- if (auto Comdat = GetOrCreateFunctionComdat(F, CurModuleUniqueId))
+ if (auto Comdat =
+ GetOrCreateFunctionComdat(F, TargetTriple, CurModuleUniqueId))
GV->setComdat(Comdat);
}
diff --git a/llvm/lib/Transforms/Instrumentation/Instrumentation.cpp b/llvm/lib/Transforms/Instrumentation/Instrumentation.cpp
index 16976ef..eb6a373 100644
--- a/llvm/lib/Transforms/Instrumentation/Instrumentation.cpp
+++ b/llvm/lib/Transforms/Instrumentation/Instrumentation.cpp
@@ -14,6 +14,7 @@
#include "llvm/Transforms/Instrumentation.h"
#include "llvm-c/Initialization.h"
+#include "llvm/ADT/Triple.h"
#include "llvm/IR/IntrinsicInst.h"
#include "llvm/IR/Module.h"
#include "llvm/InitializePasses.h"
@@ -70,19 +71,31 @@
return GV;
}
-Comdat *llvm::GetOrCreateFunctionComdat(Function &F,
+Comdat *llvm::GetOrCreateFunctionComdat(Function &F, Triple &T,
const std::string &ModuleId) {
if (auto Comdat = F.getComdat()) return Comdat;
assert(F.hasName());
Module *M = F.getParent();
std::string Name = F.getName();
- if (F.hasLocalLinkage()) {
+
+ // Make a unique comdat name for internal linkage things on ELF. On COFF, the
+ // name of the comdat group identifies the leader symbol of the comdat group.
+ // The linkage of the leader symbol is considered during comdat resolution,
+ // and internal symbols with the same name from different objects will not be
+ // merged.
+ if (T.isOSBinFormatELF() && F.hasLocalLinkage()) {
if (ModuleId.empty())
return nullptr;
Name += ModuleId;
}
- F.setComdat(M->getOrInsertComdat(Name));
- return F.getComdat();
+
+ // Make a new comdat for the function. Use the "no duplicates" selection kind
+ // for non-weak symbols if the object file format supports it.
+ Comdat *C = M->getOrInsertComdat(Name);
+ if (T.isOSBinFormatCOFF() && !F.isWeakForLinker())
+ C->setSelectionKind(Comdat::NoDuplicates);
+ F.setComdat(C);
+ return C;
}
/// initializeInstrumentation - Initialize all passes in the TransformUtils
diff --git a/llvm/lib/Transforms/Instrumentation/SanitizerCoverage.cpp b/llvm/lib/Transforms/Instrumentation/SanitizerCoverage.cpp
index 074ae13..7f683ad 100644
--- a/llvm/lib/Transforms/Instrumentation/SanitizerCoverage.cpp
+++ b/llvm/lib/Transforms/Instrumentation/SanitizerCoverage.cpp
@@ -577,8 +577,9 @@
*CurModule, ArrayTy, false, GlobalVariable::PrivateLinkage,
Constant::getNullValue(ArrayTy), "__sancov_gen_");
- if (TargetTriple.isOSBinFormatELF())
- if (auto Comdat = GetOrCreateFunctionComdat(F, CurModuleUniqueId))
+ if (TargetTriple.supportsCOMDAT())
+ if (auto Comdat =
+ GetOrCreateFunctionComdat(F, TargetTriple, CurModuleUniqueId))
Array->setComdat(Comdat);
Array->setSection(getSectionName(Section));
Array->setAlignment(Ty->isPointerTy() ? DL->getPointerSize()