diff --git a/lld/MachO/Config.h b/lld/MachO/Config.h --- a/lld/MachO/Config.h +++ b/lld/MachO/Config.h @@ -188,6 +188,8 @@ SymbolPatterns unexportedSymbols; SymbolPatterns whyLive; + llvm::DenseMap aliasedSymbols; + SymtabPresence localSymbolsPresence = SymtabPresence::All; SymbolPatterns localSymbolPatterns; diff --git a/lld/MachO/Driver.cpp b/lld/MachO/Driver.cpp --- a/lld/MachO/Driver.cpp +++ b/lld/MachO/Driver.cpp @@ -1306,6 +1306,10 @@ OPT_call_graph_profile_sort, OPT_no_call_graph_profile_sort, true); config->printSymbolOrder = args.getLastArgValue(OPT_print_symbol_order); + for (const Arg *arg : args.filtered(OPT_alias)) { + config->aliasedSymbols[arg->getValue(0)] = arg->getValue(1); + } + // FIXME: Add a commandline flag for this too. config->zeroModTime = getenv("ZERO_AR_DATE"); @@ -1558,6 +1562,22 @@ createSyntheticSections(); createSyntheticSymbols(); + for (auto pair : config->aliasedSymbols) { + if (auto *sym = symtab->find(pair.getFirst())) { + if (auto *defined = dyn_cast(sym)) { + symtab->addDefined(pair.getSecond(), defined->getFile(), + defined->isec, defined->value, defined->size, + defined->isWeakDef(), defined->privateExtern, + defined->thumb, defined->referencedDynamically, + defined->noDeadStrip, defined->weakDefCanBeHidden); + continue; + } + } + + warn("undefined base symbol '" + pair.getFirst() + "' for alias '" + + pair.getSecond() + "'\n"); + } + if (config->hasExplicitExports) { parallelForEach(symtab->getSymbols(), [](Symbol *sym) { if (auto *defined = dyn_cast(sym)) { diff --git a/lld/MachO/Options.td b/lld/MachO/Options.td --- a/lld/MachO/Options.td +++ b/lld/MachO/Options.td @@ -505,7 +505,6 @@ def alias : MultiArg<["-"], "alias", 2>, MetaVarName<" ">, HelpText<"Create a symbol alias with default global visibility">, - Flags<[HelpHidden]>, Group; def alias_list : Separate<["-"], "alias_list">, MetaVarName<"">, diff --git a/lld/test/MachO/aliases.s b/lld/test/MachO/aliases.s new file mode 100644 --- /dev/null +++ b/lld/test/MachO/aliases.s @@ -0,0 +1,45 @@ +# REQUIRES: x86 +# RUN: rm -rf %t; split-file %s %t + +# RUN: llvm-mc -filetype=obj -triple=x86_64-apple-macos -o %t/foo.o %t/foo.s +# RUN: llvm-mc -filetype=obj -triple=x86_64-apple-macos -o %t/main.o %t/main.s + +# RUN: not %lld -alias 2>&1 | FileCheck %s --check-prefix=INVALIDARG +# RUN: not %lld -alias missing_second 2>&1 | FileCheck %s --check-prefix=INVALIDARG + +# INVALIDARG: error: -alias: missing argument + +# RUN: %lld -alias _foo _bar -u _bar -exported_symbol _bar %t/main.o %t/foo.o -o %t/bar.o +# RUN: llvm-nm %t/bar.o | FileCheck %s --check-prefix=BAR + +# BAR: _bar +# BAR: _foo + +# RUN: not %lld -alias _missing _bar -alias _missing2 _baz %t/main.o -o %t/missing.o %s 2>&1 | FileCheck %s --check-prefix=MISSING + +# MISSING-DAG: undefined base symbol '_missing' for alias '_bar' +# MISSING-DAG: undefined base symbol '_missing2' for alias '_baz' + +# RUN: %lld -alias _foo _main %t/foo.o -o %t/main_rename.o +# RUN: llvm-nm %t/main_rename.o | FileCheck %s --check-prefix=MAIN + +# MAIN: _foo +# MAIN: _main + +# RUN: %lld -alias _foo _bar -alias _main _fake_main %t/main.o %t/foo.o -o %t/multiple.o +# RUN: llvm-nm %t/multiple.o | FileCheck %s --check-prefix=MULTIPLE + +# MULTIPLE: _bar +# MULTIPLE: _fake_main +# MULTIPLE: _foo +# MULTIPLE: _main + +#--- foo.s +.globl _foo +_foo: + ret + +#--- main.s +.globl _main +_main: + ret