forked from OSchip/llvm-project
COFF: Add /alternatename option.
Previously, this feature was implemented using a special type of undefined symbol, in addition to an intricate way to make the resolver read a virtual file containing that renaming symbols. Now the feature is directly handled by the symbol table. The symbol table has a function, rename(), to rename symbols, whose definition is 4 lines long. Symbol renaming is naturally modeled using Symbol and SymbolBody. llvm-svn: 238696
This commit is contained in:
parent
a97365b8e0
commit
360bace8eb
|
@ -320,6 +320,27 @@ bool LinkerDriver::link(int Argc, const char *Argv[]) {
|
|||
}
|
||||
}
|
||||
|
||||
// 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 *Arg : Args->filtered(OPT_alternatename)) {
|
||||
StringRef From, To;
|
||||
std::tie(From, To) = StringRef(Arg->getValue()).split('=');
|
||||
if (From.empty() || To.empty()) {
|
||||
llvm::errs() << "/alternatename: invalid argument: "
|
||||
<< Arg->getValue() << "\n";
|
||||
return false;
|
||||
}
|
||||
// If it's already resolved as some Defined type, do nothing.
|
||||
// Otherwise, rename it to see if To can be resolved successfully.
|
||||
if (Symtab.find(From))
|
||||
continue;
|
||||
if (auto EC = Symtab.rename(From, To)) {
|
||||
llvm::errs() << EC.message() << "\n";
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
// Windows specific -- If entry point name is not given, we need to
|
||||
// infer that from user-defined entry name. The symbol table takes
|
||||
// care of details.
|
||||
|
|
|
@ -187,6 +187,15 @@ std::error_code SymbolTable::addUndefined(StringRef Name) {
|
|||
return addSymbol(new Undefined(Name));
|
||||
}
|
||||
|
||||
// Resolve To, and make From an alias to To.
|
||||
std::error_code SymbolTable::rename(StringRef From, StringRef To) {
|
||||
SymbolBody *Body = new (Alloc) Undefined(To);
|
||||
if (auto EC = resolve(Body))
|
||||
return EC;
|
||||
Symtab[From]->Body = Body->getReplacement();
|
||||
return std::error_code();
|
||||
}
|
||||
|
||||
std::error_code SymbolTable::addSymbol(SymbolBody *Body) {
|
||||
OwningSymbols.push_back(std::unique_ptr<SymbolBody>(Body));
|
||||
return resolve(Body);
|
||||
|
|
|
@ -68,6 +68,9 @@ public:
|
|||
// Creates an Undefined symbol for a given name.
|
||||
std::error_code addUndefined(StringRef Name);
|
||||
|
||||
// Rename From -> To in the symbol table.
|
||||
std::error_code rename(StringRef From, StringRef To);
|
||||
|
||||
private:
|
||||
std::error_code addObject(ObjectFile *File);
|
||||
std::error_code addArchive(ArchiveFile *File);
|
||||
|
|
|
@ -0,0 +1,4 @@
|
|||
# RUN: yaml2obj < %p/Inputs/ret42.yaml > %t.obj
|
||||
|
||||
# RUN: lld -flavor link2 /entry:foo /subsystem:console \
|
||||
# RUN: /alternatename:foo=mainCRTStartup /out:%t.exe %t.obj
|
Loading…
Reference in New Issue