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:
Rui Ueyama 2015-05-31 22:31:31 +00:00
parent a97365b8e0
commit 360bace8eb
4 changed files with 37 additions and 0 deletions

View File

@ -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.

View File

@ -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);

View File

@ -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);

View 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