[lld] 5be8502 - [lld-macho] Explicitly undefine literal exported symbols

Greg McGary via llvm-commits llvm-commits at lists.llvm.org
Sat May 8 11:38:01 PDT 2021


Author: Greg McGary
Date: 2021-05-08T11:37:00-07:00
New Revision: 5be8502271ac5644a7873fa801ecf537f8087d7f

URL: https://github.com/llvm/llvm-project/commit/5be8502271ac5644a7873fa801ecf537f8087d7f
DIFF: https://github.com/llvm/llvm-project/commit/5be8502271ac5644a7873fa801ecf537f8087d7f.diff

LOG: [lld-macho] Explicitly undefine literal exported symbols

Symbols explicitly exported via command-line options `--exported_symbol SYM` and `--exported_symbols_list FILE` must be defined. Before this fix, lazy symbols defined in archives would be left to languish. We now force them to be included in the linked output.

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

Added: 
    

Modified: 
    lld/MachO/Driver.cpp
    lld/test/MachO/export-options.s

Removed: 
    


################################################################################
diff  --git a/lld/MachO/Driver.cpp b/lld/MachO/Driver.cpp
index e1efac0b7ec1d..dfc92e8e1c9e4 100644
--- a/lld/MachO/Driver.cpp
+++ b/lld/MachO/Driver.cpp
@@ -1059,6 +1059,12 @@ bool macho::link(ArrayRef<const char *> argsArr, bool canExitEarly,
           ">>> ignoring unexports");
     config->unexportedSymbols.clear();
   }
+  // Explicitly-exported literal symbols must be defined, but might
+  // languish in an archive if unreferenced elsewhere. Light a fire
+  // under those lazy symbols!
+  for (const CachedHashStringRef &cachedName : config->exportedSymbols.literals)
+    symtab->addUndefined(cachedName.val(), /*file=*/nullptr,
+                         /*isWeakRef=*/false);
 
   config->saveTemps = args.hasArg(OPT_save_temps);
 
