[lld] 3eb2fc4 - [lld/mac] Partially implement -export_dynamic

Nico Weber via llvm-commits llvm-commits at lists.llvm.org
Tue Jul 6 08:22:38 PDT 2021


Author: Nico Weber
Date: 2021-07-06T11:22:18-04:00
New Revision: 3eb2fc4b505159cd34f1cfe4ec2359420e44b916

URL: https://github.com/llvm/llvm-project/commit/3eb2fc4b505159cd34f1cfe4ec2359420e44b916
DIFF: https://github.com/llvm/llvm-project/commit/3eb2fc4b505159cd34f1cfe4ec2359420e44b916.diff

LOG: [lld/mac] Partially implement -export_dynamic

This implements the part of -export_dynamic that adds external
symbols as dead strip roots even for executables.

It does not yet implement the effect -export_dynamic has for LTO.
I tried just replacing `config->outputType != MH_EXECUTE` with
`(config->outputType != MH_EXECUTE || config->exportDynamic)` in
LTO.cpp, but then local symbols make it into the symbol table too,
which is too much (and also doesn't match ld64). So punt on this
for now until I understand it better.
(D91583 may or may not be related too).

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

Added: 
    

Modified: 
    lld/MachO/Config.h
    lld/MachO/Driver.cpp
    lld/MachO/LTO.cpp
    lld/MachO/MarkLive.cpp
    lld/MachO/Options.td
    lld/test/MachO/dead-strip.s

Removed: 
    


################################################################################
diff  --git a/lld/MachO/Config.h b/lld/MachO/Config.h
index f285a18f4190c..654fd794b27a4 100644
--- a/lld/MachO/Config.h
+++ b/lld/MachO/Config.h
@@ -96,6 +96,7 @@ struct Configuration {
   bool hasReexports = false;
   bool allLoad = false;
   bool archMultiple = false;
+  bool exportDynamic = false;
   bool forceLoadObjC = false;
   bool forceLoadSwift = false;
   bool staticLink = false;

diff  --git a/lld/MachO/Driver.cpp b/lld/MachO/Driver.cpp
index 28239ea95e141..f886f0e03929c 100644
--- a/lld/MachO/Driver.cpp
+++ b/lld/MachO/Driver.cpp
@@ -525,6 +525,14 @@ static void initLLVM() {
 }
 
 static void compileBitcodeFiles() {
+  // FIXME: Remove this once LTO.cpp honors config->exportDynamic.
+  if (config->exportDynamic)
+    for (InputFile *file : inputFiles)
+      if (auto *bitcodeFile = dyn_cast<BitcodeFile>(file)) {
+        warn("the effect of -export_dynamic on LTO is not yet implemented");
+        break;
+      }
+
   TimeTraceScope timeScope("LTO");
   auto *lto = make<BitcodeCompiler>();
   for (InputFile *file : inputFiles)
@@ -1140,6 +1148,7 @@ bool macho::link(ArrayRef<const char *> argsArr, bool canExitEarly,
   config->runtimePaths = args::getStrings(args, OPT_rpath);
   config->allLoad = args.hasArg(OPT_all_load);
   config->archMultiple = args.hasArg(OPT_arch_multiple);
+  config->exportDynamic = args.hasArg(OPT_export_dynamic);
   config->forceLoadObjC = args.hasArg(OPT_ObjC);
   config->forceLoadSwift = args.hasArg(OPT_force_load_swift_libs);
   config->deadStripDylibs = args.hasArg(OPT_dead_strip_dylibs);

diff  --git a/lld/MachO/LTO.cpp b/lld/MachO/LTO.cpp
index 3fa7fe4e32e59..061cda9c1054a 100644
--- a/lld/MachO/LTO.cpp
+++ b/lld/MachO/LTO.cpp
@@ -76,6 +76,7 @@ void BitcodeCompiler::add(BitcodeFile &f) {
 
     // FIXME: What about other output types? And we can probably be less
     // restrictive with -flat_namespace, but it's an infrequent use case.
+    // FIXME: Honor config->exportDynamic.
     r.VisibleToRegularObj = config->outputType != MH_EXECUTE ||
                             config->namespaceKind == NamespaceKind::flat ||
                             sym->isUsedInRegularObj;

diff  --git a/lld/MachO/MarkLive.cpp b/lld/MachO/MarkLive.cpp
index 8e2c1aa472925..116691260985e 100644
--- a/lld/MachO/MarkLive.cpp
+++ b/lld/MachO/MarkLive.cpp
@@ -79,9 +79,11 @@ void markLive() {
       // * -alias(-list)
       // * -init
 
-      // In dylibs and bundles, all external functions are GC roots.
-      // FIXME: -export_dynamic should enable this for executables too.
-      if (config->outputType != MH_EXECUTE && !defined->privateExtern) {
+      // In dylibs and bundles and in executables with -export_dynamic,
+      // all external functions are GC roots.
+      bool externsAreRoots =
+          config->outputType != MH_EXECUTE || config->exportDynamic;
+      if (externsAreRoots && !defined->privateExtern) {
         addSym(defined);
         continue;
       }

diff  --git a/lld/MachO/Options.td b/lld/MachO/Options.td
index ffaec4e96df70..b351645cedd66 100644
--- a/lld/MachO/Options.td
+++ b/lld/MachO/Options.td
@@ -424,8 +424,7 @@ def allow_stack_execute : Flag<["-"], "allow_stack_execute">,
     Flags<[HelpHidden]>,
     Group<grp_main>;
 def export_dynamic : Flag<["-"], "export_dynamic">,
-    HelpText<"Preserve all global symbols during LTO">,
-    Flags<[HelpHidden]>,
+    HelpText<"Preserve all global symbols during LTO and when dead-stripping executables">,
     Group<grp_main>;
 
 def grp_bundle : OptionGroup<"bundle">, HelpText<"CREATING A BUNDLE">;

diff  --git a/lld/test/MachO/dead-strip.s b/lld/test/MachO/dead-strip.s
index 5e18be3ca71a9..bd7fa07f58f6b 100644
--- a/lld/test/MachO/dead-strip.s
+++ b/lld/test/MachO/dead-strip.s
@@ -65,6 +65,32 @@
 # DYLIB-NEXT:   g {{.*}} _unref_extern
 # DYLIB-NEXT:   g {{.*}} _no_dead_strip_globl
 
+## Extern symbols aren't stripped from executables with -export_dynamic
+# RUN: %lld -lSystem -dead_strip -export_dynamic -u _ref_private_extern_u \
+# RUN:     %t/basics.o -o %t/basics
+# RUN: llvm-objdump --syms --section-headers %t/basics | \
+# RUN:     FileCheck --check-prefix=EXECDYN %s
+# EXECDYN-LABEL: Sections:
+# EXECDYN-LABEL: Name
+# EXECDYN-NEXT:  __text
+# EXECDYN-NEXT:  __got
+# EXECDYN-NEXT:  __ref_section
+# EXECDYN-NEXT:  __common
+# EXECDYN-LABEL: SYMBOL TABLE:
+# EXECDYN-NEXT:   l {{.*}} _ref_data
+# EXECDYN-NEXT:   l {{.*}} _ref_local
+# EXECDYN-NEXT:   l {{.*}} _ref_from_no_dead_strip_globl
+# EXECDYN-NEXT:   l {{.*}} _no_dead_strip_local
+# EXECDYN-NEXT:   l {{.*}} _ref_from_no_dead_strip_local
+# EXECDYN-NEXT:   l {{.*}} _ref_private_extern_u
+# EXECDYN-NEXT:   l {{.*}} _main
+# EXECDYN-NEXT:   l {{.*}} _ref_private_extern
+# EXECDYN-NEXT:   g {{.*}} _ref_com
+# EXECDYN-NEXT:   g {{.*}} _unref_com
+# EXECDYN-NEXT:   g {{.*}} _unref_extern
+# EXECDYN-NEXT:   g {{.*}} _no_dead_strip_globl
+# EXECDYN-NEXT:   g {{.*}} __mh_execute_header
+
 ## Absolute symbol handling.
 # RUN: llvm-mc -filetype=obj -triple=x86_64-apple-macos \
 # RUN:     %t/abs.s -o %t/abs.o


        


More information about the llvm-commits mailing list