aboutsummaryrefslogtreecommitdiff
path: root/contrib/llvm/lib/Object/IRSymtab.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'contrib/llvm/lib/Object/IRSymtab.cpp')
-rw-r--r--contrib/llvm/lib/Object/IRSymtab.cpp58
1 files changed, 46 insertions, 12 deletions
diff --git a/contrib/llvm/lib/Object/IRSymtab.cpp b/contrib/llvm/lib/Object/IRSymtab.cpp
index 7a6424a76a98..2d8d3f7c0878 100644
--- a/contrib/llvm/lib/Object/IRSymtab.cpp
+++ b/contrib/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) {
@@ -156,6 +187,7 @@ Error Builder::addSymbol(const ModuleSymbolTable &Msymtab,
Unc = &Uncommons.back();
*Unc = {};
setStr(Unc->COFFWeakExternFallbackName, "");
+ setStr(Unc->SectionName, "");
return *Unc;
};
@@ -215,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()) {
@@ -230,16 +258,22 @@ Error Builder::addSymbol(const ModuleSymbolTable &Msymtab,
if ((Flags & object::BasicSymbolRef::SF_Weak) &&
(Flags & object::BasicSymbolRef::SF_Indirect)) {
+ auto *Fallback = dyn_cast<GlobalValue>(
+ cast<GlobalAlias>(GV)->getAliasee()->stripPointerCasts());
+ if (!Fallback)
+ return make_error<StringError>("Invalid weak external",
+ inconvertibleErrorCode());
std::string FallbackName;
raw_string_ostream OS(FallbackName);
- Msymtab.printSymbolName(
- OS, cast<GlobalValue>(
- cast<GlobalAlias>(GV)->getAliasee()->stripPointerCasts()));
+ Msymtab.printSymbolName(OS, Fallback);
OS.flush();
setStr(Uncommon().COFFWeakExternFallbackName, Saver.save(FallbackName));
}
}
+ if (!Base->getSection().empty())
+ setStr(Uncommon().SectionName, Saver.save(Base->getSection()));
+
return Error::success();
}