diff --git a/lld/MachO/Driver.cpp b/lld/MachO/Driver.cpp --- a/lld/MachO/Driver.cpp +++ b/lld/MachO/Driver.cpp @@ -83,45 +83,51 @@ lld::outs() << "\n"; } -static Optional findLibrary(StringRef name) { - std::string stub = (llvm::Twine("lib") + name + ".tbd").str(); - std::string shared = (llvm::Twine("lib") + name + ".dylib").str(); - std::string archive = (llvm::Twine("lib") + name + ".a").str(); - llvm::SmallString<260> location; +static Optional findWithExtension(StringRef base, + ArrayRef extensions) { + for (StringRef ext : extensions) { + Twine location = base + ext; + if (fs::exists(location)) + return location.str(); + } + return {}; +} +static Optional findLibrary(StringRef name) { + llvm::SmallString<261> location; for (StringRef dir : config->librarySearchPaths) { - for (StringRef library : {stub, shared, archive}) { location = dir; - llvm::sys::path::append(location, library); - if (fs::exists(location)) - return location.str().str(); - } + path::append(location, Twine("lib") + name); + if (Optional path = + findWithExtension(location, {".tbd", ".dylib", ".a"})) + return path; } return {}; } static Optional 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(); + // NOTE: we must resolve the symlink before trying the suffixes, because + // there are no symlinks for the suffixed paths. + llvm::SmallString<260> location; + if (!fs::real_path(symlink, location)) { + // only append suffix if realpath() succeeds + 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(); + + if (Optional path = findWithExtension(symlink, {".tbd", ""})) + return path; } return {}; } diff --git a/lld/test/MachO/Inputs/MacOSX.sdk/System/Library/Frameworks/CoreFoundation.framework/CoreFoundation.tbd b/lld/test/MachO/Inputs/MacOSX.sdk/System/Library/Frameworks/CoreFoundation.framework/CoreFoundation.tbd new file mode 100644 --- /dev/null +++ b/lld/test/MachO/Inputs/MacOSX.sdk/System/Library/Frameworks/CoreFoundation.framework/CoreFoundation.tbd @@ -0,0 +1,10 @@ +--- !tapi-tbd-v3 +archs: [ x86_64 ] +uuids: [ 'x86_64: 00000000-0000-0000-0000-000000000000' ] +platform: macosx +install-name: '/System/Library/Frameworks/CoreFoundation.framework/CoreFoundation' +current-version: 0001.001.1 +compatibility-version: 150 +exports: + - archs: [ 'x86_64' ] + symbols: [ '__CFBigNumGetInt128' ] diff --git a/lld/test/MachO/stub-framework.s b/lld/test/MachO/stub-framework.s new file mode 100644 --- /dev/null +++ b/lld/test/MachO/stub-framework.s @@ -0,0 +1,14 @@ +# REQUIRES: x86 +# RUN: mkdir -p %t +# RUN: llvm-mc -filetype obj -triple x86_64-apple-darwin %s -o %t/test.o +# RUN: lld -flavor darwinnew -o %t/test -Z -F%S/Inputs/MacOSX.sdk/System/Library/Frameworks -framework CoreFoundation %t/test.o +# +# RUN: llvm-objdump --macho --dylibs-used %t/test | FileCheck %s +# CHECK: /System/Library/Frameworks/CoreFoundation.framework/CoreFoundation + +.section __TEXT,__text +.global _main + +_main: + movq __CFBigNumGetInt128@GOTPCREL(%rip), %rax + ret