Object: Improve COFF irsymtab comdat representation.
Change the representation of COFF comdats so that a COFF linker
is able to accurately resolve comdats between IR and native object
files. Specifically, apply name mangling to comdat names consistently
with native object files, and do not export comdats with an internal
leader because they do not affect symbol resolution.
Differential Revision: https://reviews.llvm.org/D40278
llvm-svn: 318805
diff --git a/llvm/lib/Object/IRSymtab.cpp b/llvm/lib/Object/IRSymtab.cpp
index 7fc84e2..2d8d3f7 100644
--- a/llvm/lib/Object/IRSymtab.cpp
+++ b/llvm/lib/Object/IRSymtab.cpp
@@ -72,7 +72,7 @@
BumpPtrAllocator &Alloc)
: Symtab(Symtab), StrtabBuilder(StrtabBuilder), Saver(Alloc) {}
- DenseMap<const Comdat *, unsigned> ComdatMap;
+ DenseMap<const Comdat *, int> ComdatMap;
Mangler Mang;
Triple TT;
@@ -97,6 +97,8 @@
reinterpret_cast<const char *>(Objs.data() + Objs.size()));
}
+ Expected<int> getComdatIndex(const Comdat *C, const Module *M);
+
Error addModule(Module *M);
Error addSymbol(const ModuleSymbolTable &Msymtab,
const SmallPtrSet<GlobalValue *, 8> &Used,
@@ -140,6 +142,35 @@
return Error::success();
}
+Expected<int> Builder::getComdatIndex(const Comdat *C, const Module *M) {
+ auto P = ComdatMap.insert(std::make_pair(C, Comdats.size()));
+ if (P.second) {
+ std::string Name;
+ if (TT.isOSBinFormatCOFF()) {
+ const GlobalValue *GV = M->getNamedValue(C->getName());
+ if (!GV)
+ return make_error<StringError>("Could not find leader",
+ inconvertibleErrorCode());
+ // Internal leaders do not affect symbol resolution, therefore they do not
+ // appear in the symbol table.
+ if (GV->hasLocalLinkage()) {
+ P.first->second = -1;
+ return -1;
+ }
+ llvm::raw_string_ostream OS(Name);
+ Mang.getNameWithPrefix(OS, GV, false);
+ } else {
+ Name = C->getName();
+ }
+
+ storage::Comdat Comdat;
+ setStr(Comdat.Name, Saver.save(Name));
+ Comdats.push_back(Comdat);
+ }
+
+ return P.first->second;
+}
+
Error Builder::addSymbol(const ModuleSymbolTable &Msymtab,
const SmallPtrSet<GlobalValue *, 8> &Used,
ModuleSymbolTable::Symbol Msym) {
@@ -216,14 +247,10 @@
return make_error<StringError>("Unable to determine comdat of alias!",
inconvertibleErrorCode());
if (const Comdat *C = Base->getComdat()) {
- auto P = ComdatMap.insert(std::make_pair(C, Comdats.size()));
- Sym.ComdatIndex = P.first->second;
-
- if (P.second) {
- storage::Comdat Comdat;
- setStr(Comdat.Name, C->getName());
- Comdats.push_back(Comdat);
- }
+ Expected<int> ComdatIndexOrErr = getComdatIndex(C, GV->getParent());
+ if (!ComdatIndexOrErr)
+ return ComdatIndexOrErr.takeError();
+ Sym.ComdatIndex = *ComdatIndexOrErr;
}
if (TT.isOSBinFormatCOFF()) {