[lld] [lld][MachO] Support for -interposable (PR #131813)

John Holdsworth via llvm-commits llvm-commits at lists.llvm.org
Fri Mar 21 09:02:48 PDT 2025


https://github.com/johnno1962 updated https://github.com/llvm/llvm-project/pull/131813

>From 4235b44c0ba46a237d48839ffa1b216e2a3b18bb Mon Sep 17 00:00:00 2001
From: John Holdsworth <github at johnholdsworth.com>
Date: Tue, 18 Mar 2025 17:31:40 +0100
Subject: [PATCH 1/5] [lld][MachO] Support for -interposable

---
 lld/MachO/Config.h        | 1 +
 lld/MachO/Driver.cpp      | 1 +
 lld/MachO/Options.td      | 7 +++----
 lld/MachO/SymbolTable.cpp | 6 +++---
 4 files changed, 8 insertions(+), 7 deletions(-)

diff --git a/lld/MachO/Config.h b/lld/MachO/Config.h
index f8dcc84e4ee1b..629fa2bfd0cb3 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 4f6c9b4ddc798..a335b5750b3de 100644
--- a/lld/MachO/Driver.cpp
+++ b/lld/MachO/Driver.cpp
@@ -1676,6 +1676,7 @@ bool link(ArrayRef<const char *> 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 9001e85582c12..43d4266bdca06 100644
--- a/lld/MachO/Options.td
+++ b/lld/MachO/Options.td
@@ -390,6 +390,9 @@ def grp_opts : OptionGroup<"opts">, HelpText<"OPTIMIZATIONS">;
 def dead_strip : Flag<["-"], "dead_strip">,
     HelpText<"Remove unreachable functions and data">,
     Group<grp_opts>;
+def interposable : Flag<["-"], "interposable">,
+    HelpText<"Indirects access to all to exported symbols in a dylib">,
+    Group<grp_rare>;
 def order_file : Separate<["-"], "order_file">,
     MetaVarName<"<file>">,
     HelpText<"Layout functions and data according to specification in <file>">,
@@ -873,10 +876,6 @@ def setuid_safe : Flag<["-"], "setuid_safe">,
     HelpText<"Set the MH_SETUID_SAFE bit in the mach-o header">,
     Flags<[HelpHidden]>,
     Group<grp_rare>;
-def interposable : Flag<["-"], "interposable">,
-    HelpText<"Indirects access to all to exported symbols in a dylib">,
-    Flags<[HelpHidden]>,
-    Group<grp_rare>;
 def multi_module : Flag<["-"], "multi_module">,
     Alias<interposable>,
     HelpText<"Alias for -interposable">,
diff --git a/lld/MachO/SymbolTable.cpp b/lld/MachO/SymbolTable.cpp
index a61e60a944fb4..ad48e909903b5 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<Defined>(
       s, name, file, isec, value, size, isWeakDef, /*isExternal=*/true,

>From 838c1546845078e9b71cdfe005b6e07c50b233eb Mon Sep 17 00:00:00 2001
From: John Holdsworth <github at johnholdsworth.com>
Date: Tue, 18 Mar 2025 19:41:21 +0100
Subject: [PATCH 2/5] Test for lld -interposable option.

---
 lld/MachO/Options.td          |  2 +-
 lld/test/MachO/interposable.s | 34 ++++++++++++++++++++++++++++++++++
 2 files changed, 35 insertions(+), 1 deletion(-)
 create mode 100644 lld/test/MachO/interposable.s

diff --git a/lld/MachO/Options.td b/lld/MachO/Options.td
index 43d4266bdca06..9b35e02d8baba 100644
--- a/lld/MachO/Options.td
+++ b/lld/MachO/Options.td
@@ -392,7 +392,7 @@ def dead_strip : Flag<["-"], "dead_strip">,
     Group<grp_opts>;
 def interposable : Flag<["-"], "interposable">,
     HelpText<"Indirects access to all to exported symbols in a dylib">,
-    Group<grp_rare>;
+    Group<grp_opts>;
 def order_file : Separate<["-"], "order_file">,
     MetaVarName<"<file>">,
     HelpText<"Layout functions and data according to specification in <file>">,
diff --git a/lld/test/MachO/interposable.s b/lld/test/MachO/interposable.s
new file mode 100644
index 0000000000000..344af2fe0bb14
--- /dev/null
+++ b/lld/test/MachO/interposable.s
@@ -0,0 +1,34 @@
+
+# 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 -interposable -lSystem -o %t/main %t/main.o %t/2.o %t/3.o
+# RUN: llvm-objdump  --macho --lazy-bind %t/main | FileCheck %s --check-prefix BUNDLE-OBJ
+# BUNDLE-OBJ: segment  section             address            dylib                 symbol
+# BUNDLE-OBJ: __DATA   __la_symbol_ptr     0x{{[0-9a-f]*}}    flat-namespace        _main
+# BUNDLE-OBJ: __DATA   __la_symbol_ptr     0x{{[0-9a-f]*}}    flat-namespace        my_func
+
+#--- 2.s
+# my_lib: This contains the exported function
+.globl my_func
+my_func:
+  retq
+
+#--- 3.s
+# my_user.s: This is the user/caller of the
+#            exported function
+.text
+my_user:
+  callq my_func()
+  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

>From 72e7e23ebfc4a3bdf1f588d0bcccd52f96a1f736 Mon Sep 17 00:00:00 2001
From: John Holdsworth <github at johnholdsworth.com>
Date: Wed, 19 Mar 2025 17:33:12 +0100
Subject: [PATCH 3/5] No longer .dylib only.

---
 lld/MachO/Options.td | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/lld/MachO/Options.td b/lld/MachO/Options.td
index 9b35e02d8baba..095de7e93660a 100644
--- a/lld/MachO/Options.td
+++ b/lld/MachO/Options.td
@@ -391,7 +391,7 @@ def dead_strip : Flag<["-"], "dead_strip">,
     HelpText<"Remove unreachable functions and data">,
     Group<grp_opts>;
 def interposable : Flag<["-"], "interposable">,
-    HelpText<"Indirects access to all to exported symbols in a dylib">,
+    HelpText<"Indirects access to all exported symbols in an image">,
     Group<grp_opts>;
 def order_file : Separate<["-"], "order_file">,
     MetaVarName<"<file>">,

>From 8652346160e248d21d15714d3e8f00018f20c8ca Mon Sep 17 00:00:00 2001
From: John Holdsworth <github at johnholdsworth.com>
Date: Wed, 19 Mar 2025 18:12:02 +0100
Subject: [PATCH 4/5] Tweak test.

---
 lld/test/MachO/interposable.s | 5 +++--
 1 file changed, 3 insertions(+), 2 deletions(-)

diff --git a/lld/test/MachO/interposable.s b/lld/test/MachO/interposable.s
index 344af2fe0bb14..99e778522e0fe 100644
--- a/lld/test/MachO/interposable.s
+++ b/lld/test/MachO/interposable.s
@@ -7,8 +7,9 @@
 # RUN: %lld -interposable -lSystem -o %t/main %t/main.o %t/2.o %t/3.o
 # RUN: llvm-objdump  --macho --lazy-bind %t/main | FileCheck %s --check-prefix BUNDLE-OBJ
 # BUNDLE-OBJ: segment  section             address            dylib                 symbol
-# BUNDLE-OBJ: __DATA   __la_symbol_ptr     0x{{[0-9a-f]*}}    flat-namespace        _main
-# BUNDLE-OBJ: __DATA   __la_symbol_ptr     0x{{[0-9a-f]*}}    flat-namespace        my_func
+# BUNDLE-OBJ-NEXT: __DATA   __la_symbol_ptr     0x[[#%x,]]    flat-namespace        _main
+# BUNDLE-OBJ: __DATA   __la_symbol_ptr     0x[[#%x,]]    flat-namespace        my_func
+# BUNDLE-OBJ-EMPTY:
 
 #--- 2.s
 # my_lib: This contains the exported function

>From e6b529e3d9e0caf411836748982a6d77ca0402a1 Mon Sep 17 00:00:00 2001
From: John Holdsworth <github at johnholdsworth.com>
Date: Fri, 21 Mar 2025 17:02:31 +0100
Subject: [PATCH 5/5] Check non-interposed.

---
 lld/test/MachO/interposable.s | 15 ++++++++++-----
 1 file changed, 10 insertions(+), 5 deletions(-)

diff --git a/lld/test/MachO/interposable.s b/lld/test/MachO/interposable.s
index 99e778522e0fe..17d199322429b 100644
--- a/lld/test/MachO/interposable.s
+++ b/lld/test/MachO/interposable.s
@@ -4,12 +4,17 @@
 # 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 -lSystem -o %t/main %t/main.o %t/2.o %t/3.o
+# RUN: llvm-objdump  --macho --lazy-bind %t/main | FileCheck %s --check-prefix BASE-OBJ
+# BASE-OBJ: segment  section             address            dylib                 symbol
+# BASE-OBJ-EMPTY:
+
 # RUN: %lld -interposable -lSystem -o %t/main %t/main.o %t/2.o %t/3.o
-# RUN: llvm-objdump  --macho --lazy-bind %t/main | FileCheck %s --check-prefix BUNDLE-OBJ
-# BUNDLE-OBJ: segment  section             address            dylib                 symbol
-# BUNDLE-OBJ-NEXT: __DATA   __la_symbol_ptr     0x[[#%x,]]    flat-namespace        _main
-# BUNDLE-OBJ: __DATA   __la_symbol_ptr     0x[[#%x,]]    flat-namespace        my_func
-# BUNDLE-OBJ-EMPTY:
+# RUN: llvm-objdump  --macho --lazy-bind %t/main | FileCheck %s --check-prefix INTER-OBJ
+# INTER-OBJ: segment  section             address            dylib                 symbol
+# INTER-OBJ-NEXT: __DATA   __la_symbol_ptr     0x[[#%x,]]    flat-namespace        _main
+# INTER-OBJ: __DATA   __la_symbol_ptr     0x[[#%x,]]    flat-namespace        my_func
+# INTER-OBJ-EMPTY:
 
 #--- 2.s
 # my_lib: This contains the exported function



More information about the llvm-commits mailing list