[lld] 35f6d91 - [lld] check cache in loadDylib before real_path (#143595)
via llvm-commits
llvm-commits at lists.llvm.org
Tue Jun 17 07:18:53 PDT 2025
Author: Richard Howell
Date: 2025-06-17T07:18:50-07:00
New Revision: 35f6d917206d79ab0e3d382a36ca05ccc13983d5
URL: https://github.com/llvm/llvm-project/commit/35f6d917206d79ab0e3d382a36ca05ccc13983d5
DIFF: https://github.com/llvm/llvm-project/commit/35f6d917206d79ab0e3d382a36ca05ccc13983d5.diff
LOG: [lld] check cache in loadDylib before real_path (#143595)
Added:
lld/test/MachO/reexport-with-symlink.s
Modified:
lld/MachO/DriverUtils.cpp
Removed:
################################################################################
diff --git a/lld/MachO/DriverUtils.cpp b/lld/MachO/DriverUtils.cpp
index f7f6be049f0e1..a3b722f13daca 100644
--- a/lld/MachO/DriverUtils.cpp
+++ b/lld/MachO/DriverUtils.cpp
@@ -225,14 +225,21 @@ std::optional<StringRef> macho::resolveDylibPath(StringRef dylibPath) {
// especially if it's a commonly re-exported core library.
static DenseMap<CachedHashStringRef, DylibFile *> loadedDylibs;
+static StringRef realPathIfDifferent(StringRef path) {
+ SmallString<128> realPathBuf;
+ if (fs::real_path(path, realPathBuf))
+ return StringRef();
+
+ SmallString<128> absPathBuf = path;
+ if (!fs::make_absolute(absPathBuf) && realPathBuf == absPathBuf)
+ return StringRef();
+
+ return uniqueSaver().save(StringRef(realPathBuf));
+}
+
DylibFile *macho::loadDylib(MemoryBufferRef mbref, DylibFile *umbrella,
bool isBundleLoader, bool explicitlyLinked) {
- // Frameworks can be found from
diff erent symlink paths, so resolve
- // symlinks before looking up in the dylib cache.
- SmallString<128> realPath;
- std::error_code err = fs::real_path(mbref.getBufferIdentifier(), realPath);
- CachedHashStringRef path(!err ? uniqueSaver().save(StringRef(realPath))
- : mbref.getBufferIdentifier());
+ CachedHashStringRef path(mbref.getBufferIdentifier());
DylibFile *&file = loadedDylibs[path];
if (file) {
if (explicitlyLinked)
@@ -240,6 +247,22 @@ DylibFile *macho::loadDylib(MemoryBufferRef mbref, DylibFile *umbrella,
return file;
}
+ // Frameworks can be found from
diff erent symlink paths, so resolve
+ // symlinks and look up in the dylib cache.
+ CachedHashStringRef realPath(
+ realPathIfDifferent(mbref.getBufferIdentifier()));
+ if (!realPath.val().empty()) {
+ // Avoid map insertions here so that we do not invalidate the "file"
+ // reference.
+ auto it = loadedDylibs.find(realPath);
+ if (it != loadedDylibs.end()) {
+ DylibFile *realfile = it->second;
+ if (explicitlyLinked)
+ realfile->setExplicitlyLinked();
+ return realfile;
+ }
+ }
+
DylibFile *newFile;
file_magic magic = identify_magic(mbref.getBuffer());
if (magic == file_magic::tapi_file) {
@@ -292,6 +315,11 @@ DylibFile *macho::loadDylib(MemoryBufferRef mbref, DylibFile *umbrella,
sys::path::filename(newFile->installName) + "' because " +
config->clientName + " is not an allowed client");
}
+
+ // If the load path was a symlink, cache the real path too.
+ if (!realPath.val().empty())
+ loadedDylibs[realPath] = newFile;
+
return newFile;
}
diff --git a/lld/test/MachO/reexport-with-symlink.s b/lld/test/MachO/reexport-with-symlink.s
new file mode 100644
index 0000000000000..a6b5992713f39
--- /dev/null
+++ b/lld/test/MachO/reexport-with-symlink.s
@@ -0,0 +1,74 @@
+# REQUIRES: aarch64, shell
+# RUN: rm -rf %t; split-file %s %t
+# RUN: ln -s Versions/A/Developer %t/Developer/Library/Frameworks/Developer.framework/
+# RUN: llvm-mc -filetype obj -triple arm64-apple-macos11.0 %t/test.s -o %t/test.o
+# RUN: %lld -arch arm64 -platform_version macos 11.0 11.0 -o %t/test -framework Developer -F %t/Developer/Library/Frameworks -L %t/Developer/usr/lib %t/test.o -t | FileCheck %s
+
+# CHECK: {{.*}}/Developer/Library/Frameworks/Developer.framework/Developer
+# CHECK: {{.*}}/Developer/usr/lib/libDeveloperSupport.tbd(@rpath/libDeveloperSupport.dylib)
+# CHECK-NOT: {{.*}}/Developer/Library/Frameworks/Developer.framework/Versions/A/Developer
+
+#--- Developer/Library/Frameworks/Developer.framework/Versions/A/Developer
+{
+ "tapi_tbd_version": 5,
+ "main_library": {
+ "target_info": [
+ {
+ "target": "arm64-macos"
+ }
+ ],
+ "install_names": [
+ {
+ "name": "@rpath/Developer.framework/Developer"
+ }
+ ],
+ "exported_symbols": [
+ {
+ "text": {
+ "global": ["_funcPublic"]
+ }
+ }
+ ]
+ }
+}
+#--- Developer/usr/lib/libDeveloperSupport.tbd
+{
+ "tapi_tbd_version": 5,
+ "main_library": {
+ "target_info": [
+ {
+ "target": "arm64-macos"
+ }
+ ],
+ "install_names": [
+ {
+ "name": "@rpath/libDeveloperSupport.dylib"
+ }
+ ],
+ "reexported_libraries": [
+ {
+ "names": [
+ "@rpath/Developer.framework/Versions/A/Developer"
+ ]
+ }
+ ],
+ "exported_symbols": [
+ {
+ "text": {
+ "global": ["_funcSupport"]
+ }
+ }
+ ]
+ }
+}
+#--- test.s
+.text
+.globl _main
+.linker_option "-lDeveloperSupport"
+
+_main:
+ ret
+
+.data
+ .quad _funcPublic
+ .quad _funcSupport
More information about the llvm-commits
mailing list