[lld] 272bf0f - [lld-macho] Add support for exporting no symbols

Keith Smiley via llvm-commits llvm-commits at lists.llvm.org
Wed Jun 15 15:07:39 PDT 2022


Author: Keith Smiley
Date: 2022-06-15T15:07:27-07:00
New Revision: 272bf0fc41e6a50f89dd01b55a33a3aabcdaf5a8

URL: https://github.com/llvm/llvm-project/commit/272bf0fc41e6a50f89dd01b55a33a3aabcdaf5a8
DIFF: https://github.com/llvm/llvm-project/commit/272bf0fc41e6a50f89dd01b55a33a3aabcdaf5a8.diff

LOG: [lld-macho] Add support for exporting no symbols

As an optimization for ld64 sometimes it can be useful to not export any
symbols for top level binaries that don't need any exports, to do this
you can pass `-exported_symbols_list /dev/null`, or new with Xcode 14
(ld64 816) there is a `-no_exported_symbols` flag for the same behavior.
This reproduces this behavior where previously an empty exported symbols
list file would have been ignored.

Differential Revision: https://reviews.llvm.org/D127562

Added: 
    

Modified: 
    lld/MachO/Config.h
    lld/MachO/Driver.cpp
    lld/MachO/Options.td
    lld/test/MachO/export-options.s

Removed: 
    


