[lld/mac] When loading reexports, look for basename in -F / -L first

Matches ld64 (cf Options::findIndirectDylib()), and fixes PR51218.

Differential Revision: https://reviews.llvm.org/D106842
This commit is contained in:
Nico Weber 2021-07-26 20:39:24 -04:00
parent 21c24ae902
commit 8e8701abca
2 changed files with 54 additions and 0 deletions

View File

@ -860,14 +860,37 @@ static DylibFile *loadDylib(StringRef path, DylibFile *umbrella) {
// files.
static DylibFile *findDylib(StringRef path, DylibFile *umbrella,
const InterfaceFile *currentTopLevelTapi) {
// Search order:
// 1. Install name basename in -F / -L directories.
{
StringRef stem = path::stem(path);
SmallString<128> frameworkName;
path::append(frameworkName, stem + ".framework", stem);
bool isFramework = path.endswith(frameworkName);
if (isFramework) {
for (StringRef dir : config->frameworkSearchPaths) {
SmallString<128> candidate = dir;
path::append(candidate, frameworkName);
if (Optional<std::string> dylibPath = resolveDylibPath(candidate))
return loadDylib(*dylibPath, umbrella);
}
} else if (Optional<StringRef> dylibPath = findPathCombination(
stem, config->librarySearchPaths, {".tbd", ".dylib"}))
return loadDylib(*dylibPath, umbrella);
}
// 2. As absolute path.
if (path::is_absolute(path, path::Style::posix))
for (StringRef root : config->systemLibraryRoots)
if (Optional<std::string> dylibPath =
resolveDylibPath((root + path).str()))
return loadDylib(*dylibPath, umbrella);
// 3. As relative path.
// TODO: Handle -dylib_file
// Replace @executable_path, @loader_path, @rpath prefixes in install name.
SmallString<128> newPath;
if (config->outputType == MH_EXECUTE &&
path.consume_front("@executable_path/")) {
@ -894,6 +917,7 @@ static DylibFile *findDylib(StringRef path, DylibFile *umbrella,
}
}
// FIXME: Should this be further up?
if (currentTopLevelTapi) {
for (InterfaceFile &child :
make_pointee_range(currentTopLevelTapi->documents())) {

View File

@ -86,6 +86,36 @@
# RUN: -o %t/libgoodbye.dylib 2>&1 | FileCheck %s --check-prefix=MISSING-FRAMEWORK
# MISSING-FRAMEWORK: error: -sub_umbrella libhello does not match a supplied dylib
## Check that -F (but not -L) can override the search path in install_name for
## frameworks.
# RUN: mkdir -p %t/Hello2.framework
# RUN: %lld -dylib %t/libhello.o \
# RUN: -install_name /path/to/Hello2.framework/Hello2 \
# RUN: -o %t/Hello2.framework/Hello2
# RUN: %lld -dylib -o %t/libgoodbye4.dylib %t/libgoodbye.o \
# RUN: -reexport_library %t/Hello2.framework/Hello2
# RUN: not %lld -lSystem -o %t/hello %t/libgoodbye4.dylib %t/sub-library.o 2>&1 \
# RUN: | FileCheck %s --check-prefix=NOTFOUND
# RUN: not %lld -lSystem -o %t/hello -L%t %t/libgoodbye4.dylib %t/sub-library.o 2>&1 \
# RUN: | FileCheck %s --check-prefix=NOTFOUND
# NOTFOUND: unable to locate re-export with install name /path/to/Hello2.framework/Hello2
# RUN: %lld -lSystem -o %t/hello -F%t %t/libgoodbye4.dylib %t/sub-library.o
## Check that -L (but not -F) can override the search path in install_name for
## libraries.
# RUN: %lld -dylib %t/libhello.o \
# RUN: -install_name /path/to/libhello2.dylib \
# RUN: -o %t/libhello2.dylib
# RUN: %lld -dylib -o %t/libgoodbye5.dylib %t/libgoodbye.o \
# RUN: -reexport_library %t/libhello2.dylib
# RUN: not %lld -lSystem -o %t/hello %t/libgoodbye5.dylib %t/sub-library.o 2>&1 \
# RUN: | FileCheck %s --check-prefix=NOTFOUND2
# RUN: not %lld -lSystem -o %t/hello -F%t %t/libgoodbye5.dylib %t/sub-library.o 2>&1 \
# RUN: | FileCheck %s --check-prefix=NOTFOUND2
# NOTFOUND2: unable to locate re-export with install name /path/to/libhello2.dylib
# RUN: %lld -lSystem -o %t/hello -L%t %t/libgoodbye5.dylib %t/sub-library.o
.text
.globl _main