[lld] 9282d04 - [lld-macho] Support lookup of dylibs in frameworks

Jez Ng via llvm-commits llvm-commits at lists.llvm.org
Sun Jul 26 12:47:14 PDT 2020


Author: Jez Ng
Date: 2020-07-26T12:46:46-07:00
New Revision: 9282d04e041c4dd21d3af8463e2cb30964a9272c

URL: https://github.com/llvm/llvm-project/commit/9282d04e041c4dd21d3af8463e2cb30964a9272c
DIFF: https://github.com/llvm/llvm-project/commit/9282d04e041c4dd21d3af8463e2cb30964a9272c.diff

LOG: [lld-macho] Support lookup of dylibs in frameworks

Needed for testing Objective-C programs (since e.g. Core
Foundation is a framework)

Reviewed By: #lld-macho, compnerd

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

Added: 
    lld/test/MachO/framework.s

Modified: 
    lld/MachO/Config.h
    lld/MachO/Driver.cpp

Removed: 
    


################################################################################
diff  --git a/lld/MachO/Config.h b/lld/MachO/Config.h
index 79812a433563..c66991b581fc 100644
--- a/lld/MachO/Config.h
+++ b/lld/MachO/Config.h
@@ -30,7 +30,6 @@ struct Configuration {
   llvm::MachO::Architecture arch;
   llvm::MachO::HeaderFileType outputType;
   std::vector<llvm::StringRef> librarySearchPaths;
-  // TODO: use the framework search paths
   std::vector<llvm::StringRef> frameworkSearchPaths;
   llvm::DenseMap<llvm::StringRef, SymbolPriorityEntry> priorities;
 };

diff  --git a/lld/MachO/Driver.cpp b/lld/MachO/Driver.cpp
index 4dfb387e4e62..ee794129e1fc 100644
--- a/lld/MachO/Driver.cpp
+++ b/lld/MachO/Driver.cpp
@@ -30,6 +30,7 @@
 #include "llvm/Object/Archive.h"
 #include "llvm/Option/ArgList.h"
 #include "llvm/Option/Option.h"
+#include "llvm/Support/FileSystem.h"
 #include "llvm/Support/Host.h"
 #include "llvm/Support/MemoryBuffer.h"
 #include "llvm/Support/Path.h"
@@ -98,6 +99,32 @@ static Optional<std::string> findLibrary(StringRef name) {
   return {};
 }
 
+static Optional<std::string> findFramework(StringRef name) {
+  // TODO: support .tbd files
+  llvm::SmallString<260> symlink;
+  llvm::SmallString<260> location;
+  StringRef suffix;
+  std::tie(name, suffix) = name.split(",");
+  for (StringRef dir : config->frameworkSearchPaths) {
+    symlink = dir;
+    path::append(symlink, name + ".framework", name);
+    // If the symlink fails to resolve, skip to the next search path.
+    // NOTE: we must resolve the symlink before trying the suffixes, because
+    // there are no symlinks for the suffixed paths.
+    if (fs::real_path(symlink, location))
+      continue;
+    if (!suffix.empty()) {
+      llvm::Twine suffixed = location + suffix;
+      if (fs::exists(suffixed))
+        return suffixed.str();
+      // Suffix lookup failed, fall through to the no-suffix case.
+    }
+    if (fs::exists(location))
+      return location.str().str();
+  }
+  return {};
+}
+
 static TargetInfo *createTargetInfo(opt::InputArgList &args) {
   StringRef arch = args.getLastArgValue(OPT_arch, "x86_64");
   config->arch = llvm::MachO::getArchitectureFromName(
@@ -393,13 +420,24 @@ bool macho::link(llvm::ArrayRef<const char *> argsArr, bool canExitEarly,
       error("library not found for -l" + name);
       break;
     }
+    case OPT_framework: {
+      StringRef name = arg->getValue();
+      if (Optional<std::string> path = findFramework(name)) {
+        addFile(*path);
+        break;
+      }
+      error("framework not found for -framework " + name);
+      break;
+    }
     case OPT_platform_version:
       handlePlatformVersion(arg);
       break;
     case OPT_o:
     case OPT_dylib:
     case OPT_e:
+    case OPT_F:
     case OPT_L:
+    case OPT_install_name:
     case OPT_Z:
     case OPT_arch:
       // handled elsewhere

diff  --git a/lld/test/MachO/framework.s b/lld/test/MachO/framework.s
new file mode 100644
index 000000000000..a527970ed6bc
--- /dev/null
+++ b/lld/test/MachO/framework.s
@@ -0,0 +1,29 @@
+# REQUIRES: x86, shell
+# RUN: mkdir -p %t
+# RUN: echo ".globl _foo; _foo: ret" | llvm-mc -filetype=obj -triple=x86_64-apple-darwin -o %t/foo.o
+# RUN: mkdir -p %t/Foo.framework/Versions/A
+# RUN: lld -flavor darwinnew -L%S/Inputs/MacOSX.sdk/usr/lib -dylib -install_name %t/Foo.framework/Versions/A/Foo %t/foo.o -o %t/Foo.framework/Versions/A/Foo
+# RUN: lld -flavor darwinnew -L%S/Inputs/MacOSX.sdk/usr/lib -dylib -install_name %t/Foo.framework/Versions/A/Foobar %t/foo.o -o %t/Foo.framework/Versions/A/Foobar
+# RUN: ln -sf %t/Foo.framework/Versions/A %t/Foo.framework/Versions/Current
+# RUN: ln -sf %t/Foo.framework/Versions/Current/Foo %t/Foo.framework/Foo
+
+# RUN: llvm-mc -filetype=obj -triple=x86_64-apple-darwin -o %t/test.o %s
+# RUN: lld -flavor darwinnew -L%S/Inputs/MacOSX.sdk/usr/lib -lSystem -F%t -framework Foo %t/test.o -o %t/test
+# RUN: llvm-objdump --macho --lazy-bind %t/test | FileCheck %s --check-prefix=NOSUFFIX
+# NOSUFFIX: __DATA __la_symbol_ptr 0x{{[0-9a-f]*}} {{.*}}Foo _foo
+
+# RUN: lld -flavor darwinnew -L%S/Inputs/MacOSX.sdk/usr/lib -lSystem -F%t -framework Foo,baz %t/test.o -o %t/test-wrong-suffix
+# RUN: llvm-objdump --macho --lazy-bind %t/test-wrong-suffix | FileCheck %s --check-prefix=NOSUFFIX
+
+# RUN: lld -flavor darwinnew -L%S/Inputs/MacOSX.sdk/usr/lib -lSystem -F%t -framework Foo,bar %t/test.o -o %t/test-suffix
+# RUN: llvm-objdump --macho --lazy-bind %t/test-suffix | FileCheck %s --check-prefix=SUFFIX
+# SUFFIX: __DATA __la_symbol_ptr 0x{{[0-9a-f]*}} {{.*}}Foobar _foo
+
+.globl _main
+.text
+_main:
+  sub $8, %rsp # 16-byte-align the stack; dylld -flavor darwinnew checks for this
+  callq _foo
+  mov $0, %rax
+  add $8, %rsp
+  ret


        


More information about the llvm-commits mailing list