[lld] 1b44364 - [lld-macho] Unreferenced weak dylib symbols shouldn't fetch archive symbols

Jez Ng via llvm-commits llvm-commits at lists.llvm.org
Sun Dec 5 12:11:54 PST 2021


Author: Jez Ng
Date: 2021-12-05T15:11:44-05:00
New Revision: 1b44364714981017302f182583a43fda4d28e0eb

URL: https://github.com/llvm/llvm-project/commit/1b44364714981017302f182583a43fda4d28e0eb
DIFF: https://github.com/llvm/llvm-project/commit/1b44364714981017302f182583a43fda4d28e0eb.diff

LOG: [lld-macho] Unreferenced weak dylib symbols shouldn't fetch archive symbols

We were fetching archive symbols too eagerly, bloating binary size as well as
just screwing up binaries that expected to look up certain symbols only at
runtime.

Reviewed By: #lld-macho, oontvoo

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

Added: 
    

Modified: 
    lld/MachO/SymbolTable.cpp
    lld/test/MachO/weak-definition-direct-fetch.s

Removed: 
    


################################################################################
diff  --git a/lld/MachO/SymbolTable.cpp b/lld/MachO/SymbolTable.cpp
index c212516a47804..cec717e0cd314 100644
--- a/lld/MachO/SymbolTable.cpp
+++ b/lld/MachO/SymbolTable.cpp
@@ -184,10 +184,18 @@ Symbol *SymbolTable::addLazy(StringRef name, ArchiveFile *file,
   bool wasInserted;
   std::tie(s, wasInserted) = insert(name, file);
 
-  if (wasInserted)
+  if (wasInserted) {
     replaceSymbol<LazySymbol>(s, file, sym);
-  else if (isa<Undefined>(s) || (isa<DylibSymbol>(s) && s->isWeakDef()))
+  } else if (isa<Undefined>(s)) {
     file->fetch(sym);
+  } else if (auto *dysym = dyn_cast<DylibSymbol>(s)) {
+    if (dysym->isWeakDef()) {
+      if (dysym->getRefState() != RefState::Unreferenced)
+        file->fetch(sym);
+      else
+        replaceSymbol<LazySymbol>(s, file, sym);
+    }
+  }
   return s;
 }
 

diff  --git a/lld/test/MachO/weak-definition-direct-fetch.s b/lld/test/MachO/weak-definition-direct-fetch.s
index 48f101a180165..8c90be506bb4e 100644
--- a/lld/test/MachO/weak-definition-direct-fetch.s
+++ b/lld/test/MachO/weak-definition-direct-fetch.s
@@ -4,7 +4,8 @@
 ## This test exercises the various possible combinations of weak and non-weak
 ## symbols that get referenced directly by a relocation in an object file.
 
-# RUN: llvm-mc -filetype=obj -triple=x86_64-apple-darwin %t/test.s -o %t/test.o
+# RUN: llvm-mc -filetype=obj -triple=x86_64-apple-darwin %t/refs-foo.s -o %t/refs-foo.o
+# RUN: llvm-mc -filetype=obj -triple=x86_64-apple-darwin %t/weak-refs-foo.s -o %t/weak-refs-foo.o
 # RUN: llvm-mc -filetype=obj -triple=x86_64-apple-darwin %t/foo.s -o %t/foo.o
 # RUN: llvm-mc -filetype=obj -triple=x86_64-apple-darwin %t/weakfoo.s -o %t/weakfoo.o
 
@@ -33,6 +34,7 @@
 # PREFER-NONWEAK-DYLIB:  __DATA __la_symbol_ptr 0x{{[0-9a-f]+}} libfoo _foo
 # PREFER-WEAK-OBJECT:    O __TEXT,weak _foo
 # PREFER-NONWEAK-OBJECT: O __TEXT,nonweak _foo
+# NO-SYM-NOT: _foo
 
 ## First, we test the cases where the symbols are of the same type (both from a
 ## dylib, or both from an archive, etc.)
@@ -40,53 +42,66 @@
 ## For dylibs and object files, the non-weak symbol always wins. But the weak
 ## flag has no effect when we are dealing with two archive symbols.
 
-# RUN: %lld -lSystem -o %t/weak-nonweak-dylibs -L%t -lweakfoo -lfoo %t/test.o
+# RUN: %lld -lSystem -o %t/weak-nonweak-dylibs -L%t -lweakfoo -lfoo %t/refs-foo.o
 # RUN: llvm-objdump --macho --lazy-bind --syms %t/weak-nonweak-dylibs | FileCheck %s --check-prefix=PREFER-NONWEAK-DYLIB
