diff --git a/lld/MachO/Config.h b/lld/MachO/Config.h index 1752f4ef3406..a01e60efbe76 100644 --- a/lld/MachO/Config.h +++ b/lld/MachO/Config.h @@ -183,6 +183,7 @@ struct Configuration { bool deadStripDylibs = false; bool demangle = false; bool deadStrip = false; + bool interposable = false; bool errorForArchMismatch = false; bool ignoreAutoLink = false; // ld64 allows invalid auto link options as long as the link succeeds. LLD diff --git a/lld/MachO/Driver.cpp b/lld/MachO/Driver.cpp index ee26fafb50b7..7070e92ddc4a 100644 --- a/lld/MachO/Driver.cpp +++ b/lld/MachO/Driver.cpp @@ -1676,6 +1676,7 @@ bool link(ArrayRef argsArr, llvm::raw_ostream &stdoutOS, // Must be set before any InputSections and Symbols are created. config->deadStrip = args.hasArg(OPT_dead_strip); + config->interposable = args.hasArg(OPT_interposable); config->systemLibraryRoots = getSystemLibraryRoots(args); if (const char *path = getReproduceOption(args)) { diff --git a/lld/MachO/Options.td b/lld/MachO/Options.td index 9179ae2d1812..4f0602f59812 100644 --- a/lld/MachO/Options.td +++ b/lld/MachO/Options.td @@ -393,6 +393,9 @@ def grp_opts : OptionGroup<"opts">, HelpText<"OPTIMIZATIONS">; def dead_strip : Flag<["-"], "dead_strip">, HelpText<"Remove unreachable functions and data">, Group; +def interposable : Flag<["-"], "interposable">, + HelpText<"Indirects access to all exported symbols in an image">, + Group; def order_file : Separate<["-"], "order_file">, MetaVarName<"">, HelpText<"Layout functions and data according to specification in ">, @@ -876,10 +879,6 @@ def setuid_safe : Flag<["-"], "setuid_safe">, HelpText<"Set the MH_SETUID_SAFE bit in the mach-o header">, Flags<[HelpHidden]>, Group; -def interposable : Flag<["-"], "interposable">, - HelpText<"Indirects access to all to exported symbols in a dylib">, - Flags<[HelpHidden]>, - Group; def multi_module : Flag<["-"], "multi_module">, Alias, HelpText<"Alias for -interposable">, diff --git a/lld/MachO/SymbolTable.cpp b/lld/MachO/SymbolTable.cpp index a61e60a944fb..ad48e909903b 100644 --- a/lld/MachO/SymbolTable.cpp +++ b/lld/MachO/SymbolTable.cpp @@ -203,9 +203,9 @@ Defined *SymbolTable::addDefined(StringRef name, InputFile *file, } // With -flat_namespace, all extern symbols in dylibs are interposable. - // FIXME: Add support for `-interposable` (PR53680). - bool interposable = config->namespaceKind == NamespaceKind::flat && - config->outputType != MachO::MH_EXECUTE && + bool interposable = ((config->namespaceKind == NamespaceKind::flat && + config->outputType != MachO::MH_EXECUTE) || + config->interposable) && !isPrivateExtern; Defined *defined = replaceSymbol( s, name, file, isec, value, size, isWeakDef, /*isExternal=*/true, diff --git a/lld/test/MachO/interposable.s b/lld/test/MachO/interposable.s new file mode 100644 index 000000000000..cfa5197c2231 --- /dev/null +++ b/lld/test/MachO/interposable.s @@ -0,0 +1,34 @@ +# REQUIRES: x86 + +# RUN: rm -rf %t; split-file %s %t +# RUN: llvm-mc -filetype=obj -triple=x86_64-apple-darwin %t/2.s -o %t/2.o +# RUN: llvm-mc -filetype=obj -triple=x86_64-apple-darwin %t/3.s -o %t/3.o +# RUN: llvm-mc -filetype=obj -triple=x86_64-apple-darwin %t/main.s -o %t/main.o + +# RUN: %lld -arch x86_64 -interposable -lSystem -o %t/main %t/main.o %t/2.o %t/3.o +# RUN: llvm-objdump --macho -d %t/main | FileCheck %s --check-prefix BUNDLE-OBJ +BUNDLE-OBJ-LABEL: _my_user: +BUNDLE-OBJ-NEXT: callq [[#%#x,]] ## symbol stub for: _my_friend + +#--- 2.s +# my_lib: This contains the exported function +.globl _my_friend +_my_friend: + retq + +#--- 3.s +# _my_user.s: This is the user/caller of the +# exported function +.text +_my_user: + callq _my_friend() + retq + +#--- main.s +# main.s: dummy exec/main loads the exported function. +# This is basically a way to say `my_user` should get +# `my_func` from this executable. +.globl _main +.text + _main: + retq