From: Rui Ueyama Date: Thu, 2 Jul 2015 02:38:59 +0000 (+0000) Subject: COFF: Resolve AlternateNames using weak aliases. X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=3d4c69c04de5d7fc30c5d1df430a51a5bd3c6a3d;p=platform%2Fupstream%2Fllvm.git 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 --- diff --git a/lld/COFF/Driver.cpp b/lld/COFF/Driver.cpp index 85c63ed..6db8f01 100644 --- a/lld/COFF/Driver.cpp +++ b/lld/COFF/Driver.cpp @@ -555,8 +555,6 @@ bool LinkerDriver::link(llvm::ArrayRef 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 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(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 845f3e50..20cc25f 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(SparseSymbolBodies[Aux->TagIndex]); return U; } diff --git a/lld/COFF/SymbolTable.cpp b/lld/COFF/SymbolTable.cpp index 7aa662a..627c9a22 100644 --- a/lld/COFF/SymbolTable.cpp +++ b/lld/COFF/SymbolTable.cpp @@ -45,12 +45,11 @@ void SymbolTable::addFile(std::unique_ptr 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(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(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(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(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(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(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 b8f2fd8..37075bd 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 LocalImportChunks; @@ -107,9 +104,6 @@ private: std::vector BitcodeFiles; std::unique_ptr 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 949d3ae..7eac93d 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.