[lld] r217898 - [mach-o] Fix two-level namespace ordinals

Nick Kledzik kledzik at apple.com
Tue Sep 16 13:27:28 PDT 2014


Author: kledzik
Date: Tue Sep 16 15:27:28 2014
New Revision: 217898

URL: http://llvm.org/viewvc/llvm-project?rev=217898&view=rev
Log:
[mach-o] Fix two-level namespace ordinals

On darwin, the linker tools records which dylib (DSO) each undefined was found
in, and then at runtime, the loader (dyld) only looks in that one specific
dylib for each undefined symbol.  Now that llvm-objdump can display that info
I can write test cases.

Added:
    lld/trunk/test/mach-o/lazy-bind-x86_64.yaml
Modified:
    lld/trunk/lib/ReaderWriter/MachO/MachONormalizedFileFromAtoms.cpp

Modified: lld/trunk/lib/ReaderWriter/MachO/MachONormalizedFileFromAtoms.cpp
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/lib/ReaderWriter/MachO/MachONormalizedFileFromAtoms.cpp?rev=217898&r1=217897&r2=217898&view=diff
==============================================================================
--- lld/trunk/lib/ReaderWriter/MachO/MachONormalizedFileFromAtoms.cpp (original)
+++ lld/trunk/lib/ReaderWriter/MachO/MachONormalizedFileFromAtoms.cpp Tue Sep 16 15:27:28 2014
@@ -1073,23 +1073,26 @@ void Util::addRebaseAndBindingInfo(const
             nFile.bindingInfo.push_back(bind);
           }
         }
-        if (_archHandler.isLazyPointer(*ref)) {
-            BindLocation bind;
-            bind.segIndex = segmentIndex;
-            bind.segOffset = segmentOffset;
-            bind.kind = llvm::MachO::BIND_TYPE_POINTER;
-            bind.canBeNull = false; //sa->canBeNullAtRuntime();
-            bind.ordinal = 1; // FIXME
-            bind.symbolName = targ->name();
-            bind.addend = ref->addend();
-            nFile.lazyBindingInfo.push_back(bind);
+        else if (_archHandler.isLazyPointer(*ref)) {
+          BindLocation bind;
+          if (const SharedLibraryAtom *sa = dyn_cast<SharedLibraryAtom>(targ)) {
+            bind.ordinal = dylibOrdinal(sa);
+          } else {
+            bind.ordinal = llvm::MachO::BIND_SPECIAL_DYLIB_SELF;
+          }
+          bind.segIndex = segmentIndex;
+          bind.segOffset = segmentOffset;
+          bind.kind = llvm::MachO::BIND_TYPE_POINTER;
+          bind.canBeNull = false; //sa->canBeNullAtRuntime();
+          bind.symbolName = targ->name();
+          bind.addend = ref->addend();
+          nFile.lazyBindingInfo.push_back(bind);
         }
       }
     }
   }
 }
 
-
 void Util::addExportInfo(const lld::File &atomFile, NormalizedFile &nFile) {
   if (_context.outputMachOType() == llvm::MachO::MH_OBJECT)
     return;

Added: lld/trunk/test/mach-o/lazy-bind-x86_64.yaml
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/test/mach-o/lazy-bind-x86_64.yaml?rev=217898&view=auto
==============================================================================
--- lld/trunk/test/mach-o/lazy-bind-x86_64.yaml (added)
+++ lld/trunk/test/mach-o/lazy-bind-x86_64.yaml Tue Sep 16 15:27:28 2014
@@ -0,0 +1,94 @@
+# RUN: lld -flavor darwin -arch x86_64 -macosx_version_min 10.8 %s -o %t  \
+# RUN:   %p/Inputs/libSystem.yaml \
+# RUN:  && llvm-objdump -lazy-bind %t | FileCheck %s \
+# RUN:  && llvm-nm -m %t | FileCheck --check-prefix=CHECK-NM %s
+#
+# Test that correct two-level namespace ordinals are used for lazy bindings.
+#
+
+--- !mach-o
+arch:            x86_64
+file-type:       MH_OBJECT
+flags:           [ MH_SUBSECTIONS_VIA_SYMBOLS ]
+sections:
+  - segment:         __TEXT
+    section:         __text
+    type:            S_REGULAR
+    attributes:      [ S_ATTR_PURE_INSTRUCTIONS, S_ATTR_SOME_INSTRUCTIONS ]
+    address:         0x0000000000000000
+    content:         [ 0x55, 0x48, 0x89, 0xE5, 0x31, 0xC0, 0xE8, 0x00,
+                       0x00, 0x00, 0x00, 0x31, 0xC0, 0xE8, 0x00, 0x00,
+                       0x00, 0x00, 0x31, 0xC0, 0xE8, 0x00, 0x00, 0x00,
+                       0x00, 0x31, 0xC0, 0x5D, 0xC3 ]
+    relocations:
+      - offset:          0x00000015
+        type:            X86_64_RELOC_BRANCH
+        length:          2
+        pc-rel:          true
+        extern:          true
+        symbol:          3
+      - offset:          0x0000000E
+        type:            X86_64_RELOC_BRANCH
+        length:          2
+        pc-rel:          true
+        extern:          true
+        symbol:          2
+      - offset:          0x00000007
+        type:            X86_64_RELOC_BRANCH
+        length:          2
+        pc-rel:          true
+        extern:          true
+        symbol:          1
+global-symbols:
+  - name:            _main
+    type:            N_SECT
+    scope:           [ N_EXT ]
+    sect:            1
+    value:           0x0000000000000000
+undefined-symbols:
+  - name:            _bar
+    type:            N_UNDF
+    scope:           [ N_EXT ]
+    value:           0x0000000000000000
+  - name:            _baz
+    type:            N_UNDF
+    scope:           [ N_EXT ]
+    value:           0x0000000000000000
+  - name:            _foo
+    type:            N_UNDF
+    scope:           [ N_EXT ]
+    value:           0x0000000000000000
+
+--- !mach-o
+arch:            x86_64
+file-type:       MH_DYLIB
+install-name:    /usr/lib/libbar.dylib
+exports:
+  - name:            _bar
+
+--- !mach-o
+arch:            x86_64
+file-type:       MH_DYLIB
+install-name:    /usr/lib/libfoo.dylib
+exports:
+  - name:            _foo
+
+--- !mach-o
+arch:            x86_64
+file-type:       MH_DYLIB
+install-name:    /usr/lib/libbaz.dylib
+exports:
+  - name:            _baz
+
+...
+
+
+# CHECK:    libbar.dylib        _bar
+# CHECK:    libbaz.dylib        _baz
+# CHECK:    libfoo.dylib        _foo
+
+
+# CHECK-NM:   (undefined) external _bar (from libbar)
+# CHECK-NM:   (undefined) external _baz (from libbaz)
+# CHECK-NM:   (undefined) external _foo (from libfoo)
+





More information about the llvm-commits mailing list