[lld] r241230 - COFF: Resolve AlternateNames using weak aliases.
Rui Ueyama
ruiu at google.com
Wed Jul 1 19:38:59 PDT 2015
Author: ruiu
Date: Wed Jul 1 21:38:59 2015
New Revision: 241230
URL: http://llvm.org/viewvc/llvm-project?rev=241230&view=rev
Log:
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.
Modified:
lld/trunk/COFF/Driver.cpp
lld/trunk/COFF/InputFiles.cpp
lld/trunk/COFF/SymbolTable.cpp
lld/trunk/COFF/SymbolTable.h
lld/trunk/COFF/Symbols.h
Modified: lld/trunk/COFF/Driver.cpp
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/COFF/Driver.cpp?rev=241230&r1=241229&r2=241230&view=diff
==============================================================================
--- lld/trunk/COFF/Driver.cpp (original)
+++ lld/trunk/COFF/Driver.cpp Wed Jul 1 21:38:59 2015
@@ -555,8 +555,6 @@ bool LinkerDriver::link(llvm::ArrayRef<c
// 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<c
// 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.
Modified: lld/trunk/COFF/InputFiles.cpp
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/COFF/InputFiles.cpp?rev=241230&r1=241229&r2=241230&view=diff
==============================================================================
--- lld/trunk/COFF/InputFiles.cpp (original)
+++ lld/trunk/COFF/InputFiles.cpp Wed Jul 1 21:38:59 2015
@@ -197,7 +197,7 @@ Undefined *ObjectFile::createWeakExterna
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;
}
Modified: lld/trunk/COFF/SymbolTable.cpp
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/COFF/SymbolTable.cpp?rev=241230&r1=241229&r2=241230&view=diff
==============================================================================
--- lld/trunk/COFF/SymbolTable.cpp (original)
+++ lld/trunk/COFF/SymbolTable.cpp Wed Jul 1 21:38:59 2015
@@ -45,12 +45,11 @@ void SymbolTable::addFile(std::unique_pt
}
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::reportRemainingUndefin
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::reportRemainingUndefin
continue;
}
Ret = true;
+ next:;
}
return Ret;
}
@@ -253,44 +258,21 @@ void SymbolTable::mangleMaybe(Undefined
// 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) {
Modified: lld/trunk/COFF/SymbolTable.h
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/COFF/SymbolTable.h?rev=241230&r1=241229&r2=241230&view=diff
==============================================================================
--- lld/trunk/COFF/SymbolTable.h (original)
+++ lld/trunk/COFF/SymbolTable.h Wed Jul 1 21:38:59 2015
@@ -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
Modified: lld/trunk/COFF/Symbols.h
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/COFF/Symbols.h?rev=241230&r1=241229&r2=241230&view=diff
==============================================================================
--- lld/trunk/COFF/Symbols.h (original)
+++ lld/trunk/COFF/Symbols.h Wed Jul 1 21:38:59 2015
@@ -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.
More information about the llvm-commits
mailing list