forked from OSchip/llvm-project
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
This commit is contained in:
parent
c3ca6e563b
commit
3d4c69c04d
|
@ -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.
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
||||
|
|
|
@ -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) {
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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.
|
||||
|
|
Loading…
Reference in New Issue