[mach-o] Support old style objc class names in export lists
authorNick Kledzik <kledzik@apple.com>
Fri, 24 Oct 2014 22:28:54 +0000 (22:28 +0000)
committerNick Kledzik <kledzik@apple.com>
Fri, 24 Oct 2014 22:28:54 +0000 (22:28 +0000)
Objective-C switched to a new ABI which uses a different mangling for class
names.  But to keep projects building that use export lists that use the old
class name mangling, the linker recognizes the old names and transforms them
to the new mangling.

llvm-svn: 220598

lld/lib/ReaderWriter/MachO/MachOLinkingContext.cpp
lld/test/mach-o/objc_export_list.yaml [new file with mode: 0644]

index 3026957..cbadcfc 100644 (file)
@@ -715,6 +715,26 @@ bool MachOLinkingContext::sectionAligned(StringRef seg, StringRef sect,
 
 
 void MachOLinkingContext::addExportSymbol(StringRef sym) {
+  // Support old crufty export lists with bogus entries.
+  if (sym.endswith(".eh") || sym.startswith(".objc_category_name_")) {
+    llvm::errs() << "warning: ignoring " << sym << " in export list\n";
+    return;
+  }
+  // Only i386 MacOSX uses old ABI, so don't change those.
+  if ((_os != OS::macOSX) || (_arch != arch_x86)) {
+    // ObjC has two differnent ABIs.  Be nice and allow one export list work for
+    // both ABIs by renaming symbols.
+    if (sym.startswith(".objc_class_name_")) {
+      std::string abi2className("_OBJC_CLASS_$_");
+      abi2className += sym.substr(17);
+      _exportedSymbols.insert(copy(abi2className));
+      std::string abi2metaclassName("_OBJC_METACLASS_$_");
+      abi2metaclassName += sym.substr(17);
+      _exportedSymbols.insert(copy(abi2metaclassName));
+      return;
+    }
+  }
+
   // FIXME: Support wildcards.
   _exportedSymbols.insert(sym);
 }
diff --git a/lld/test/mach-o/objc_export_list.yaml b/lld/test/mach-o/objc_export_list.yaml
new file mode 100644 (file)
index 0000000..5844812
--- /dev/null
@@ -0,0 +1,63 @@
+# RUN: lld -flavor darwin -arch x86_64 -dylib %s -o %t \
+# RUN:     -exported_symbol .objc_class_name_Foo %p/Inputs/libSystem.yaml
+# RUN: llvm-nm -m %t | FileCheck %s
+#
+# Test that exported objc classes can be specificed using old naming
+# (.e.g .objc_class_name_Foo instead of _OBJC_CLASS_$_Foo)
+#
+
+--- !mach-o
+arch:            x86_64
+file-type:       MH_OBJECT
+flags:           [ MH_SUBSECTIONS_VIA_SYMBOLS ]
+sections:
+  - segment:         __DATA
+    section:         __objc_data
+    type:            S_REGULAR
+    attributes:      [  ]
+    alignment:       3
+    address:         0x0000000000000000
+    content:         [ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+                       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+                       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+                       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+                       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+                       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+                       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+                       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+                       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+                       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 ]
+    relocations:
+      - offset:          0x00000030
+        type:            X86_64_RELOC_UNSIGNED
+        length:          3
+        pc-rel:          false
+        extern:          true
+        symbol:          0
+      - offset:          0x00000028
+        type:            X86_64_RELOC_UNSIGNED
+        length:          3
+        pc-rel:          false
+        extern:          true
+        symbol:          1
+      - offset:          0x00000000
+        type:            X86_64_RELOC_UNSIGNED
+        length:          3
+        pc-rel:          false
+        extern:          true
+        symbol:          1
+global-symbols:
+  - name:            '_OBJC_CLASS_$_Foo'
+    type:            N_SECT
+    scope:           [ N_EXT ]
+    sect:            1
+    value:           0x0000000000000000
+  - name:            '_OBJC_METACLASS_$_Foo'
+    type:            N_SECT
+    scope:           [ N_EXT ]
+    sect:            1
+    value:           0x0000000000000028
+...
+
+# CHECK:  (__DATA,__objc_data) external _OBJC_CLASS_$_Foo
+# CHECK:  (__DATA,__objc_data) external _OBJC_METACLASS_$_Foo