From: Nico Weber Date: Sun, 6 Jun 2021 22:12:27 +0000 (-0400) Subject: [lld/mac] Implement support for searching dylibs with @loader_path/ in install name X-Git-Tag: llvmorg-14-init~4721 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=52489021cf8ba7bb3b8e5ae56ab5f25ce4790c0f;p=platform%2Fupstream%2Fllvm.git [lld/mac] Implement support for searching dylibs with @loader_path/ in install name Differential Revision: https://reviews.llvm.org/D103779 --- diff --git a/lld/MachO/InputFiles.cpp b/lld/MachO/InputFiles.cpp index ac34920..2fe338f 100644 --- a/lld/MachO/InputFiles.cpp +++ b/lld/MachO/InputFiles.cpp @@ -752,15 +752,15 @@ static DylibFile *loadDylib(StringRef path, DylibFile *umbrella) { // // 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 @@ DylibFile *findDylib(StringRef path, DylibFile *umbrella, // 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 @@ static bool isImplicitlyLinked(StringRef path) { 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 index 0000000..96ed266 --- /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