[lld] 10e28a7 - [lld/mac] Use normal Undefined machinery for dyld_stub_binder lookup

Nico Weber via llvm-commits llvm-commits at lists.llvm.org
Sun Jul 11 09:49:47 PDT 2021


Author: Nico Weber
Date: 2021-07-11T12:48:59-04:00
New Revision: 10e28a748493270e31821acc0f7f0e1a9a9b0735

URL: https://github.com/llvm/llvm-project/commit/10e28a748493270e31821acc0f7f0e1a9a9b0735
DIFF: https://github.com/llvm/llvm-project/commit/10e28a748493270e31821acc0f7f0e1a9a9b0735.diff

LOG: [lld/mac] Use normal Undefined machinery for dyld_stub_binder lookup

This is for aesthetic reasons, I'm not aware of anything that needs
this in practice. It does have a few effects:

- `-undefined dynamic_lookup` now has an effect for dyld_stub_binder.
  This matches ld64.

- `-U dyld_stub_binder` now works like you'd expect (it doesn't work in ld64).

- The error message for a missing dyld_stub_binder symbol now looks like
  other undefined reference symbols, it changes from

      symbol dyld_stub_binder not found (normally in libSystem.dylib). Needed to perform lazy binding.

  to

      error: undefined symbol: dyld_stub_binder
      >>> referenced by lazy binding (normally in libSystem.dylib)

Also add test coverage for that error message.

But in practice, this should have no interesting effects since everything links
in dyld_stub_binder via libSystem anyways.

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

Added: 
    lld/test/MachO/dyld-stub-binder.s

Modified: 
    lld/MachO/SyntheticSections.cpp

Removed: 
    


################################################################################
diff  --git a/lld/MachO/SyntheticSections.cpp b/lld/MachO/SyntheticSections.cpp
index a95dddff28a38..12c62554c2437 100644
--- a/lld/MachO/SyntheticSections.cpp
+++ b/lld/MachO/SyntheticSections.cpp
@@ -497,13 +497,17 @@ void StubHelperSection::writeTo(uint8_t *buf) const {
 }
 
 void StubHelperSection::setup() {
-  stubBinder = dyn_cast_or_null<DylibSymbol>(symtab->find("dyld_stub_binder"));
-  if (stubBinder == nullptr) {
-    error("symbol dyld_stub_binder not found (normally in libSystem.dylib). "
-          "Needed to perform lazy binding.");
+  Symbol *binder = symtab->addUndefined("dyld_stub_binder", /*file=*/nullptr,
+                                        /*isWeakRef=*/false);
+  if (auto *undefined = dyn_cast<Undefined>(binder))
+    treatUndefinedSymbol(*undefined,
+                         "lazy binding (normally in libSystem.dylib)");
+
+  // treatUndefinedSymbol() can replace binder with a DylibSymbol; re-check.
+  stubBinder = dyn_cast_or_null<DylibSymbol>(binder);
+  if (stubBinder == nullptr)
     return;
-  }
-  stubBinder->reference(RefState::Strong);
+
   in.got->addEntry(stubBinder);
 
   inputSections.push_back(in.imageLoaderCache);

diff  --git a/lld/test/MachO/dyld-stub-binder.s b/lld/test/MachO/dyld-stub-binder.s
new file mode 100644
index 0000000000000..36685580b5e1f
--- /dev/null
+++ b/lld/test/MachO/dyld-stub-binder.s
@@ -0,0 +1,59 @@
+# REQUIRES: aarch64
+# RUN: rm -rf %t; split-file %s %t
+# RUN: llvm-mc -filetype=obj -triple=arm64-apple-darwin %t/foo.s -o %t/foo.o
+# RUN: llvm-mc -filetype=obj -triple=arm64-apple-darwin %t/bar.s -o %t/bar.o
+# RUN: llvm-mc -filetype=obj -triple=arm64-apple-darwin %t/test.s -o %t/test.o
+
+## Dylibs that don't do lazy dynamic calls don't need dyld_stub_binder.
+# RUN: %lld -arch arm64 -dylib %t/foo.o -o %t/libfoo.dylib
+# RUN: llvm-nm -m %t/libfoo.dylib | FileCheck --check-prefix=NOSTUB %s
+
+## Dylibs that do lazy dynamic calls do need dyld_stub_binder.
+# RUN: not %lld -arch arm64 -dylib %t/bar.o %t/libfoo.dylib \
+# RUN:     -o %t/libbar.dylib 2>&1 | FileCheck --check-prefix=MISSINGSTUB %s
+# RUN: %lld -arch arm64 -lSystem -dylib %t/bar.o  %t/libfoo.dylib \
+# RUN:     -o %t/libbar.dylib
+# RUN: llvm-nm -m %t/libbar.dylib | FileCheck --check-prefix=STUB %s
+
+## As do executables.
+# RUN: not %lld -arch arm64 %t/libfoo.dylib %t/libbar.dylib %t/test.o \
+# RUN:     -o %t/test 2>&1 | FileCheck --check-prefix=MISSINGSTUB %s
+# RUN: %lld -arch arm64 -lSystem %t/libfoo.dylib %t/libbar.dylib %t/test.o \
+# RUN:     -o %t/test
+# RUN: llvm-nm -m %t/test | FileCheck --check-prefix=STUB %s
+
+## Test dynamic lookup of dyld_stub_binder.
+# RUN: %lld -arch arm64 %t/libfoo.dylib %t/libbar.dylib %t/test.o \
+# RUN:     -o %t/test -undefined dynamic_lookup
+# RUN: llvm-nm -m %t/test | FileCheck --check-prefix=DYNSTUB %s
+# RUN: %lld -arch arm64 %t/libfoo.dylib %t/libbar.dylib %t/test.o \
+# RUN:     -o %t/test -U dyld_stub_binder
+# RUN: llvm-nm -m %t/test | FileCheck --check-prefix=DYNSTUB %s
+
+# MISSINGSTUB:      error: undefined symbol: dyld_stub_binder
+# MISSINGSTUB-NEXT: >>> referenced by lazy binding (normally in libSystem.dylib)
+
+# NOSTUB-NOT: dyld_stub_binder
+# STUB: (undefined) external dyld_stub_binder (from libSystem)
+# DYNSTUB: (undefined) external dyld_stub_binder (dynamically looked up)
+
+#--- foo.s
+.globl _foo
+_foo:
+
+#--- bar.s
+.text
+.globl _bar
+_bar:
+  bl _foo
+  ret
+
+#--- test.s
+.text
+.globl _main
+
+.p2align 2
+_main:
+  bl _foo
+  bl _bar
+  ret


        


More information about the llvm-commits mailing list