[lld] [lld] check cache in loadDylib before real_path (PR #143595)
Richard Howell via llvm-commits
llvm-commits at lists.llvm.org
Wed Jun 11 10:06:55 PDT 2025
https://github.com/rmaz updated https://github.com/llvm/llvm-project/pull/143595
>From cf85cffd218cd554c28ddd21985af32f89cc24bd Mon Sep 17 00:00:00 2001
From: Richard Howell <rhow at meta.com>
Date: Tue, 10 Jun 2025 12:35:38 -0700
Subject: [PATCH] [lld] check cache in loadDylib before real_path
---
lld/MachO/DriverUtils.cpp | 38 ++++++++++++++++++++++++++++++++------
1 file changed, 32 insertions(+), 6 deletions(-)
diff --git a/lld/MachO/DriverUtils.cpp b/lld/MachO/DriverUtils.cpp
index f7f6be049f0e1..05bae4a44016a 100644
--- a/lld/MachO/DriverUtils.cpp
+++ b/lld/MachO/DriverUtils.cpp
@@ -225,14 +225,22 @@ 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;
+ std::error_code err = fs::real_path(path, realPathBuf);
+ if (err)
+ return StringRef();
+
+ StringRef realPath(realPathBuf);
+ if (realPath.ends_with(path))
+ return StringRef();
+
+ return uniqueSaver().save(realPath);
+}
+
DylibFile *macho::loadDylib(MemoryBufferRef mbref, DylibFile *umbrella,
bool isBundleLoader, bool explicitlyLinked) {
- // Frameworks can be found from different 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 +248,19 @@ DylibFile *macho::loadDylib(MemoryBufferRef mbref, DylibFile *umbrella,
return file;
}
+ // Frameworks can be found from different symlink paths, so resolve
+ // symlinks and look up in the dylib cache.
+ StringRef realPath = realPathIfDifferent(mbref.getBufferIdentifier());
+ if (!realPath.empty()) {
+ CachedHashStringRef cachedRealPath(realPath);
+ if (loadedDylibs.contains(cachedRealPath)) {
+ DylibFile *realfile = loadedDylibs.at(cachedRealPath);
+ if (explicitlyLinked)
+ realfile->setExplicitlyLinked();
+ return realfile;
+ }
+ }
+
DylibFile *newFile;
file_magic magic = identify_magic(mbref.getBuffer());
if (magic == file_magic::tapi_file) {
@@ -292,6 +313,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.empty())
+ loadedDylibs[CachedHashStringRef(realPath)] = newFile;
+
return newFile;
}
More information about the llvm-commits
mailing list