Skip to content

Commit 9282d04

Browse files
committed
[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
1 parent df12524 commit 9282d04

File tree

3 files changed

+67
-1
lines changed

3 files changed

+67
-1
lines changed

lld/MachO/Config.h

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,6 @@ struct Configuration {
3030
llvm::MachO::Architecture arch;
3131
llvm::MachO::HeaderFileType outputType;
3232
std::vector<llvm::StringRef> librarySearchPaths;
33-
// TODO: use the framework search paths
3433
std::vector<llvm::StringRef> frameworkSearchPaths;
3534
llvm::DenseMap<llvm::StringRef, SymbolPriorityEntry> priorities;
3635
};

lld/MachO/Driver.cpp

Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,7 @@
3030
#include "llvm/Object/Archive.h"
3131
#include "llvm/Option/ArgList.h"
3232
#include "llvm/Option/Option.h"
33+
#include "llvm/Support/FileSystem.h"
3334
#include "llvm/Support/Host.h"
3435
#include "llvm/Support/MemoryBuffer.h"
3536
#include "llvm/Support/Path.h"
@@ -98,6 +99,32 @@ static Optional<std::string> findLibrary(StringRef name) {
9899
return {};
99100
}
100101

102+
static Optional<std::string> findFramework(StringRef name) {
103+
// TODO: support .tbd files
104+
llvm::SmallString<260> symlink;
105+
llvm::SmallString<260> location;
106+
StringRef suffix;
107+
std::tie(name, suffix) = name.split(",");
108+
for (StringRef dir : config->frameworkSearchPaths) {
109+
symlink = dir;
110+
path::append(symlink, name + ".framework", name);
111+
// If the symlink fails to resolve, skip to the next search path.
112+
// NOTE: we must resolve the symlink before trying the suffixes, because
113+
// there are no symlinks for the suffixed paths.
114+
if (fs::real_path(symlink, location))
115+
continue;
116+
if (!suffix.empty()) {
117+
llvm::Twine suffixed = location + suffix;
118+
if (fs::exists(suffixed))
119+
return suffixed.str();
120+
// Suffix lookup failed, fall through to the no-suffix case.
121+
}
122+
if (fs::exists(location))
123+
return location.str().str();
124+
}
125+
return {};
126+
}
127+
101128
static TargetInfo *createTargetInfo(opt::InputArgList &args) {
102129
StringRef arch = args.getLastArgValue(OPT_arch, "x86_64");
103130
config->arch = llvm::MachO::getArchitectureFromName(
@@ -393,13 +420,24 @@ bool macho::link(llvm::ArrayRef<const char *> argsArr, bool canExitEarly,
393420
error("library not found for -l" + name);
394421
break;
395422
}
423+
case OPT_framework: {
424+
StringRef name = arg->getValue();
425+
if (Optional<std::string> path = findFramework(name)) {
426+
addFile(*path);
427+
break;
428+
}
429+
error("framework not found for -framework " + name);
430+
break;
431+
}
396432
case OPT_platform_version:
397433
handlePlatformVersion(arg);
398434
break;
399435
case OPT_o:
400436
case OPT_dylib:
401437
case OPT_e:
438+
case OPT_F:
402439
case OPT_L:
440+
case OPT_install_name:
403441
case OPT_Z:
404442
case OPT_arch:
405443
// handled elsewhere

lld/test/MachO/framework.s

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
# REQUIRES: x86, shell
2+
# RUN: mkdir -p %t
3+
# RUN: echo ".globl _foo; _foo: ret" | llvm-mc -filetype=obj -triple=x86_64-apple-darwin -o %t/foo.o
4+
# RUN: mkdir -p %t/Foo.framework/Versions/A
5+
# 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
6+
# 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
7+
# RUN: ln -sf %t/Foo.framework/Versions/A %t/Foo.framework/Versions/Current
8+
# RUN: ln -sf %t/Foo.framework/Versions/Current/Foo %t/Foo.framework/Foo
9+
10+
# RUN: llvm-mc -filetype=obj -triple=x86_64-apple-darwin -o %t/test.o %s
11+
# RUN: lld -flavor darwinnew -L%S/Inputs/MacOSX.sdk/usr/lib -lSystem -F%t -framework Foo %t/test.o -o %t/test
12+
# RUN: llvm-objdump --macho --lazy-bind %t/test | FileCheck %s --check-prefix=NOSUFFIX
13+
# NOSUFFIX: __DATA __la_symbol_ptr 0x{{[0-9a-f]*}} {{.*}}Foo _foo
14+
15+
# 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
16+
# RUN: llvm-objdump --macho --lazy-bind %t/test-wrong-suffix | FileCheck %s --check-prefix=NOSUFFIX
17+
18+
# RUN: lld -flavor darwinnew -L%S/Inputs/MacOSX.sdk/usr/lib -lSystem -F%t -framework Foo,bar %t/test.o -o %t/test-suffix
19+
# RUN: llvm-objdump --macho --lazy-bind %t/test-suffix | FileCheck %s --check-prefix=SUFFIX
20+
# SUFFIX: __DATA __la_symbol_ptr 0x{{[0-9a-f]*}} {{.*}}Foobar _foo
21+
22+
.globl _main
23+
.text
24+
_main:
25+
sub $8, %rsp # 16-byte-align the stack; dylld -flavor darwinnew checks for this
26+
callq _foo
27+
mov $0, %rax
28+
add $8, %rsp
29+
ret

0 commit comments

Comments
 (0)