@@ -1156,7 +1162,7 @@ bool macho::link(ArrayRef<const char *> argsArr, bool canExitEarly,
       if (const Symbol *sym = symtab->find(cachedName))
         if (isa<Defined>(sym))
           continue;
-      error("undefined symbol " + cachedName.val() +
+      error("undefined symbol: " + cachedName.val() +
             "\n>>> referenced from option -exported_symbol(s_list)");
     }
 

diff  --git a/lld/test/MachO/export-options.s b/lld/test/MachO/export-options.s
index d7c904e842bc9..0ef8a3d0e1e86 100644
--- a/lld/test/MachO/export-options.s
+++ b/lld/test/MachO/export-options.s
@@ -1,7 +1,9 @@
 # REQUIRES: x86
 
-# RUN: split-file %s %t
+# RUN: rm -rf %t; split-file %s %t
 # RUN: llvm-mc -filetype=obj -triple=x86_64-apple-macos %t/default.s -o %t/default.o
+# RUN: llvm-mc -filetype=obj -triple=x86_64-apple-macos %t/lazydef.s -o %t/lazydef.o
+# RUN: llvm-ar --format=darwin rcs %t/lazydef.a %t/lazydef.o
 
 ## Check that mixing exported and unexported symbol options yields an error
 # RUN: not %lld -dylib %t/default.o -o /dev/null \
@@ -11,16 +13,28 @@
 # CONFLICT: error: cannot use both -exported_symbol* and -unexported_symbol* options
 # CONFLICT-NEXT: >>> ignoring unexports
 
-## Check that exported literal symbol name is present in symbol table
+## 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
 # RUN: not %lld -dylib %t/default.o -o /dev/null \
 # RUN:         -exported_symbol absent_literal \
 # RUN:         -exported_symbol absent_gl?b 2>&1 | \
 # RUN:     FileCheck --check-prefix=UNDEF %s
 
-# UNDEF: error: undefined symbol absent_literal
+# UNDEF: error: undefined symbol: absent_literal
 # UNDEF-NEXT: >>> referenced from option -exported_symbol(s_list)
 # UNDEF-NOT: error: {{.*}} absent_gl{{.}}b
 
+## Check that exported literal symbols are present in output's
+## symbol table, even lazy symbols which would otherwise be omitted
+# RUN: %lld -dylib %t/default.o %t/lazydef.a -o %t/lazydef \
+# RUN:         -exported_symbol _keep_globl \
+# RUN:         -exported_symbol _keep_lazy
+# RUN: llvm-objdump --syms %t/lazydef | \
+# RUN:     FileCheck --check-prefix=EXPORT %s
+
+# EXPORT-DAG: g     F __TEXT,__text _keep_globl
+# EXPORT-DAG: g     F __TEXT,__text _keep_lazy
+
 ## Check that exported symbol is global
 # RUN: not %lld -dylib %t/default.o -o /dev/null \
 # RUN:         -exported_symbol _private_extern 2>&1 | \
@@ -28,19 +42,6 @@
 
 # PRIVATE: error: cannot export hidden symbol _private_extern
 
-#--- default.s
-
-.globl _keep_globl, _hide_globl
-_keep_globl:
-  retq
-_hide_globl:
-  retq
-.private_extern _private_extern
-_private_extern:
-  retq
-_private:
-  retq
-
 ## Check that the export trie is unaltered
 # RUN: %lld -dylib %t/default.o -o %t/default
 # RUN: llvm-objdump --macho --exports-trie %t/default | \
@@ -82,6 +83,49 @@ _private:
 # RUN: llvm-mc -filetype=obj -triple=x86_64-apple-macos \
 # RUN:     %t/symdefs.s -o %t/symdefs.o
 
+## Check that only string-literal patterns match
+## Check that comments and blank lines are stripped from symbol list
+# RUN: %lld -dylib %t/symdefs.o -o %t/literal \
+# RUN:     -exported_symbols_list %t/literals.txt
+# RUN: llvm-objdump --macho --exports-trie %t/literal | \
+# RUN:     FileCheck --check-prefix=LITERAL %s
+
+# LITERAL-DAG: literal_only
+# LITERAL-DAG: literal_also
+# LITERAL-DAG: globby_also
+# LITERAL-NOT: globby_only
+
+## Check that only glob patterns match
+## Check that comments and blank lines are stripped from symbol list
+# RUN: %lld -dylib %t/symdefs.o -o %t/globby \
+# RUN:     -exported_symbols_list %t/globbys.txt
+# RUN: llvm-objdump --macho --exports-trie %t/globby | \
+# RUN:     FileCheck --check-prefix=GLOBBY %s
+
+# GLOBBY-DAG: literal_also
+# GLOBBY-DAG: globby_only
+# GLOBBY-DAG: globby_also
+# GLOBBY-NOT: literal_only
+
+#--- default.s
+
+.globl _keep_globl, _hide_globl
+_keep_globl:
+  retq
+_hide_globl:
+  retq
+.private_extern _private_extern
+_private_extern:
+  retq
+_private:
+  retq
+
+#--- lazydef.s
+
+.globl _keep_lazy
+_keep_lazy:
+  retq
+
 #--- symdefs.s
 
 .globl literal_only, literal_also, globby_only, globby_also
@@ -102,33 +146,9 @@ globby_also:
 # globby_only
   globby_also
 
-## Check that only string-literal patterns match
-## Check that comments and blank lines are stripped from symbol list
-# RUN: %lld -dylib %t/symdefs.o -o %t/literal \
-# RUN:     -exported_symbols_list %t/literals.txt
-# RUN: llvm-objdump --macho --exports-trie %t/literal | \
-# RUN:     FileCheck --check-prefix=LITERAL %s
-
-# LITERAL-DAG: literal_only
-# LITERAL-DAG: literal_also
-# LITERAL-DAG: globby_also
-# LITERAL-NOT: globby_only
-
 #--- globbys.txt
 
 # literal_only
   l?ter[aeiou]l_*[^y] # comment
 
   *gl?bby_*
-
-## Check that only glob patterns match
-## Check that comments and blank lines are stripped from symbol list
-# RUN: %lld -dylib %t/symdefs.o -o %t/globby \
-# RUN:     -exported_symbols_list %t/globbys.txt
-# RUN: llvm-objdump --macho --exports-trie %t/globby | \
-# RUN:     FileCheck --check-prefix=GLOBBY %s
-
-# GLOBBY-DAG: literal_also
-# GLOBBY-DAG: globby_only
-# GLOBBY-DAG: globby_also
-# GLOBBY-NOT: literal_only


        


More information about the llvm-commits mailing list