-# RUN: %lld -lSystem -o %t/nonweak-weak-dylibs -L%t -lfoo -lweakfoo %t/test.o
+# RUN: %lld -lSystem -o %t/nonweak-weak-dylibs -L%t -lfoo -lweakfoo %t/refs-foo.o
 # RUN: llvm-objdump --macho --lazy-bind --syms %t/nonweak-weak-dylibs | FileCheck %s --check-prefix=PREFER-NONWEAK-DYLIB
 
-# RUN: %lld -lSystem -o %t/weak-nonweak-objs %t/weakfoo.o %t/foo.o %t/test.o
+# RUN: %lld -lSystem -o %t/weak-nonweak-objs %t/weakfoo.o %t/foo.o %t/refs-foo.o
 # RUN: llvm-objdump --macho --lazy-bind --syms %t/weak-nonweak-objs | FileCheck %s --check-prefix=PREFER-NONWEAK-OBJECT
-# RUN: %lld -lSystem -o %t/nonweak-weak-objs %t/foo.o %t/weakfoo.o %t/test.o
+# RUN: %lld -lSystem -o %t/nonweak-weak-objs %t/foo.o %t/weakfoo.o %t/refs-foo.o
 # RUN: llvm-objdump --macho --lazy-bind --syms %t/nonweak-weak-objs | FileCheck %s --check-prefix=PREFER-NONWEAK-OBJECT
 
-# RUN: %lld -lSystem -o %t/weak-nonweak-archives %t/weakfoo.a %t/foo.a %t/test.o
+# RUN: %lld -lSystem -o %t/weak-nonweak-archives %t/weakfoo.a %t/foo.a %t/refs-foo.o
 # RUN: llvm-objdump --macho --lazy-bind --syms %t/weak-nonweak-archives | FileCheck %s --check-prefix=PREFER-WEAK-OBJECT
-# RUN: %lld -lSystem -o %t/nonweak-weak-archives %t/foo.a %t/weakfoo.a %t/test.o
+# RUN: %lld -lSystem -o %t/nonweak-weak-archives %t/foo.a %t/weakfoo.a %t/refs-foo.o
 # RUN: llvm-objdump --macho --lazy-bind --syms %t/nonweak-weak-archives | FileCheck %s --check-prefix=PREFER-NONWEAK-OBJECT
 
-## The remaining lines test symbol pairs of 
diff erent types.
+## The next 5 chunks refs-foo.symbol pairs of 
diff erent types.
 
 ## (Weak) archive symbols take precedence over weak dylib symbols.
-# RUN: %lld -lSystem -o %t/weak-dylib-weak-ar -L%t -lweakfoo %t/weakfoo.a %t/test.o
+# RUN: %lld -lSystem -o %t/weak-dylib-weak-ar -L%t -lweakfoo %t/weakfoo.a %t/refs-foo.o
 # RUN: llvm-objdump --macho --lazy-bind --syms %t/weak-dylib-weak-ar | FileCheck %s --check-prefix=PREFER-WEAK-OBJECT
-# RUN: %lld -lSystem -o %t/weak-ar-weak-dylib -L%t %t/weakfoo.a -lweakfoo %t/test.o
+# RUN: %lld -lSystem -o %t/weak-ar-weak-dylib -L%t %t/weakfoo.a -lweakfoo %t/refs-foo.o
 # RUN: llvm-objdump --macho --lazy-bind --syms %t/weak-ar-weak-dylib | FileCheck %s --check-prefix=PREFER-WEAK-OBJECT
 
 ## (Weak) archive symbols have the same precedence as dylib symbols.
-# RUN: %lld -lSystem -o %t/weak-ar-nonweak-dylib -L%t %t/weakfoo.a -lfoo %t/test.o
+# RUN: %lld -lSystem -o %t/weak-ar-nonweak-dylib -L%t %t/weakfoo.a -lfoo %t/refs-foo.o
 # RUN: llvm-objdump --macho --lazy-bind --syms %t/weak-ar-nonweak-dylib | FileCheck %s --check-prefix=PREFER-WEAK-OBJECT
-# RUN: %lld -lSystem -o %t/nonweak-dylib-weak-ar -L%t -lfoo %t/weakfoo.a %t/test.o
+# RUN: %lld -lSystem -o %t/nonweak-dylib-weak-ar -L%t -lfoo %t/weakfoo.a %t/refs-foo.o
 # RUN: llvm-objdump --macho --lazy-bind --syms %t/nonweak-dylib-weak-ar | FileCheck %s --check-prefix=PREFER-NONWEAK-DYLIB
 
 ## Weak defined symbols take precedence over weak dylib symbols.
-# RUN: %lld -lSystem -o %t/weak-dylib-weak-obj -L%t -lweakfoo %t/weakfoo.o %t/test.o
+# RUN: %lld -lSystem -o %t/weak-dylib-weak-obj -L%t -lweakfoo %t/weakfoo.o %t/refs-foo.o
 # RUN: llvm-objdump --macho --lazy-bind --syms %t/weak-dylib-weak-obj | FileCheck %s --check-prefix=PREFER-WEAK-OBJECT
