summaryrefslogtreecommitdiffstats
path: root/llvm/lib/Object/IRSymtab.cpp
diff options
context:
space:
mode:
authorPeter Collingbourne <peter@pcc.me.uk>2017-11-21 22:06:20 +0000
committerPeter Collingbourne <peter@pcc.me.uk>2017-11-21 22:06:20 +0000
commit6c4846227609423e2a0922a5cefe3aac11cf2ee9 (patch)
treead0b9c865ca217703b2b87237fd79cb69fced1fc /llvm/lib/Object/IRSymtab.cpp
parentba40b0566ff0e835bc8234a4651e8cbf76181c3e (diff)
downloadbcm5719-llvm-6c4846227609423e2a0922a5cefe3aac11cf2ee9.tar.gz
bcm5719-llvm-6c4846227609423e2a0922a5cefe3aac11cf2ee9.zip
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
Diffstat (limited to 'llvm/lib/Object/IRSymtab.cpp')
-rw-r--r--llvm/lib/Object/IRSymtab.cpp45
1 files changed, 36 insertions, 9 deletions
diff --git a/llvm/lib/Object/IRSymtab.cpp b/llvm/lib/Object/IRSymtab.cpp
index 7fc84e2046c..2d8d3f7c087 100644
--- a/llvm/lib/Object/IRSymtab.cpp
+++ b/llvm/lib/Object/IRSymtab.cpp
@@ -72,7 +72,7 @@ struct Builder {
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 @@ struct Builder {
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 @@ Error Builder::addModule(Module *M) {
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 @@ Error Builder::addSymbol(const ModuleSymbolTable &Msymtab,
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()) {
OpenPOWER on IntegriCloud