[lld] check cache in loadDylib before real_path (#143595)
This commit is contained in:
parent
414710c753
commit
35f6d91720
@ -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 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 +247,22 @@ 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.
|
||||
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;
|
||||
}
|
||||
|
||||
|
74
lld/test/MachO/reexport-with-symlink.s
Normal file
74
lld/test/MachO/reexport-with-symlink.s
Normal file
@ -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
|
Loading…
x
Reference in New Issue
Block a user