diff --git a/lldb/source/Plugins/Platform/MacOSX/PlatformDarwin.h b/lldb/source/Plugins/Platform/MacOSX/PlatformDarwin.h --- a/lldb/source/Plugins/Platform/MacOSX/PlatformDarwin.h +++ b/lldb/source/Plugins/Platform/MacOSX/PlatformDarwin.h @@ -144,11 +144,6 @@ void ReadLibdispatchOffsets(Process *process); - virtual Status GetSharedModuleWithLocalCache( - const ModuleSpec &module_spec, lldb::ModuleSP &module_sp, - const FileSpecList *module_search_paths_ptr, - llvm::SmallVectorImpl *old_modules, bool *did_create_ptr); - virtual bool CheckLocalSharedCache() const { return IsHost(); } struct SDKEnumeratorInfo { diff --git a/lldb/source/Plugins/Platform/MacOSX/PlatformDarwin.cpp b/lldb/source/Plugins/Platform/MacOSX/PlatformDarwin.cpp --- a/lldb/source/Plugins/Platform/MacOSX/PlatformDarwin.cpp +++ b/lldb/source/Plugins/Platform/MacOSX/PlatformDarwin.cpp @@ -200,167 +200,6 @@ return {}; } -static lldb_private::Status -MakeCacheFolderForFile(const FileSpec &module_cache_spec) { - FileSpec module_cache_folder = - module_cache_spec.CopyByRemovingLastPathComponent(); - return llvm::sys::fs::create_directory(module_cache_folder.GetPath()); -} - -static lldb_private::Status -BringInRemoteFile(Platform *platform, - const lldb_private::ModuleSpec &module_spec, - const FileSpec &module_cache_spec) { - MakeCacheFolderForFile(module_cache_spec); - Status err = platform->GetFile(module_spec.GetFileSpec(), module_cache_spec); - return err; -} - -lldb_private::Status PlatformDarwin::GetSharedModuleWithLocalCache( - const lldb_private::ModuleSpec &module_spec, lldb::ModuleSP &module_sp, - const lldb_private::FileSpecList *module_search_paths_ptr, - llvm::SmallVectorImpl *old_modules, bool *did_create_ptr) { - - Log *log = GetLog(LLDBLog::Platform); - LLDB_LOGF(log, - "[%s] Trying to find module %s/%s - platform path %s/%s symbol " - "path %s/%s", - (IsHost() ? "host" : "remote"), - module_spec.GetFileSpec().GetDirectory().AsCString(), - module_spec.GetFileSpec().GetFilename().AsCString(), - module_spec.GetPlatformFileSpec().GetDirectory().AsCString(), - module_spec.GetPlatformFileSpec().GetFilename().AsCString(), - module_spec.GetSymbolFileSpec().GetDirectory().AsCString(), - module_spec.GetSymbolFileSpec().GetFilename().AsCString()); - - Status err; - - if (CheckLocalSharedCache()) { - // When debugging on the host, we are most likely using the same shared - // cache as our inferior. The dylibs from the shared cache might not - // exist on the filesystem, so let's use the images in our own memory - // to create the modules. - - // Check if the requested image is in our shared cache. - SharedCacheImageInfo image_info = - HostInfo::GetSharedCacheImageInfo(module_spec.GetFileSpec().GetPath()); - - // If we found it and it has the correct UUID, let's proceed with - // creating a module from the memory contents. - if (image_info.uuid && - (!module_spec.GetUUID() || module_spec.GetUUID() == image_info.uuid)) { - ModuleSpec shared_cache_spec(module_spec.GetFileSpec(), image_info.uuid, - image_info.data_sp); - err = ModuleList::GetSharedModule(shared_cache_spec, module_sp, - module_search_paths_ptr, old_modules, - did_create_ptr); - if (module_sp) - return err; - } - } - - err = ModuleList::GetSharedModule(module_spec, module_sp, - module_search_paths_ptr, old_modules, - did_create_ptr); - if (module_sp) - return err; - - if (!IsHost()) { - std::string cache_path(GetLocalCacheDirectory()); - // Only search for a locally cached file if we have a valid cache path - if (!cache_path.empty()) { - std::string module_path(module_spec.GetFileSpec().GetPath()); - cache_path.append(module_path); - FileSpec module_cache_spec(cache_path); - - // if rsync is supported, always bring in the file - rsync will be very - // efficient when files are the same on the local and remote end of the - // connection - if (this->GetSupportsRSync()) { - err = BringInRemoteFile(this, module_spec, module_cache_spec); - if (err.Fail()) - return err; - if (FileSystem::Instance().Exists(module_cache_spec)) { - Log *log = GetLog(LLDBLog::Platform); - LLDB_LOGF(log, "[%s] module %s/%s was rsynced and is now there", - (IsHost() ? "host" : "remote"), - module_spec.GetFileSpec().GetDirectory().AsCString(), - module_spec.GetFileSpec().GetFilename().AsCString()); - ModuleSpec local_spec(module_cache_spec, - module_spec.GetArchitecture()); - module_sp = std::make_shared(local_spec); - module_sp->SetPlatformFileSpec(module_spec.GetFileSpec()); - return Status(); - } - } - - // try to find the module in the cache - if (FileSystem::Instance().Exists(module_cache_spec)) { - // get the local and remote MD5 and compare - if (m_remote_platform_sp) { - // when going over the *slow* GDB remote transfer mechanism we first - // check the hashes of the files - and only do the actual transfer if - // they differ - uint64_t high_local, high_remote, low_local, low_remote; - auto MD5 = llvm::sys::fs::md5_contents(module_cache_spec.GetPath()); - if (!MD5) - return Status(MD5.getError()); - std::tie(high_local, low_local) = MD5->words(); - - m_remote_platform_sp->CalculateMD5(module_spec.GetFileSpec(), - low_remote, high_remote); - if (low_local != low_remote || high_local != high_remote) { - // bring in the remote file - Log *log = GetLog(LLDBLog::Platform); - LLDB_LOGF(log, - "[%s] module %s/%s needs to be replaced from remote copy", - (IsHost() ? "host" : "remote"), - module_spec.GetFileSpec().GetDirectory().AsCString(), - module_spec.GetFileSpec().GetFilename().AsCString()); - Status err = - BringInRemoteFile(this, module_spec, module_cache_spec); - if (err.Fail()) - return err; - } - } - - ModuleSpec local_spec(module_cache_spec, module_spec.GetArchitecture()); - module_sp = std::make_shared(local_spec); - module_sp->SetPlatformFileSpec(module_spec.GetFileSpec()); - Log *log = GetLog(LLDBLog::Platform); - LLDB_LOGF(log, "[%s] module %s/%s was found in the cache", - (IsHost() ? "host" : "remote"), - module_spec.GetFileSpec().GetDirectory().AsCString(), - module_spec.GetFileSpec().GetFilename().AsCString()); - return Status(); - } - - // bring in the remote module file - LLDB_LOGF(log, "[%s] module %s/%s needs to come in remotely", - (IsHost() ? "host" : "remote"), - module_spec.GetFileSpec().GetDirectory().AsCString(), - module_spec.GetFileSpec().GetFilename().AsCString()); - Status err = BringInRemoteFile(this, module_spec, module_cache_spec); - if (err.Fail()) - return err; - if (FileSystem::Instance().Exists(module_cache_spec)) { - Log *log = GetLog(LLDBLog::Platform); - LLDB_LOGF(log, "[%s] module %s/%s is now cached and fine", - (IsHost() ? "host" : "remote"), - module_spec.GetFileSpec().GetDirectory().AsCString(), - module_spec.GetFileSpec().GetFilename().AsCString()); - ModuleSpec local_spec(module_cache_spec, module_spec.GetArchitecture()); - module_sp = std::make_shared(local_spec); - module_sp->SetPlatformFileSpec(module_spec.GetFileSpec()); - return Status(); - } else - return Status("unable to obtain valid module file"); - } else - return Status("no cache path"); - } else - return Status("unable to resolve module"); -} - Status PlatformDarwin::GetSharedModule( const ModuleSpec &module_spec, Process *process, ModuleSP &module_sp, const FileSpecList *module_search_paths_ptr, diff --git a/lldb/source/Plugins/Platform/MacOSX/PlatformDarwinDevice.h b/lldb/source/Plugins/Platform/MacOSX/PlatformDarwinDevice.h --- a/lldb/source/Plugins/Platform/MacOSX/PlatformDarwinDevice.h +++ b/lldb/source/Plugins/Platform/MacOSX/PlatformDarwinDevice.h @@ -24,6 +24,11 @@ ~PlatformDarwinDevice() override; protected: + virtual Status GetSharedModuleWithLocalCache( + const ModuleSpec &module_spec, lldb::ModuleSP &module_sp, + const FileSpecList *module_search_paths_ptr, + llvm::SmallVectorImpl *old_modules, bool *did_create_ptr); + struct SDKDirectoryInfo { SDKDirectoryInfo(const FileSpec &sdk_dir_spec); FileSpec directory; diff --git a/lldb/source/Plugins/Platform/MacOSX/PlatformDarwinDevice.cpp b/lldb/source/Plugins/Platform/MacOSX/PlatformDarwinDevice.cpp --- a/lldb/source/Plugins/Platform/MacOSX/PlatformDarwinDevice.cpp +++ b/lldb/source/Plugins/Platform/MacOSX/PlatformDarwinDevice.cpp @@ -7,6 +7,9 @@ //===----------------------------------------------------------------------===// #include "PlatformDarwinDevice.h" +#include "lldb/Core/Module.h" +#include "lldb/Core/ModuleList.h" +#include "lldb/Core/ModuleSpec.h" #include "lldb/Host/HostInfo.h" #include "lldb/Utility/FileSpec.h" #include "lldb/Utility/LLDBLog.h" @@ -263,3 +266,168 @@ return m_device_support_directory_for_os_version.c_str(); return nullptr; } + +static lldb_private::Status +MakeCacheFolderForFile(const FileSpec &module_cache_spec) { + FileSpec module_cache_folder = + module_cache_spec.CopyByRemovingLastPathComponent(); + return llvm::sys::fs::create_directory(module_cache_folder.GetPath()); +} + +static lldb_private::Status +BringInRemoteFile(Platform *platform, + const lldb_private::ModuleSpec &module_spec, + const FileSpec &module_cache_spec) { + MakeCacheFolderForFile(module_cache_spec); + Status err = platform->GetFile(module_spec.GetFileSpec(), module_cache_spec); + return err; +} + +lldb_private::Status PlatformDarwinDevice::GetSharedModuleWithLocalCache( + const lldb_private::ModuleSpec &module_spec, lldb::ModuleSP &module_sp, + const lldb_private::FileSpecList *module_search_paths_ptr, + llvm::SmallVectorImpl *old_modules, bool *did_create_ptr) { + + Log *log = GetLog(LLDBLog::Platform); + LLDB_LOGF(log, + "[%s] Trying to find module %s/%s - platform path %s/%s symbol " + "path %s/%s", + (IsHost() ? "host" : "remote"), + module_spec.GetFileSpec().GetDirectory().AsCString(), + module_spec.GetFileSpec().GetFilename().AsCString(), + module_spec.GetPlatformFileSpec().GetDirectory().AsCString(), + module_spec.GetPlatformFileSpec().GetFilename().AsCString(), + module_spec.GetSymbolFileSpec().GetDirectory().AsCString(), + module_spec.GetSymbolFileSpec().GetFilename().AsCString()); + + Status err; + + if (CheckLocalSharedCache()) { + // When debugging on the host, we are most likely using the same shared + // cache as our inferior. The dylibs from the shared cache might not + // exist on the filesystem, so let's use the images in our own memory + // to create the modules. + + // Check if the requested image is in our shared cache. + SharedCacheImageInfo image_info = + HostInfo::GetSharedCacheImageInfo(module_spec.GetFileSpec().GetPath()); + + // If we found it and it has the correct UUID, let's proceed with + // creating a module from the memory contents. + if (image_info.uuid && + (!module_spec.GetUUID() || module_spec.GetUUID() == image_info.uuid)) { + ModuleSpec shared_cache_spec(module_spec.GetFileSpec(), image_info.uuid, + image_info.data_sp); + err = ModuleList::GetSharedModule(shared_cache_spec, module_sp, + module_search_paths_ptr, old_modules, + did_create_ptr); + if (module_sp) { + LLDB_LOGF(log, "[%s] module %s was found in the in-memory shared cache", + (IsHost() ? "host" : "remote"), + module_spec.GetFileSpec().GetPath().c_str()); + return err; + } + } + } + + err = ModuleList::GetSharedModule(module_spec, module_sp, + module_search_paths_ptr, old_modules, + did_create_ptr); + if (module_sp) + return err; + + if (!IsHost()) { + std::string cache_path(GetLocalCacheDirectory()); + // Only search for a locally cached file if we have a valid cache path + if (!cache_path.empty()) { + std::string module_path(module_spec.GetFileSpec().GetPath()); + cache_path.append(module_path); + FileSpec module_cache_spec(cache_path); + + // if rsync is supported, always bring in the file - rsync will be very + // efficient when files are the same on the local and remote end of the + // connection + if (this->GetSupportsRSync()) { + err = BringInRemoteFile(this, module_spec, module_cache_spec); + if (err.Fail()) + return err; + if (FileSystem::Instance().Exists(module_cache_spec)) { + Log *log = GetLog(LLDBLog::Platform); + LLDB_LOGF(log, "[%s] module %s/%s was rsynced and is now there", + (IsHost() ? "host" : "remote"), + module_spec.GetFileSpec().GetDirectory().AsCString(), + module_spec.GetFileSpec().GetFilename().AsCString()); + ModuleSpec local_spec(module_cache_spec, + module_spec.GetArchitecture()); + module_sp = std::make_shared(local_spec); + module_sp->SetPlatformFileSpec(module_spec.GetFileSpec()); + return Status(); + } + } + + // try to find the module in the cache + if (FileSystem::Instance().Exists(module_cache_spec)) { + // get the local and remote MD5 and compare + if (m_remote_platform_sp) { + // when going over the *slow* GDB remote transfer mechanism we first + // check the hashes of the files - and only do the actual transfer if + // they differ + uint64_t high_local, high_remote, low_local, low_remote; + auto MD5 = llvm::sys::fs::md5_contents(module_cache_spec.GetPath()); + if (!MD5) + return Status(MD5.getError()); + std::tie(high_local, low_local) = MD5->words(); + + m_remote_platform_sp->CalculateMD5(module_spec.GetFileSpec(), + low_remote, high_remote); + if (low_local != low_remote || high_local != high_remote) { + // bring in the remote file + Log *log = GetLog(LLDBLog::Platform); + LLDB_LOGF(log, + "[%s] module %s/%s needs to be replaced from remote copy", + (IsHost() ? "host" : "remote"), + module_spec.GetFileSpec().GetDirectory().AsCString(), + module_spec.GetFileSpec().GetFilename().AsCString()); + Status err = + BringInRemoteFile(this, module_spec, module_cache_spec); + if (err.Fail()) + return err; + } + } + + ModuleSpec local_spec(module_cache_spec, module_spec.GetArchitecture()); + module_sp = std::make_shared(local_spec); + module_sp->SetPlatformFileSpec(module_spec.GetFileSpec()); + Log *log = GetLog(LLDBLog::Platform); + LLDB_LOGF(log, "[%s] module %s/%s was found in the cache", + (IsHost() ? "host" : "remote"), + module_spec.GetFileSpec().GetDirectory().AsCString(), + module_spec.GetFileSpec().GetFilename().AsCString()); + return Status(); + } + + // bring in the remote module file + LLDB_LOGF(log, "[%s] module %s/%s needs to come in remotely", + (IsHost() ? "host" : "remote"), + module_spec.GetFileSpec().GetDirectory().AsCString(), + module_spec.GetFileSpec().GetFilename().AsCString()); + Status err = BringInRemoteFile(this, module_spec, module_cache_spec); + if (err.Fail()) + return err; + if (FileSystem::Instance().Exists(module_cache_spec)) { + Log *log = GetLog(LLDBLog::Platform); + LLDB_LOGF(log, "[%s] module %s/%s is now cached and fine", + (IsHost() ? "host" : "remote"), + module_spec.GetFileSpec().GetDirectory().AsCString(), + module_spec.GetFileSpec().GetFilename().AsCString()); + ModuleSpec local_spec(module_cache_spec, module_spec.GetArchitecture()); + module_sp = std::make_shared(local_spec); + module_sp->SetPlatformFileSpec(module_spec.GetFileSpec()); + return Status(); + } else + return Status("unable to obtain valid module file"); + } else + return Status("no cache path"); + } else + return Status("unable to resolve module"); +} diff --git a/lldb/source/Plugins/Platform/MacOSX/PlatformMacOSX.h b/lldb/source/Plugins/Platform/MacOSX/PlatformMacOSX.h --- a/lldb/source/Plugins/Platform/MacOSX/PlatformMacOSX.h +++ b/lldb/source/Plugins/Platform/MacOSX/PlatformMacOSX.h @@ -9,7 +9,7 @@ #ifndef LLDB_SOURCE_PLUGINS_PLATFORM_MACOSX_PLATFORMMACOSX_H #define LLDB_SOURCE_PLUGINS_PLATFORM_MACOSX_PLATFORMMACOSX_H -#include "PlatformDarwin.h" +#include "PlatformDarwinDevice.h" #include "lldb/Target/Platform.h" #include "lldb/Utility/ConstString.h" #include "lldb/Utility/Status.h" @@ -28,7 +28,7 @@ class Process; class Target; -class PlatformMacOSX : public PlatformDarwin { +class PlatformMacOSX : public PlatformDarwinDevice { public: PlatformMacOSX(); @@ -69,6 +69,10 @@ return PlatformDarwin::AddClangModuleCompilationOptionsForSDKType( target, options, XcodeSDK::Type::MacOSX); } + +protected: + llvm::StringRef GetDeviceSupportDirectoryName() override; + llvm::StringRef GetPlatformName() override; }; } // namespace lldb_private diff --git a/lldb/source/Plugins/Platform/MacOSX/PlatformMacOSX.cpp b/lldb/source/Plugins/Platform/MacOSX/PlatformMacOSX.cpp --- a/lldb/source/Plugins/Platform/MacOSX/PlatformMacOSX.cpp +++ b/lldb/source/Plugins/Platform/MacOSX/PlatformMacOSX.cpp @@ -96,7 +96,7 @@ } /// Default Constructor -PlatformMacOSX::PlatformMacOSX() : PlatformDarwin(true) {} +PlatformMacOSX::PlatformMacOSX() : PlatformDarwinDevice(true) {} ConstString PlatformMacOSX::GetSDKDirectory(lldb_private::Target &target) { ModuleSP exe_module_sp(target.GetExecutableModule()); @@ -211,3 +211,9 @@ } return error; } + +llvm::StringRef PlatformMacOSX::GetDeviceSupportDirectoryName() { + return "macOS DeviceSupport"; +} + +llvm::StringRef PlatformMacOSX::GetPlatformName() { return "MacOSX.platform"; }