diff --git a/lld/MachO/InputFiles.cpp b/lld/MachO/InputFiles.cpp --- a/lld/MachO/InputFiles.cpp +++ b/lld/MachO/InputFiles.cpp @@ -752,15 +752,15 @@ // // Re-exports can either refer to on-disk files, or to documents within .tbd // files. -DylibFile *findDylib(StringRef path, DylibFile *umbrella, - const InterfaceFile *currentTopLevelTapi) { +static DylibFile *findDylib(StringRef path, DylibFile *umbrella, + const InterfaceFile *currentTopLevelTapi) { if (path::is_absolute(path, path::Style::posix)) for (StringRef root : config->systemLibraryRoots) if (Optional dylibPath = resolveDylibPath((root + path).str())) return loadDylib(*dylibPath, umbrella); - // TODO: Expand @loader_path, @rpath etc, handle -dylib_file + // TODO: Expand @rpath, handle -dylib_file SmallString<128> newPath; if (config->outputType == MH_EXECUTE && path.consume_front("@executable_path/")) { @@ -768,6 +768,9 @@ // lld doesn't currently implement that flag. path::append(newPath, sys::path::parent_path(config->outputFile), path); path = newPath; + } else if (path.consume_front("@loader_path/")) { + path::append(newPath, sys::path::parent_path(umbrella->getName()), path); + path = newPath; } if (currentTopLevelTapi) { @@ -808,8 +811,8 @@ return false; } -void loadReexport(StringRef path, DylibFile *umbrella, - const InterfaceFile *currentTopLevelTapi) { +static void loadReexport(StringRef path, DylibFile *umbrella, + const InterfaceFile *currentTopLevelTapi) { DylibFile *reexport = findDylib(path, umbrella, currentTopLevelTapi); if (!reexport) error("unable to locate re-export with install name " + path); diff --git a/lld/test/MachO/link-search-at-loader-path.s b/lld/test/MachO/link-search-at-loader-path.s new file mode 100644 --- /dev/null +++ b/lld/test/MachO/link-search-at-loader-path.s @@ -0,0 +1,34 @@ +# REQUIRES: x86 + +# RUN: rm -rf %t; split-file %s %t +# RUN: mkdir %t/subdir + +# RUN: llvm-mc -filetype obj -triple x86_64-apple-darwin %t/foo.s -o %t/foo.o +# RUN: llvm-mc -filetype obj -triple x86_64-apple-darwin %t/bar.s -o %t/bar.o +# RUN: llvm-mc -filetype obj -triple x86_64-apple-darwin %t/main.s -o %t/main.o + +# RUN: %lld -dylib -install_name @loader_path/libfoo.dylib %t/foo.o -o %t/subdir/libfoo.dylib + +## Test that @loader_path is replaced by the actual path, not by install_name. +# RUN: %lld -dylib -reexport_library %t/subdir/libfoo.dylib -install_name /tmp/libbar.dylib %t/bar.o -o %t/subdir/libbar.dylib + +# RUN: %lld -lSystem %t/main.o %t/subdir/libbar.dylib -o %t/test +# RUN: %lld -dylib -lSystem %t/main.o %t/subdir/libbar.dylib -o %t/libtest.dylib + +#--- foo.s +.globl _foo +_foo: + retq + +#--- bar.s +.globl _bar +_bar: + retq + +#--- main.s +.section __TEXT,__text +.global _main +_main: + callq _foo + callq _bar + ret