[lld] [lld-macho]Fix bug in finding "chained" re-exported libs. (PR #135241)
Vy Nguyen via llvm-commits
llvm-commits at lists.llvm.org
Thu Apr 10 12:27:06 PDT 2025
https://github.com/oontvoo created https://github.com/llvm/llvm-project/pull/135241
Details:
When we have the following scenario:
- lib_a re-exports lib_b
- lib_b re-exports @rpath/lib_c
+ lib_b contains LC_RPATH
Previously, lld-macho cannot find lib_c because it was attempting to resolve the '@rpath' from lib_b (which had no LC_RPATH defined). The change here is to also consider all the LC_RPATH rom lib_b when trying to find lib_c.
Inspired by real-life example when linking with libXCTestSwiftSupport.dylib (which re-exports XCTest, which re-exports XCTestCore)
>From 503a6a57ccb5e8e1d7ba6e46288cb0eb8492c965 Mon Sep 17 00:00:00 2001
From: Vy Nguyen <vyng at google.com>
Date: Thu, 10 Apr 2025 15:20:04 -0400
Subject: [PATCH] [lld-macho]Fix bug in finding "chained" re-exported libs.
Details:
When we have the following scenario:
- lib_a re-exports lib_b
- lib_b re-exports @rpath/lib_c
+ lib_b contains LC_RPATH
Previously, lld-macho cannot find lib_c because it was attempting to resolve the '@rpath' from lib_b (which had no LC_RPATH defined).
The change here is to also consider all the LC_RPATH rom lib_b when trying to find lib_c.
Inspired by real-life example when linking with libXCTestSwiftSupport.dylib (which re-exports XCTest, which re-exports XCTestCore)
---
lld/MachO/InputFiles.cpp | 24 +++++++++++++++---
lld/test/MachO/reexport-with-rpath.s | 37 ++++++++++++++++++++++++++++
2 files changed, 58 insertions(+), 3 deletions(-)
create mode 100644 lld/test/MachO/reexport-with-rpath.s
diff --git a/lld/MachO/InputFiles.cpp b/lld/MachO/InputFiles.cpp
index 9adfbc9d3f6f5..9afa5feaa1693 100644
--- a/lld/MachO/InputFiles.cpp
+++ b/lld/MachO/InputFiles.cpp
@@ -1633,6 +1633,17 @@ static DylibFile *findDylib(StringRef path, DylibFile *umbrella,
if (std::optional<StringRef> dylibPath = resolveDylibPath(newPath.str()))
return loadDylib(*dylibPath, umbrella);
}
+ // If not found in umbrella, try the rpaths specified via -rpath too.
+ for (StringRef rpath : config->runtimePaths) {
+ newPath.clear();
+ if (rpath.consume_front("@loader_path/")) {
+ fs::real_path(umbrella->getName(), newPath);
+ path::remove_filename(newPath);
+ }
+ path::append(newPath, rpath, path.drop_front(strlen("@rpath/")));
+ if (std::optional<StringRef> dylibPath = resolveDylibPath(newPath.str()))
+ return loadDylib(*dylibPath, umbrella);
+ }
}
// FIXME: Should this be further up?
@@ -1678,9 +1689,16 @@ static bool isImplicitlyLinked(StringRef path) {
void DylibFile::loadReexport(StringRef path, DylibFile *umbrella,
const InterfaceFile *currentTopLevelTapi) {
DylibFile *reexport = findDylib(path, umbrella, currentTopLevelTapi);
- if (!reexport)
- error(toString(this) + ": unable to locate re-export with install name " +
- path);
+ if (!reexport) {
+ // If not found in umbrella, retry since some rpaths might have been
+ // defined in "this" dyblib (which contains the LC_REEXPORT_DYLIB cmd) and
+ // not in the umbrella.
+ DylibFile *reexport2 = findDylib(path, this, currentTopLevelTapi);
+ if (!reexport2) {
+ error(toString(this) + ": unable to locate re-export with install name " +
+ path);
+ }
+ }
}
DylibFile::DylibFile(MemoryBufferRef mb, DylibFile *umbrella,
diff --git a/lld/test/MachO/reexport-with-rpath.s b/lld/test/MachO/reexport-with-rpath.s
new file mode 100644
index 0000000000000..f1b00ddc9f7e5
--- /dev/null
+++ b/lld/test/MachO/reexport-with-rpath.s
@@ -0,0 +1,37 @@
+# REQUIRES: x86
+# RUN: rm -rf %t; split-file %s %t
+# RUN: mkdir -p %t/cc/two/three
+# RUN: mkdir -p %t/bb/two/three
+# RUN: mkdir -p %t/aa/two/three
+
+# RUN: llvm-mc -filetype=obj -triple=x86_64-apple-darwin %t/c.s -o %t/c.o
+# RUN: llvm-mc -filetype=obj -triple=x86_64-apple-darwin %t/b.s -o %t/b.o
+# RUN: llvm-mc -filetype=obj -triple=x86_64-apple-darwin %t/a.s -o %t/a.o
+
+# RUN: %lld -dylib -install_name @rpath/two/three/libCee.dylib %t/c.o -o %t/cc/two/three/libCee.dylib
+# RUN: %lld -dylib -install_name @rpath/two/three/libBee.dylib -L%t/cc/two/three -sub_library libCee -lCee %t/b.o -o %t/bb/two/three/libBee.dylib -rpath %t/cc
+# RUN: %lld -dylib -install_name @rpath/two/three/libAee.dylib -L%t/bb/two/three -sub_library libBee -lBee %t/a.o -o %t/aa/two/three/libAee.dylib
+##################
+
+
+#--- c.s
+.text
+.global _c_func
+_c_func:
+ mov $0, %rax
+ ret
+
+#--- b.s
+.text
+.global _b_func
+
+_b_func:
+ mov $0, %rax
+ ret
+
+#--- a.s
+.text
+.global _a_func
+_a_func:
+ mov $0, %rax
+ ret
More information about the llvm-commits
mailing list