diff --git a/include/eld/Script/Expression.h b/include/eld/Script/Expression.h index af6acd30a..faad33c38 100644 --- a/include/eld/Script/Expression.h +++ b/include/eld/Script/Expression.h @@ -331,6 +331,7 @@ class Symbol : public Expression { Expression *getRightExpression() const override { return nullptr; } mutable LDSymbol *ThisSymbol = nullptr; + const Assignment *SourceAssignment = nullptr; }; //===----------------------------------------------------------------------===// diff --git a/include/eld/Target/GNULDBackend.h b/include/eld/Target/GNULDBackend.h index ab46d82de..e18929d8a 100644 --- a/include/eld/Target/GNULDBackend.h +++ b/include/eld/Target/GNULDBackend.h @@ -20,6 +20,7 @@ #include "eld/Readers/ELFSection.h" #include "eld/Readers/SymDefReader.h" #include "eld/Script/Assignment.h" +#include "eld/Script/Expression.h" #include "eld/Script/VersionScript.h" #include "eld/SymbolResolver/ResolveInfo.h" #include "eld/Target/ELFSegment.h" @@ -824,6 +825,17 @@ class GNULDBackend { const ResolveInfo *findAbsolutePLT(ResolveInfo *I) const; + const Assignment *getLatestAssignment(llvm::StringRef SymName) { + auto it = SymbolNameToLatestAssignment.find(SymName); + if (it != SymbolNameToLatestAssignment.end()) + return it->getValue(); + return nullptr; + } + + void updateLatestAssignment(llvm::StringRef SymName, const Assignment *A) { + SymbolNameToLatestAssignment[SymName] = A; + } + protected: virtual int numReservedSegments() const { return m_NumReservedSegments; } @@ -1132,6 +1144,8 @@ class GNULDBackend { bool m_NeedEhdr = false; bool m_NeedPhdr = false; + + llvm::StringMap SymbolNameToLatestAssignment; }; } // namespace eld diff --git a/lib/Object/ObjectLinker.cpp b/lib/Object/ObjectLinker.cpp index dc1077ed5..5fc794d13 100644 --- a/lib/Object/ObjectLinker.cpp +++ b/lib/Object/ObjectLinker.cpp @@ -1716,6 +1716,7 @@ bool ObjectLinker::addScriptSymbols() { // If there is a relocation to this symbol, the symbols contained in the // assignment also need to be considered as part of the list of symbols // that will be live. + // FIXME: Duplicate redundant addAssignment! if (Symbol) ThisModule->addAssignment(Symbol->resolveInfo()->name(), AssignCmd); } diff --git a/lib/Script/Assignment.cpp b/lib/Script/Assignment.cpp index a03b762e6..808b15f7c 100644 --- a/lib/Script/Assignment.cpp +++ b/lib/Script/Assignment.cpp @@ -222,6 +222,9 @@ bool Assignment::assign(Module &CurModule, const ELFSection *Section) { ThisSymbol->setScriptValueDefined(); } + auto &Backend = CurModule.getBackend(); + Backend.updateLatestAssignment(Name, this); + if (CurModule.getPrinter()->traceAssignments()) trace(llvm::outs()); return true; diff --git a/lib/Script/Expression.cpp b/lib/Script/Expression.cpp index 1628f8e44..cfe645250 100644 --- a/lib/Script/Expression.cpp +++ b/lib/Script/Expression.cpp @@ -9,6 +9,7 @@ #include "eld/Core/LinkerScript.h" #include "eld/Core/Module.h" #include "eld/Readers/ELFSection.h" +#include "eld/Script/Assignment.h" #include "eld/Script/ScriptFile.h" #include "eld/Support/MsgHandling.h" #include "eld/Support/Utils.h" @@ -133,10 +134,17 @@ bool Symbol::hasDot() const { } eld::Expected Symbol::evalImpl() { - if (!ThisSymbol) ThisSymbol = ThisModule.getNamePool().findSymbol(Name); + if (!SourceAssignment && ThisSymbol->resolveInfo()->isAbsolute()) { + auto &Backend = ThisModule.getBackend(); + const auto *A = Backend.getLatestAssignment(Name); + if (!A) + A = ThisModule.getAssignmentForSymbol(Name); + SourceAssignment = A; + } + if (!ThisSymbol || ThisSymbol->resolveInfo()->isUndef() || ThisSymbol->resolveInfo()->isBitCode()) return std::make_unique( @@ -152,6 +160,10 @@ eld::Expected Symbol::evalImpl() { "using a symbol that points to a non allocatable section!"); return Section->addr() + FragRef->getOutputOffset(ThisModule); } + if (hasDot()) + return ThisSymbol->value(); + if (SourceAssignment) + return SourceAssignment->value(); return ThisSymbol->value(); } diff --git a/lib/Target/GNULDBackend.cpp b/lib/Target/GNULDBackend.cpp index a68890486..2aea5b14b 100644 --- a/lib/Target/GNULDBackend.cpp +++ b/lib/Target/GNULDBackend.cpp @@ -3100,6 +3100,7 @@ bool GNULDBackend::layout() { return false; } + // FIXME: Adding more symbols this late can cause layout issues. { eld::RegisterTimer T("Define Magic Symbols", "Establish Layout", m_Module.getConfig().options().printTimingStats());