################################################################################
diff  --git a/lld/MachO/Config.h b/lld/MachO/Config.h
index 69e42c596d16c..87fdbf092012d 100644
--- a/lld/MachO/Config.h
+++ b/lld/MachO/Config.h
@@ -185,6 +185,7 @@ struct Configuration {
   SectionRenameMap sectionRenameMap;
   SegmentRenameMap segmentRenameMap;
 
+  bool hasExplicitExports = false;
   SymbolPatterns exportedSymbols;
   SymbolPatterns unexportedSymbols;
   SymbolPatterns whyLive;

diff  --git a/lld/MachO/Driver.cpp b/lld/MachO/Driver.cpp
index 0a86b09f911bb..eb661afae454e 100644
--- a/lld/MachO/Driver.cpp
+++ b/lld/MachO/Driver.cpp
@@ -1403,15 +1403,18 @@ bool macho::link(ArrayRef<const char *> argsArr, llvm::raw_ostream &stdoutOS,
     config->segmentProtections.push_back({segName, maxProt, initProt});
   }
 
+  config->hasExplicitExports =
+      args.hasArg(OPT_no_exported_symbols) ||
+      args.hasArgNoClaim(OPT_exported_symbol, OPT_exported_symbols_list);
   handleSymbolPatterns(args, config->exportedSymbols, OPT_exported_symbol,
                        OPT_exported_symbols_list);
   handleSymbolPatterns(args, config->unexportedSymbols, OPT_unexported_symbol,
                        OPT_unexported_symbols_list);
-  if (!config->exportedSymbols.empty() && !config->unexportedSymbols.empty()) {
-    error("cannot use both -exported_symbol* and -unexported_symbol* options\n"
-          ">>> ignoring unexports");
-    config->unexportedSymbols.clear();
-  }
+  if (config->hasExplicitExports && !config->unexportedSymbols.empty())
+    error("cannot use both -exported_symbol* and -unexported_symbol* options");
+
+  if (args.hasArg(OPT_no_exported_symbols) && !config->exportedSymbols.empty())
+    error("cannot use both -exported_symbol* and -no_exported_symbols options");
 
   // Imitating LD64's:
   // -non_global_symbols_no_strip_list and -non_global_symbols_strip_list can't
@@ -1555,7 +1558,7 @@ bool macho::link(ArrayRef<const char *> argsArr, llvm::raw_ostream &stdoutOS,
     createSyntheticSections();
     createSyntheticSymbols();
 
-    if (!config->exportedSymbols.empty()) {
+    if (config->hasExplicitExports) {
       parallelForEach(symtab->getSymbols(), [](Symbol *sym) {
         if (auto *defined = dyn_cast<Defined>(sym)) {
           StringRef symbolName = defined->getName();

diff  --git a/lld/MachO/Options.td b/lld/MachO/Options.td
index 291e55c9402aa..b4092c7ec80aa 100644
--- a/lld/MachO/Options.td
+++ b/lld/MachO/Options.td
@@ -483,6 +483,9 @@ def exported_symbols_list : Separate<["-"], "exported_symbols_list">,
     MetaVarName<"<file>">,
     HelpText<"Symbols specified in <file> remain global, while others become private externs">,
     Group<grp_resolve>;
+def no_exported_symbols : Flag<["-"], "no_exported_symbols">,
+    HelpText<"Don't export any symbols from the binary, useful for main executables that don't have plugins">,
+    Group<grp_resolve>;
 def unexported_symbol : Separate<["-"], "unexported_symbol">,
     MetaVarName<"<symbol>">,
     HelpText<"Global <symbol> becomes private extern">,

diff  --git a/lld/test/MachO/export-options.s b/lld/test/MachO/export-options.s
index 654834ecba121..5ec52d15cfd96 100644
--- a/lld/test/MachO/export-options.s
+++ b/lld/test/MachO/export-options.s
@@ -9,9 +9,26 @@
 # RUN: not %lld -dylib %t/default.o -o /dev/null \
 # RUN:         -exported_symbol a -unexported_symbol b 2>&1 | \
 # RUN:     FileCheck --check-prefix=CONFLICT %s
+#
+# RUN: not %lld -dylib %t/default.o -o /dev/null \
+# RUN:         -exported_symbols_list /dev/null -unexported_symbol b 2>&1 | \
+# RUN:     FileCheck --check-prefix=CONFLICT %s
+#
+# RUN: not %lld -dylib %t/default.o -o /dev/null \
+# RUN:         -no_exported_symbols -unexported_symbol b 2>&1 | \
+# RUN:     FileCheck --check-prefix=CONFLICT %s
+#
+# RUN: not %lld -dylib %t/default.o -o /dev/null \
+# RUN:         -no_exported_symbols -exported_symbol b 2>&1 | \
+# RUN:     FileCheck --check-prefix=CONFLICT-NO-EXPORTS %s
+#
+# RUN: not %lld -dylib %t/default.o -o /dev/null \
+# RUN:         -no_exported_symbols -exported_symbols_list %t/literals.txt 2>&1 | \
+# RUN:     FileCheck --check-prefix=CONFLICT-NO-EXPORTS %s
 
 # CONFLICT: error: cannot use both -exported_symbol* and -unexported_symbol* options
-# CONFLICT-NEXT: >>> ignoring unexports
+
+# CONFLICT-NO-EXPORTS: error: cannot use both -exported_symbol* and -no_exported_symbols options
 
 ## Check that an exported literal name with no symbol definition yields an error
 ## but that an exported glob-pattern with no matching symbol definition is OK
@@ -162,6 +179,17 @@
 # AUTOHIDE-PRIVATE: error: cannot export hidden symbol _foo
 # AUTOHIDE-PRIVATE-DEAD-STRIP: (__TEXT,__text) non-external (was a private external) _foo
 
+## Test not exporting any symbols
+# RUN: %lld -dylib %t/symdefs.o -o %t/noexports -exported_symbols_list /dev/null
+# RUN: llvm-objdump --macho --exports-trie %t/noexports | FileCheck --check-prefix=NOEXPORTS %s
+# RUN: %lld -dylib %t/symdefs.o -o %t/noexports -no_exported_symbols
+# RUN: llvm-objdump --macho --exports-trie %t/noexports | FileCheck --check-prefix=NOEXPORTS %s
+
+# NOEXPORTS-NOT: globby_also
+# NOEXPORTS-NOT: globby_only
+# NOEXPORTS-NOT: literal_also
+# NOEXPORTS-NOT: literal_only
+
 #--- default.s
 
 .globl _keep_globl, _hide_globl


        


More information about the llvm-commits mailing list