-# RUN: %lld -lSystem -o %t/weak-obj-weak-dylib -L%t %t/weakfoo.o -lweakfoo %t/test.o
+# RUN: %lld -lSystem -o %t/weak-obj-weak-dylib -L%t %t/weakfoo.o -lweakfoo %t/refs-foo.o
 # RUN: llvm-objdump --macho --lazy-bind --syms %t/weak-obj-weak-dylib | FileCheck %s --check-prefix=PREFER-WEAK-OBJECT
 
 ## Weak defined symbols take precedence over dylib symbols.
-# RUN: %lld -lSystem -o %t/weak-obj-nonweak-dylib -L%t %t/weakfoo.o -lfoo %t/test.o
+# RUN: %lld -lSystem -o %t/weak-obj-nonweak-dylib -L%t %t/weakfoo.o -lfoo %t/refs-foo.o
 # RUN: llvm-objdump --macho --lazy-bind --syms %t/weak-obj-nonweak-dylib | FileCheck %s --check-prefix=PREFER-WEAK-OBJECT
-# RUN: %lld -lSystem -o %t/nonweak-dylib-weak-obj -L%t -lfoo %t/weakfoo.o %t/test.o
+# RUN: %lld -lSystem -o %t/nonweak-dylib-weak-obj -L%t -lfoo %t/weakfoo.o %t/refs-foo.o
 # RUN: llvm-objdump --macho --lazy-bind --syms %t/nonweak-dylib-weak-obj | FileCheck %s --check-prefix=PREFER-WEAK-OBJECT
 
 ## Weak defined symbols take precedence over archive symbols.
-# RUN: %lld -lSystem -o %t/weak-obj-nonweak-ar %t/weakfoo.o %t/foo.a %t/test.o
+# RUN: %lld -lSystem -o %t/weak-obj-nonweak-ar %t/weakfoo.o %t/foo.a %t/refs-foo.o
 # RUN: llvm-objdump --macho --lazy-bind --syms %t/weak-obj-nonweak-ar | FileCheck %s --check-prefix=PREFER-WEAK-OBJECT
-# RUN: %lld -lSystem -o %t/nonweak-ar-weak-obj %t/foo.a %t/weakfoo.o %t/test.o
+# RUN: %lld -lSystem -o %t/nonweak-ar-weak-obj %t/foo.a %t/weakfoo.o %t/refs-foo.o
 # RUN: llvm-objdump --macho --lazy-bind --syms %t/nonweak-ar-weak-obj | FileCheck %s --check-prefix=PREFER-WEAK-OBJECT
 
+## Regression test: A weak dylib symbol that isn't referenced by an undefined
+## symbol should not cause an archive symbol to get loaded.
+# RUN: %lld -dylib -lSystem -o %t/weak-ar-weak-unref-dylib -L%t %t/weakfoo.a -lweakfoo
+# RUN: llvm-objdump --macho --lazy-bind --syms %t/weak-ar-weak-unref-dylib | FileCheck %s --check-prefix=NO-SYM
+# RUN: %lld -dylib -lSystem -o %t/weak-unref-dylib-weak-ar -L%t -lweakfoo %t/weakfoo.a
+# RUN: llvm-objdump --macho --lazy-bind --syms %t/weak-unref-dylib-weak-ar | FileCheck %s --check-prefix=NO-SYM
+
+## However, weak references are sufficient to cause the archive to be loaded.
+# RUN: %lld -dylib -lSystem -o %t/weak-ar-weak-ref-weak-dylib -L%t %t/weakfoo.a -lweakfoo %t/weak-refs-foo.o
+# RUN: llvm-objdump --macho --lazy-bind --syms %t/weak-ar-weak-ref-weak-dylib | FileCheck %s --check-prefix=PREFER-WEAK-OBJECT
+# RUN: %lld -dylib -lSystem -o %t/weak-ref-weak-dylib-weak-ar -L%t -lweakfoo %t/weakfoo.a %t/weak-refs-foo.o
+# RUN: llvm-objdump --macho --lazy-bind --syms %t/weak-ref-weak-dylib-weak-ar | FileCheck %s --check-prefix=PREFER-WEAK-OBJECT
+
 #--- foo.s
 .globl _foo
 .section __TEXT,nonweak
@@ -98,8 +113,15 @@ _foo:
 .section __TEXT,weak
 _foo:
 
-#--- test.s
+#--- refs-foo.s
+.globl _main
+_main:
+  callq _foo
+  ret
+
+#--- weak-refs-foo.s
 .globl _main
+.weak_reference _foo
 _main:
   callq _foo
   ret


        


More information about the llvm-commits mailing list