Skip to content

Commit cf85cff

Browse files
committed
[lld] check cache in loadDylib before real_path
1 parent adfea33 commit cf85cff

File tree

1 file changed

+32
-6
lines changed

1 file changed

+32
-6
lines changed

lld/MachO/DriverUtils.cpp

Lines changed: 32 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -225,21 +225,42 @@ std::optional<StringRef> macho::resolveDylibPath(StringRef dylibPath) {
225225
// especially if it's a commonly re-exported core library.
226226
static DenseMap<CachedHashStringRef, DylibFile *> loadedDylibs;
227227

228+
static StringRef realPathIfDifferent(StringRef path) {
229+
SmallString<128> realPathBuf;
230+
std::error_code err = fs::real_path(path, realPathBuf);
231+
if (err)
232+
return StringRef();
233+
234+
StringRef realPath(realPathBuf);
235+
if (realPath.ends_with(path))
236+
return StringRef();
237+
238+
return uniqueSaver().save(realPath);
239+
}
240+
228241
DylibFile *macho::loadDylib(MemoryBufferRef mbref, DylibFile *umbrella,
229242
bool isBundleLoader, bool explicitlyLinked) {
230-
// Frameworks can be found from different symlink paths, so resolve
231-
// symlinks before looking up in the dylib cache.
232-
SmallString<128> realPath;
233-
std::error_code err = fs::real_path(mbref.getBufferIdentifier(), realPath);
234-
CachedHashStringRef path(!err ? uniqueSaver().save(StringRef(realPath))
235-
: mbref.getBufferIdentifier());
243+
CachedHashStringRef path(mbref.getBufferIdentifier());
236244
DylibFile *&file = loadedDylibs[path];
237245
if (file) {
238246
if (explicitlyLinked)
239247
file->setExplicitlyLinked();
240248
return file;
241249
}
242250

251+
// Frameworks can be found from different symlink paths, so resolve
252+
// symlinks and look up in the dylib cache.
253+
StringRef realPath = realPathIfDifferent(mbref.getBufferIdentifier());
254+
if (!realPath.empty()) {
255+
CachedHashStringRef cachedRealPath(realPath);
256+
if (loadedDylibs.contains(cachedRealPath)) {
257+
DylibFile *realfile = loadedDylibs.at(cachedRealPath);
258+
if (explicitlyLinked)
259+
realfile->setExplicitlyLinked();
260+
return realfile;
261+
}
262+
}
263+
243264
DylibFile *newFile;
244265
file_magic magic = identify_magic(mbref.getBuffer());
245266
if (magic == file_magic::tapi_file) {
@@ -292,6 +313,11 @@ DylibFile *macho::loadDylib(MemoryBufferRef mbref, DylibFile *umbrella,
292313
sys::path::filename(newFile->installName) + "' because " +
293314
config->clientName + " is not an allowed client");
294315
}
316+
317+
// If the load path was a symlink, cache the real path too.
318+
if (!realPath.empty())
319+
loadedDylibs[CachedHashStringRef(realPath)] = newFile;
320+
295321
return newFile;
296322
}
297323

0 commit comments

Comments
 (0)