summaryrefslogtreecommitdiffstats
path: root/lld/ELF/SymbolTable.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'lld/ELF/SymbolTable.cpp')
-rw-r--r--lld/ELF/SymbolTable.cpp61
1 files changed, 27 insertions, 34 deletions
diff --git a/lld/ELF/SymbolTable.cpp b/lld/ELF/SymbolTable.cpp
index 08d9d0ac752..3284dd2dcce 100644
--- a/lld/ELF/SymbolTable.cpp
+++ b/lld/ELF/SymbolTable.cpp
@@ -154,19 +154,12 @@ template <class ELFT> void SymbolTable<ELFT>::resolve(SymbolBody *New) {
SymbolBody *Existing = Sym->Body;
if (Lazy *L = dyn_cast<Lazy>(Existing)) {
- if (New->isUndefined()) {
- if (New->isWeak()) {
- // See the explanation in SymbolTable::addLazy
- L->setUsedInRegularObj();
- L->setWeak();
- return;
- }
- addMemberFile(L);
+ if (auto *Undef = dyn_cast<Undefined<ELFT>>(New)) {
+ addMemberFile(Undef, L);
return;
}
-
- // Found a definition for something also in an archive. Ignore the archive
- // definition.
+ // Found a definition for something also in an archive.
+ // Ignore the archive definition.
Sym->Body = New;
return;
}
@@ -208,29 +201,14 @@ template <class ELFT> SymbolBody *SymbolTable<ELFT>::find(StringRef Name) {
return It->second->Body;
}
-template <class ELFT> void SymbolTable<ELFT>::addLazy(Lazy *New) {
- Symbol *Sym = insert(New);
- if (Sym->Body == New)
- return;
- SymbolBody *Existing = Sym->Body;
- if (Existing->isDefined() || Existing->isLazy())
- return;
- Sym->Body = New;
- assert(Existing->isUndefined() && "Unexpected symbol kind.");
-
- // Weak undefined symbols should not fetch members from archives.
- // If we were to keep old symbol we would not know that an archive member was
- // available if a strong undefined symbol shows up afterwards in the link.
- // If a strong undefined symbol never shows up, this lazy symbol will
- // get to the end of the link and must be treated as the weak undefined one.
- // We set UsedInRegularObj in a similar way to what is done with shared
- // symbols and mark it as weak to reduce how many special cases are needed.
- if (Existing->isWeak()) {
- New->setUsedInRegularObj();
- New->setWeak();
+template <class ELFT> void SymbolTable<ELFT>::addLazy(Lazy *L) {
+ Symbol *Sym = insert(L);
+ if (Sym->Body == L)
return;
+ if (auto *Undef = dyn_cast<Undefined<ELFT>>(Sym->Body)) {
+ Sym->Body = L;
+ addMemberFile(Undef, L);
}
- addMemberFile(New);
}
template <class ELFT>
@@ -247,9 +225,24 @@ void SymbolTable<ELFT>::checkCompatibility(std::unique_ptr<InputFile> &File) {
error(A + " is incompatible with " + B);
}
-template <class ELFT> void SymbolTable<ELFT>::addMemberFile(Lazy *Body) {
+template <class ELFT>
+void SymbolTable<ELFT>::addMemberFile(Undefined<ELFT> *Undef, Lazy *L) {
+ // Weak undefined symbols should not fetch members from archives.
+ // If we were to keep old symbol we would not know that an archive member was
+ // available if a strong undefined symbol shows up afterwards in the link.
+ // If a strong undefined symbol never shows up, this lazy symbol will
+ // get to the end of the link and must be treated as the weak undefined one.
+ // We set UsedInRegularObj in a similar way to what is done with shared
+ // symbols and mark it as weak to reduce how many special cases are needed.
+ if (Undef->isWeak()) {
+ L->setUsedInRegularObj();
+ L->setWeak();
+ return;
+ }
+
+ // Fetch a member file that has the definition for L.
// getMember returns nullptr if the member was already read from the library.
- if (std::unique_ptr<InputFile> File = Body->getMember())
+ if (std::unique_ptr<InputFile> File = L->getMember())
addFile(std::move(File));
}
OpenPOWER on IntegriCloud