[lld-macho] Skip platform checks for a few libSystem re-exports
authorJez Ng <jezng@fb.com>
Tue, 20 Apr 2021 23:54:41 +0000 (19:54 -0400)
committerJez Ng <jezng@fb.com>
Tue, 20 Apr 2021 23:54:53 +0000 (19:54 -0400)
XCode 12 ships with mismatched platforms for these libraries,
so this hack is necessary...

Fixes PR49799.

Reviewed By: #lld-macho, gkm, smeenai

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

lld/MachO/InputFiles.cpp
lld/test/MachO/Inputs/iPhoneSimulator.sdk/usr/lib/libSystem.tbd
lld/test/MachO/skip-platform-checks.s [new file with mode: 0644]

index c6bae08..139b4cd 100644 (file)
@@ -783,7 +783,15 @@ DylibFile::DylibFile(const InterfaceFile &interface, DylibFile *umbrella,
   compatibilityVersion = interface.getCompatibilityVersion().rawValue();
   currentVersion = interface.getCurrentVersion().rawValue();
 
-  if (!is_contained(interface.targets(), config->target)) {
+  // Some versions of XCode ship with .tbd files that don't have the right
+  // platform settings.
+  static constexpr std::array<StringRef, 3> skipPlatformChecks{
+      "/usr/lib/system/libsystem_kernel.dylib",
+      "/usr/lib/system/libsystem_platform.dylib",
+      "/usr/lib/system/libsystem_pthread.dylib"};
+
+  if (!is_contained(skipPlatformChecks, dylibName) &&
+      !is_contained(interface.targets(), config->target)) {
     error(toString(this) + " is incompatible with " +
           std::string(config->target));
     return;
@@ -825,7 +833,8 @@ DylibFile::DylibFile(const InterfaceFile &interface, DylibFile *umbrella,
 
   for (InterfaceFileRef intfRef : interface.reexportedLibraries()) {
     InterfaceFile::const_target_range targets = intfRef.targets();
-    if (is_contained(targets, config->target))
+    if (is_contained(skipPlatformChecks, intfRef.getInstallName()) ||
+        is_contained(targets, config->target))
       loadReexport(intfRef.getInstallName(), exportingFile, topLevel);
   }
 }
index ce80664..f1f1dc7 100644 (file)
@@ -8,8 +8,9 @@ install-name:     '/usr/lib/libSystem.dylib'
 current-version:  1281
 exports:
   - archs:      [ i386, x86_64, arm64 ]
-    re-exports: [ '/usr/lib/system/libcache.dylib' ]
-    symbols:    [ __crashreporter_info__, _cache_create ]
+    re-exports: [ '/usr/lib/system/libcache.dylib',
+                  '/usr/lib/system/libsystem_kernel.dylib' ]
+    symbols:    [ __crashreporter_info__, _cache_create, dyld_stub_binder ]
 --- !tapi-tbd-v3
 archs:            [ i386, x86_64, arm64 ]
 uuids:            [ 'i386: 00000000-0000-0000-0000-000000000003',
@@ -24,6 +25,18 @@ exports:
     symbols:    [ __cache_handle_memory_pressure_event ]
   - archs:      [ i386, x86_64 ]
     symbols:    [ _cache_create, _cache_destroy, _cache_get ]
+--- !tapi-tbd-v3
+archs:            [ i386, x86_64, arm64 ]
+uuids:            [ 'i386: 00000000-0000-0000-0000-000000000003',
+                    'x86_64: 00000000-0000-0000-0000-000000000004',
+                    'arm64: 00000000-0000-0000-0000-000000000005' ]
+platform:         macosx
+install-name:     '/usr/lib/system/libsystem_kernel.dylib'
+current-version:  83
+parent-umbrella:  System
+exports:
+  - archs:      [ i386, x86_64, arm64 ]
+    symbols:    [ ___fsync ]
 
 # The following TAPI document is not re-exported by any other document in this
 # TBD file, and should therefore be inaccessible.
diff --git a/lld/test/MachO/skip-platform-checks.s b/lld/test/MachO/skip-platform-checks.s
new file mode 100644 (file)
index 0000000..ce44a97
--- /dev/null
@@ -0,0 +1,12 @@
+# REQUIRES: x86, aarch64
+# RUN: llvm-mc -filetype=obj -triple=x86_64-apple-iossimulator %s -o %t.o
+## This should succeed even though libsystem_kernel.dylib has a mismatched platform.
+# RUN: ld64.lld -lSystem -arch x86_64 -platform_version ios-simulator 14.0 15.0 \
+# RUN:   -syslibroot %S/Inputs/iPhoneSimulator.sdk %t.o -o %t
+# RUN: llvm-objdump --macho --bind %t | FileCheck %s
+# CHECK: __DATA_CONST __got  0x100001000 pointer  0 libSystem  dyld_stub_binder
+
+.globl _main
+_main:
+  callq ___fsync
+  ret