Welcome to mirror list, hosted at ThFree Co, Russian Federation.

github.com/llvm/llvm-project.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
path: root/lld
diff options
context:
space:
mode:
authorRui Ueyama <ruiu@google.com>2015-07-02 05:38:59 +0300
committerRui Ueyama <ruiu@google.com>2015-07-02 05:38:59 +0300
commit3d4c69c04de5d7fc30c5d1df430a51a5bd3c6a3d (patch)
tree8f611c4cdc3a7d1d1fe7a480ffbe697de30c7ce4 /lld
parentc3ca6e563b147b6e570b9f91d0ea5cf89624d560 (diff)
COFF: Resolve AlternateNames using weak aliases.
Previously, we use SymbolTable::rename to resolve AlternateName symbols. This patch is to merge that mechanism with weak aliases, so that we remove that function. llvm-svn: 241230
Diffstat (limited to 'lld')
-rw-r--r--lld/COFF/Driver.cpp23
-rw-r--r--lld/COFF/InputFiles.cpp2
-rw-r--r--lld/COFF/SymbolTable.cpp56
-rw-r--r--lld/COFF/SymbolTable.h8
-rw-r--r--lld/COFF/Symbols.h2
5 files changed, 33 insertions, 58 deletions
diff --git a/lld/COFF/Driver.cpp b/lld/COFF/Driver.cpp
index 85c63edee429..6db8f01f30d2 100644
--- a/lld/COFF/Driver.cpp
+++ b/lld/COFF/Driver.cpp
@@ -555,8 +555,6 @@ bool LinkerDriver::link(llvm::ArrayRef<const char *> ArgsArr) {
// A new file may contain a directive section to add new command line options.
// That's why we have to repeat until converge.)
for (;;) {
- size_t Ver = Symtab.getVersion();
-
// Windows specific -- if entry point is not found,
// search for its mangled names.
if (Config->Entry)
@@ -570,22 +568,23 @@ bool LinkerDriver::link(llvm::ArrayRef<const char *> ArgsArr) {
// Add weak aliases. Weak aliases is a mechanism to give remaining
// undefined symbols final chance to be resolved successfully.
- // This is symbol renaming.
- for (auto &P : Config->AlternateNames) {
- StringRef From = P.first;
- StringRef To = P.second;
- if (auto EC = Symtab.rename(From, To)) {
- llvm::errs() << EC.message() << "\n";
- return false;
- }
+ for (auto Pair : Config->AlternateNames) {
+ StringRef From = Pair.first;
+ StringRef To = Pair.second;
+ Symbol* Sym = Symtab.findSymbol(From);
+ if (!Sym)
+ continue;
+ if (auto *U = dyn_cast<Undefined>(Sym->Body))
+ if (!U->WeakAlias)
+ U->WeakAlias = Symtab.addUndefined(To);
}
+ if (Symtab.queueEmpty())
+ break;
if (auto EC = Symtab.run()) {
llvm::errs() << EC.message() << "\n";
return false;
}
- if (Ver == Symtab.getVersion())
- break;
}
// Make sure we have resolved all symbols.
diff --git a/lld/COFF/InputFiles.cpp b/lld/COFF/InputFiles.cpp
index 845f3e502c35..20cc25f66922 100644
--- a/lld/COFF/InputFiles.cpp
+++ b/lld/COFF/InputFiles.cpp
@@ -197,7 +197,7 @@ Undefined *ObjectFile::createWeakExternal(COFFSymbolRef Sym, const void *AuxP) {
COFFObj->getSymbolName(Sym, Name);
auto *U = new (Alloc) Undefined(Name);
auto *Aux = (const coff_aux_weak_external *)AuxP;
- U->WeakAlias = SparseSymbolBodies[Aux->TagIndex];
+ U->WeakAlias = cast<Undefined>(SparseSymbolBodies[Aux->TagIndex]);
return U;
}
diff --git a/lld/COFF/SymbolTable.cpp b/lld/COFF/SymbolTable.cpp
index 7aa662a143a6..627c9a22f55e 100644
--- a/lld/COFF/SymbolTable.cpp
+++ b/lld/COFF/SymbolTable.cpp
@@ -45,12 +45,11 @@ void SymbolTable::addFile(std::unique_ptr<InputFile> FileP) {
}
std::error_code SymbolTable::run() {
- while (!ArchiveQueue.empty() || !ObjectQueue.empty()) {
+ while (!queueEmpty()) {
if (auto EC = readArchives())
return EC;
if (auto EC = readObjects())
return EC;
- ++Version;
}
return std::error_code();
}
@@ -112,6 +111,10 @@ std::error_code SymbolTable::readObjects() {
return std::error_code();
}
+bool SymbolTable::queueEmpty() {
+ return ArchiveQueue.empty() && ObjectQueue.empty();
+}
+
bool SymbolTable::reportRemainingUndefines() {
bool Ret = false;
for (auto &I : Symtab) {
@@ -120,11 +123,12 @@ bool SymbolTable::reportRemainingUndefines() {
if (!Undef)
continue;
StringRef Name = Undef->getName();
- // The weak alias may have been resovled, so check for that.
- if (SymbolBody *Alias = Undef->WeakAlias) {
- if (auto *D = dyn_cast<Defined>(Alias->repl())) {
+ // A weak alias may have been resovled, so check for that. A weak alias
+ // may be an weak alias to other symbol, so check recursively.
+ for (Undefined *U = Undef->WeakAlias; U; U = U->WeakAlias) {
+ if (auto *D = dyn_cast<Defined>(U->repl())) {
Sym->Body = D;
- continue;
+ goto next;
}
}
// If we can resolve a symbol by removing __imp_ prefix, do that.
@@ -145,6 +149,7 @@ bool SymbolTable::reportRemainingUndefines() {
continue;
}
Ret = true;
+ next:;
}
return Ret;
}
@@ -253,44 +258,21 @@ void SymbolTable::mangleMaybe(Undefined *U) {
// In Microsoft ABI, a non-member function name is mangled this way.
std::string Prefix = ("?" + U->getName() + "@@Y").str();
- for (auto I : Symtab) {
- StringRef Name = I.first;
- Symbol *New = I.second;
+ for (auto Pair : Symtab) {
+ StringRef Name = Pair.first;
if (!Name.startswith(Prefix))
continue;
- U->WeakAlias = New->Body;
- if (auto *L = dyn_cast<Lazy>(New->Body))
- addMemberFile(L);
+ U->WeakAlias = addUndefined(Name);
return;
}
}
Undefined *SymbolTable::addUndefined(StringRef Name) {
- auto *U = new (Alloc) Undefined(Name);
- addSymbol(U);
- return U;
-}
-
-// Resolve To, and make From an alias to To.
-std::error_code SymbolTable::rename(StringRef From, StringRef To) {
- // If From is not undefined, do nothing.
- // Otherwise, rename it to see if To can be resolved instead.
- auto It = Symtab.find(From);
- if (It == Symtab.end())
- return std::error_code();
- Symbol *Sym = It->second;
- if (!isa<Undefined>(Sym->Body))
- return std::error_code();
- SymbolBody *Body = new (Alloc) Undefined(To);
- if (auto EC = addSymbol(Body))
- return EC;
- SymbolBody *Repl = Body->repl();
- if (isa<Undefined>(Repl))
- return std::error_code();
- Sym->Body = Repl;
- Body->setBackref(Sym);
- ++Version;
- return std::error_code();
+ auto *New = new (Alloc) Undefined(Name);
+ addSymbol(New);
+ if (auto *U = dyn_cast<Undefined>(New->repl()))
+ return U;
+ return New;
}
void SymbolTable::printMap(llvm::raw_ostream &OS) {
diff --git a/lld/COFF/SymbolTable.h b/lld/COFF/SymbolTable.h
index b8f2fd88f1d9..37075bdf57b7 100644
--- a/lld/COFF/SymbolTable.h
+++ b/lld/COFF/SymbolTable.h
@@ -46,7 +46,7 @@ public:
std::error_code run();
std::error_code readArchives();
std::error_code readObjects();
- size_t getVersion() { return Version; }
+ bool queueEmpty();
// Print an error message on undefined symbols.
bool reportRemainingUndefines();
@@ -85,9 +85,6 @@ public:
// Creates an Undefined symbol for a given name.
Undefined *addUndefined(StringRef Name);
- // Rename From -> To in the symbol table.
- std::error_code rename(StringRef From, StringRef To);
-
// A list of chunks which to be added to .rdata.
std::vector<Chunk *> LocalImportChunks;
@@ -107,9 +104,6 @@ private:
std::vector<BitcodeFile *> BitcodeFiles;
std::unique_ptr<MemoryBuffer> LTOMB;
llvm::BumpPtrAllocator Alloc;
-
- // This variable is incremented every time Symtab is updated.
- size_t Version = 0;
};
} // namespace coff
diff --git a/lld/COFF/Symbols.h b/lld/COFF/Symbols.h
index 949d3aeb7269..7eac93dfc68e 100644
--- a/lld/COFF/Symbols.h
+++ b/lld/COFF/Symbols.h
@@ -249,7 +249,7 @@ public:
// undefined symbol a second chance if it would remain undefined.
// If it remains undefined, it'll be replaced with whatever the
// Alias pointer points to.
- SymbolBody *WeakAlias = nullptr;
+ Undefined *WeakAlias = nullptr;
};
// Windows-specific classes.