1*f6aab3d8Srobert //===-- PlatformDarwinDevice.cpp ------------------------------------------===//
2*f6aab3d8Srobert //
3*f6aab3d8Srobert // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4*f6aab3d8Srobert // See https://llvm.org/LICENSE.txt for license information.
5*f6aab3d8Srobert // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6*f6aab3d8Srobert //
7*f6aab3d8Srobert //===----------------------------------------------------------------------===//
8*f6aab3d8Srobert
9*f6aab3d8Srobert #include "PlatformDarwinDevice.h"
10*f6aab3d8Srobert #include "lldb/Core/Module.h"
11*f6aab3d8Srobert #include "lldb/Core/ModuleList.h"
12*f6aab3d8Srobert #include "lldb/Core/ModuleSpec.h"
13*f6aab3d8Srobert #include "lldb/Host/HostInfo.h"
14*f6aab3d8Srobert #include "lldb/Utility/FileSpec.h"
15*f6aab3d8Srobert #include "lldb/Utility/LLDBLog.h"
16*f6aab3d8Srobert #include "lldb/Utility/Log.h"
17*f6aab3d8Srobert #include <optional>
18*f6aab3d8Srobert
19*f6aab3d8Srobert using namespace lldb;
20*f6aab3d8Srobert using namespace lldb_private;
21*f6aab3d8Srobert
22*f6aab3d8Srobert PlatformDarwinDevice::~PlatformDarwinDevice() = default;
23*f6aab3d8Srobert
24*f6aab3d8Srobert FileSystem::EnumerateDirectoryResult
GetContainedFilesIntoVectorOfStringsCallback(void * baton,llvm::sys::fs::file_type ft,llvm::StringRef path)25*f6aab3d8Srobert PlatformDarwinDevice::GetContainedFilesIntoVectorOfStringsCallback(
26*f6aab3d8Srobert void *baton, llvm::sys::fs::file_type ft, llvm::StringRef path) {
27*f6aab3d8Srobert ((PlatformDarwinDevice::SDKDirectoryInfoCollection *)baton)
28*f6aab3d8Srobert ->push_back(PlatformDarwinDevice::SDKDirectoryInfo(FileSpec(path)));
29*f6aab3d8Srobert return FileSystem::eEnumerateDirectoryResultNext;
30*f6aab3d8Srobert }
31*f6aab3d8Srobert
UpdateSDKDirectoryInfosIfNeeded()32*f6aab3d8Srobert bool PlatformDarwinDevice::UpdateSDKDirectoryInfosIfNeeded() {
33*f6aab3d8Srobert Log *log = GetLog(LLDBLog::Host);
34*f6aab3d8Srobert std::lock_guard<std::mutex> guard(m_sdk_dir_mutex);
35*f6aab3d8Srobert if (m_sdk_directory_infos.empty()) {
36*f6aab3d8Srobert // A --sysroot option was supplied - add it to our list of SDKs to check
37*f6aab3d8Srobert if (m_sdk_sysroot) {
38*f6aab3d8Srobert FileSpec sdk_sysroot_fspec(m_sdk_sysroot.GetCString());
39*f6aab3d8Srobert FileSystem::Instance().Resolve(sdk_sysroot_fspec);
40*f6aab3d8Srobert const SDKDirectoryInfo sdk_sysroot_directory_info(sdk_sysroot_fspec);
41*f6aab3d8Srobert m_sdk_directory_infos.push_back(sdk_sysroot_directory_info);
42*f6aab3d8Srobert if (log) {
43*f6aab3d8Srobert LLDB_LOGF(log,
44*f6aab3d8Srobert "PlatformDarwinDevice::UpdateSDKDirectoryInfosIfNeeded added "
45*f6aab3d8Srobert "--sysroot SDK directory %s",
46*f6aab3d8Srobert m_sdk_sysroot.GetCString());
47*f6aab3d8Srobert }
48*f6aab3d8Srobert return true;
49*f6aab3d8Srobert }
50*f6aab3d8Srobert const char *device_support_dir = GetDeviceSupportDirectory();
51*f6aab3d8Srobert if (log) {
52*f6aab3d8Srobert LLDB_LOGF(log,
53*f6aab3d8Srobert "PlatformDarwinDevice::UpdateSDKDirectoryInfosIfNeeded Got "
54*f6aab3d8Srobert "DeviceSupport directory %s",
55*f6aab3d8Srobert device_support_dir);
56*f6aab3d8Srobert }
57*f6aab3d8Srobert if (device_support_dir) {
58*f6aab3d8Srobert const bool find_directories = true;
59*f6aab3d8Srobert const bool find_files = false;
60*f6aab3d8Srobert const bool find_other = false;
61*f6aab3d8Srobert
62*f6aab3d8Srobert SDKDirectoryInfoCollection builtin_sdk_directory_infos;
63*f6aab3d8Srobert FileSystem::Instance().EnumerateDirectory(
64*f6aab3d8Srobert m_device_support_directory, find_directories, find_files, find_other,
65*f6aab3d8Srobert GetContainedFilesIntoVectorOfStringsCallback,
66*f6aab3d8Srobert &builtin_sdk_directory_infos);
67*f6aab3d8Srobert
68*f6aab3d8Srobert // Only add SDK directories that have symbols in them, some SDKs only
69*f6aab3d8Srobert // contain developer disk images and no symbols, so they aren't useful to
70*f6aab3d8Srobert // us.
71*f6aab3d8Srobert FileSpec sdk_symbols_symlink_fspec;
72*f6aab3d8Srobert for (const auto &sdk_directory_info : builtin_sdk_directory_infos) {
73*f6aab3d8Srobert sdk_symbols_symlink_fspec = sdk_directory_info.directory;
74*f6aab3d8Srobert sdk_symbols_symlink_fspec.AppendPathComponent("Symbols");
75*f6aab3d8Srobert if (FileSystem::Instance().Exists(sdk_symbols_symlink_fspec)) {
76*f6aab3d8Srobert m_sdk_directory_infos.push_back(sdk_directory_info);
77*f6aab3d8Srobert if (log) {
78*f6aab3d8Srobert LLDB_LOGF(log,
79*f6aab3d8Srobert "PlatformDarwinDevice::UpdateSDKDirectoryInfosIfNeeded "
80*f6aab3d8Srobert "added builtin SDK directory %s",
81*f6aab3d8Srobert sdk_symbols_symlink_fspec.GetPath().c_str());
82*f6aab3d8Srobert }
83*f6aab3d8Srobert }
84*f6aab3d8Srobert }
85*f6aab3d8Srobert
86*f6aab3d8Srobert const uint32_t num_installed = m_sdk_directory_infos.size();
87*f6aab3d8Srobert llvm::StringRef dirname = GetDeviceSupportDirectoryName();
88*f6aab3d8Srobert std::string local_sdk_cache_str = "~/Library/Developer/Xcode/";
89*f6aab3d8Srobert local_sdk_cache_str += std::string(dirname);
90*f6aab3d8Srobert FileSpec local_sdk_cache(local_sdk_cache_str.c_str());
91*f6aab3d8Srobert FileSystem::Instance().Resolve(local_sdk_cache);
92*f6aab3d8Srobert if (FileSystem::Instance().Exists(local_sdk_cache)) {
93*f6aab3d8Srobert if (log) {
94*f6aab3d8Srobert LLDB_LOGF(log,
95*f6aab3d8Srobert "PlatformDarwinDevice::UpdateSDKDirectoryInfosIfNeeded "
96*f6aab3d8Srobert "searching %s for additional SDKs",
97*f6aab3d8Srobert local_sdk_cache.GetPath().c_str());
98*f6aab3d8Srobert }
99*f6aab3d8Srobert char path[PATH_MAX];
100*f6aab3d8Srobert if (local_sdk_cache.GetPath(path, sizeof(path))) {
101*f6aab3d8Srobert FileSystem::Instance().EnumerateDirectory(
102*f6aab3d8Srobert path, find_directories, find_files, find_other,
103*f6aab3d8Srobert GetContainedFilesIntoVectorOfStringsCallback,
104*f6aab3d8Srobert &m_sdk_directory_infos);
105*f6aab3d8Srobert const uint32_t num_sdk_infos = m_sdk_directory_infos.size();
106*f6aab3d8Srobert // First try for an exact match of major, minor and update
107*f6aab3d8Srobert for (uint32_t i = num_installed; i < num_sdk_infos; ++i) {
108*f6aab3d8Srobert m_sdk_directory_infos[i].user_cached = true;
109*f6aab3d8Srobert if (log) {
110*f6aab3d8Srobert LLDB_LOGF(log,
111*f6aab3d8Srobert "PlatformDarwinDevice::"
112*f6aab3d8Srobert "UpdateSDKDirectoryInfosIfNeeded "
113*f6aab3d8Srobert "user SDK directory %s",
114*f6aab3d8Srobert m_sdk_directory_infos[i].directory.GetPath().c_str());
115*f6aab3d8Srobert }
116*f6aab3d8Srobert }
117*f6aab3d8Srobert }
118*f6aab3d8Srobert }
119*f6aab3d8Srobert
120*f6aab3d8Srobert const char *addtional_platform_dirs = getenv("PLATFORM_SDK_DIRECTORY");
121*f6aab3d8Srobert if (addtional_platform_dirs) {
122*f6aab3d8Srobert SDKDirectoryInfoCollection env_var_sdk_directory_infos;
123*f6aab3d8Srobert FileSystem::Instance().EnumerateDirectory(
124*f6aab3d8Srobert addtional_platform_dirs, find_directories, find_files, find_other,
125*f6aab3d8Srobert GetContainedFilesIntoVectorOfStringsCallback,
126*f6aab3d8Srobert &env_var_sdk_directory_infos);
127*f6aab3d8Srobert FileSpec sdk_symbols_symlink_fspec;
128*f6aab3d8Srobert for (const auto &sdk_directory_info : env_var_sdk_directory_infos) {
129*f6aab3d8Srobert sdk_symbols_symlink_fspec = sdk_directory_info.directory;
130*f6aab3d8Srobert sdk_symbols_symlink_fspec.AppendPathComponent("Symbols");
131*f6aab3d8Srobert if (FileSystem::Instance().Exists(sdk_symbols_symlink_fspec)) {
132*f6aab3d8Srobert m_sdk_directory_infos.push_back(sdk_directory_info);
133*f6aab3d8Srobert if (log) {
134*f6aab3d8Srobert LLDB_LOGF(log,
135*f6aab3d8Srobert "PlatformDarwinDevice::UpdateSDKDirectoryInfosIfNeeded "
136*f6aab3d8Srobert "added env var SDK directory %s",
137*f6aab3d8Srobert sdk_symbols_symlink_fspec.GetPath().c_str());
138*f6aab3d8Srobert }
139*f6aab3d8Srobert }
140*f6aab3d8Srobert }
141*f6aab3d8Srobert }
142*f6aab3d8Srobert }
143*f6aab3d8Srobert }
144*f6aab3d8Srobert return !m_sdk_directory_infos.empty();
145*f6aab3d8Srobert }
146*f6aab3d8Srobert
147*f6aab3d8Srobert const PlatformDarwinDevice::SDKDirectoryInfo *
GetSDKDirectoryForCurrentOSVersion()148*f6aab3d8Srobert PlatformDarwinDevice::GetSDKDirectoryForCurrentOSVersion() {
149*f6aab3d8Srobert uint32_t i;
150*f6aab3d8Srobert if (UpdateSDKDirectoryInfosIfNeeded()) {
151*f6aab3d8Srobert const uint32_t num_sdk_infos = m_sdk_directory_infos.size();
152*f6aab3d8Srobert std::vector<bool> check_sdk_info(num_sdk_infos, true);
153*f6aab3d8Srobert
154*f6aab3d8Srobert // Prefer the user SDK build string.
155*f6aab3d8Srobert ConstString build = GetSDKBuild();
156*f6aab3d8Srobert
157*f6aab3d8Srobert // Fall back to the platform's build string.
158*f6aab3d8Srobert if (!build) {
159*f6aab3d8Srobert if (std::optional<std::string> os_build_str = GetOSBuildString()) {
160*f6aab3d8Srobert build = ConstString(*os_build_str);
161*f6aab3d8Srobert }
162*f6aab3d8Srobert }
163*f6aab3d8Srobert
164*f6aab3d8Srobert // If we have a build string, only check platforms for which the build
165*f6aab3d8Srobert // string matches.
166*f6aab3d8Srobert if (build) {
167*f6aab3d8Srobert for (i = 0; i < num_sdk_infos; ++i)
168*f6aab3d8Srobert check_sdk_info[i] = m_sdk_directory_infos[i].build == build;
169*f6aab3d8Srobert }
170*f6aab3d8Srobert
171*f6aab3d8Srobert // If we are connected we can find the version of the OS the platform us
172*f6aab3d8Srobert // running on and select the right SDK
173*f6aab3d8Srobert llvm::VersionTuple version = GetOSVersion();
174*f6aab3d8Srobert if (!version.empty()) {
175*f6aab3d8Srobert if (UpdateSDKDirectoryInfosIfNeeded()) {
176*f6aab3d8Srobert // First try for an exact match of major, minor and update.
177*f6aab3d8Srobert for (i = 0; i < num_sdk_infos; ++i) {
178*f6aab3d8Srobert if (check_sdk_info[i]) {
179*f6aab3d8Srobert if (m_sdk_directory_infos[i].version == version)
180*f6aab3d8Srobert return &m_sdk_directory_infos[i];
181*f6aab3d8Srobert }
182*f6aab3d8Srobert }
183*f6aab3d8Srobert // Try for an exact match of major and minor.
184*f6aab3d8Srobert for (i = 0; i < num_sdk_infos; ++i) {
185*f6aab3d8Srobert if (check_sdk_info[i]) {
186*f6aab3d8Srobert if (m_sdk_directory_infos[i].version.getMajor() ==
187*f6aab3d8Srobert version.getMajor() &&
188*f6aab3d8Srobert m_sdk_directory_infos[i].version.getMinor() ==
189*f6aab3d8Srobert version.getMinor()) {
190*f6aab3d8Srobert return &m_sdk_directory_infos[i];
191*f6aab3d8Srobert }
192*f6aab3d8Srobert }
193*f6aab3d8Srobert }
194*f6aab3d8Srobert // Lastly try to match of major version only.
195*f6aab3d8Srobert for (i = 0; i < num_sdk_infos; ++i) {
196*f6aab3d8Srobert if (check_sdk_info[i]) {
197*f6aab3d8Srobert if (m_sdk_directory_infos[i].version.getMajor() ==
198*f6aab3d8Srobert version.getMajor()) {
199*f6aab3d8Srobert return &m_sdk_directory_infos[i];
200*f6aab3d8Srobert }
201*f6aab3d8Srobert }
202*f6aab3d8Srobert }
203*f6aab3d8Srobert }
204*f6aab3d8Srobert } else if (build) {
205*f6aab3d8Srobert // No version, just a build number, return the first one that matches.
206*f6aab3d8Srobert for (i = 0; i < num_sdk_infos; ++i)
207*f6aab3d8Srobert if (check_sdk_info[i])
208*f6aab3d8Srobert return &m_sdk_directory_infos[i];
209*f6aab3d8Srobert }
210*f6aab3d8Srobert }
211*f6aab3d8Srobert return nullptr;
212*f6aab3d8Srobert }
213*f6aab3d8Srobert
214*f6aab3d8Srobert const PlatformDarwinDevice::SDKDirectoryInfo *
GetSDKDirectoryForLatestOSVersion()215*f6aab3d8Srobert PlatformDarwinDevice::GetSDKDirectoryForLatestOSVersion() {
216*f6aab3d8Srobert const PlatformDarwinDevice::SDKDirectoryInfo *result = nullptr;
217*f6aab3d8Srobert if (UpdateSDKDirectoryInfosIfNeeded()) {
218*f6aab3d8Srobert auto max = std::max_element(
219*f6aab3d8Srobert m_sdk_directory_infos.begin(), m_sdk_directory_infos.end(),
220*f6aab3d8Srobert [](const SDKDirectoryInfo &a, const SDKDirectoryInfo &b) {
221*f6aab3d8Srobert return a.version < b.version;
222*f6aab3d8Srobert });
223*f6aab3d8Srobert if (max != m_sdk_directory_infos.end())
224*f6aab3d8Srobert result = &*max;
225*f6aab3d8Srobert }
226*f6aab3d8Srobert return result;
227*f6aab3d8Srobert }
228*f6aab3d8Srobert
GetDeviceSupportDirectory()229*f6aab3d8Srobert const char *PlatformDarwinDevice::GetDeviceSupportDirectory() {
230*f6aab3d8Srobert std::string platform_dir =
231*f6aab3d8Srobert ("/Platforms/" + GetPlatformName() + "/DeviceSupport").str();
232*f6aab3d8Srobert if (m_device_support_directory.empty()) {
233*f6aab3d8Srobert if (FileSpec fspec = HostInfo::GetXcodeDeveloperDirectory()) {
234*f6aab3d8Srobert m_device_support_directory = fspec.GetPath();
235*f6aab3d8Srobert m_device_support_directory.append(platform_dir.c_str());
236*f6aab3d8Srobert } else {
237*f6aab3d8Srobert // Assign a single NULL character so we know we tried to find the device
238*f6aab3d8Srobert // support directory and we don't keep trying to find it over and over.
239*f6aab3d8Srobert m_device_support_directory.assign(1, '\0');
240*f6aab3d8Srobert }
241*f6aab3d8Srobert }
242*f6aab3d8Srobert // We should have put a single NULL character into m_device_support_directory
243*f6aab3d8Srobert // or it should have a valid path if the code gets here
244*f6aab3d8Srobert assert(m_device_support_directory.empty() == false);
245*f6aab3d8Srobert if (m_device_support_directory[0])
246*f6aab3d8Srobert return m_device_support_directory.c_str();
247*f6aab3d8Srobert return nullptr;
248*f6aab3d8Srobert }
249*f6aab3d8Srobert
GetDeviceSupportDirectoryForOSVersion()250*f6aab3d8Srobert const char *PlatformDarwinDevice::GetDeviceSupportDirectoryForOSVersion() {
251*f6aab3d8Srobert if (m_sdk_sysroot)
252*f6aab3d8Srobert return m_sdk_sysroot.GetCString();
253*f6aab3d8Srobert
254*f6aab3d8Srobert if (m_device_support_directory_for_os_version.empty()) {
255*f6aab3d8Srobert const PlatformDarwinDevice::SDKDirectoryInfo *sdk_dir_info =
256*f6aab3d8Srobert GetSDKDirectoryForCurrentOSVersion();
257*f6aab3d8Srobert if (sdk_dir_info == nullptr)
258*f6aab3d8Srobert sdk_dir_info = GetSDKDirectoryForLatestOSVersion();
259*f6aab3d8Srobert if (sdk_dir_info) {
260*f6aab3d8Srobert char path[PATH_MAX];
261*f6aab3d8Srobert if (sdk_dir_info->directory.GetPath(path, sizeof(path))) {
262*f6aab3d8Srobert m_device_support_directory_for_os_version = path;
263*f6aab3d8Srobert return m_device_support_directory_for_os_version.c_str();
264*f6aab3d8Srobert }
265*f6aab3d8Srobert } else {
266*f6aab3d8Srobert // Assign a single NULL character so we know we tried to find the device
267*f6aab3d8Srobert // support directory and we don't keep trying to find it over and over.
268*f6aab3d8Srobert m_device_support_directory_for_os_version.assign(1, '\0');
269*f6aab3d8Srobert }
270*f6aab3d8Srobert }
271*f6aab3d8Srobert // We should have put a single NULL character into
272*f6aab3d8Srobert // m_device_support_directory_for_os_version or it should have a valid path
273*f6aab3d8Srobert // if the code gets here
274*f6aab3d8Srobert assert(m_device_support_directory_for_os_version.empty() == false);
275*f6aab3d8Srobert if (m_device_support_directory_for_os_version[0])
276*f6aab3d8Srobert return m_device_support_directory_for_os_version.c_str();
277*f6aab3d8Srobert return nullptr;
278*f6aab3d8Srobert }
279*f6aab3d8Srobert
280*f6aab3d8Srobert static lldb_private::Status
MakeCacheFolderForFile(const FileSpec & module_cache_spec)281*f6aab3d8Srobert MakeCacheFolderForFile(const FileSpec &module_cache_spec) {
282*f6aab3d8Srobert FileSpec module_cache_folder =
283*f6aab3d8Srobert module_cache_spec.CopyByRemovingLastPathComponent();
284*f6aab3d8Srobert return llvm::sys::fs::create_directory(module_cache_folder.GetPath());
285*f6aab3d8Srobert }
286*f6aab3d8Srobert
287*f6aab3d8Srobert static lldb_private::Status
BringInRemoteFile(Platform * platform,const lldb_private::ModuleSpec & module_spec,const FileSpec & module_cache_spec)288*f6aab3d8Srobert BringInRemoteFile(Platform *platform,
289*f6aab3d8Srobert const lldb_private::ModuleSpec &module_spec,
290*f6aab3d8Srobert const FileSpec &module_cache_spec) {
291*f6aab3d8Srobert MakeCacheFolderForFile(module_cache_spec);
292*f6aab3d8Srobert Status err = platform->GetFile(module_spec.GetFileSpec(), module_cache_spec);
293*f6aab3d8Srobert return err;
294*f6aab3d8Srobert }
295*f6aab3d8Srobert
GetSharedModuleWithLocalCache(const lldb_private::ModuleSpec & module_spec,lldb::ModuleSP & module_sp,const lldb_private::FileSpecList * module_search_paths_ptr,llvm::SmallVectorImpl<lldb::ModuleSP> * old_modules,bool * did_create_ptr)296*f6aab3d8Srobert lldb_private::Status PlatformDarwinDevice::GetSharedModuleWithLocalCache(
297*f6aab3d8Srobert const lldb_private::ModuleSpec &module_spec, lldb::ModuleSP &module_sp,
298*f6aab3d8Srobert const lldb_private::FileSpecList *module_search_paths_ptr,
299*f6aab3d8Srobert llvm::SmallVectorImpl<lldb::ModuleSP> *old_modules, bool *did_create_ptr) {
300*f6aab3d8Srobert
301*f6aab3d8Srobert Log *log = GetLog(LLDBLog::Platform);
302*f6aab3d8Srobert LLDB_LOGF(log,
303*f6aab3d8Srobert "[%s] Trying to find module %s/%s - platform path %s/%s symbol "
304*f6aab3d8Srobert "path %s/%s",
305*f6aab3d8Srobert (IsHost() ? "host" : "remote"),
306*f6aab3d8Srobert module_spec.GetFileSpec().GetDirectory().AsCString(),
307*f6aab3d8Srobert module_spec.GetFileSpec().GetFilename().AsCString(),
308*f6aab3d8Srobert module_spec.GetPlatformFileSpec().GetDirectory().AsCString(),
309*f6aab3d8Srobert module_spec.GetPlatformFileSpec().GetFilename().AsCString(),
310*f6aab3d8Srobert module_spec.GetSymbolFileSpec().GetDirectory().AsCString(),
311*f6aab3d8Srobert module_spec.GetSymbolFileSpec().GetFilename().AsCString());
312*f6aab3d8Srobert
313*f6aab3d8Srobert Status err;
314*f6aab3d8Srobert
315*f6aab3d8Srobert if (CheckLocalSharedCache()) {
316*f6aab3d8Srobert // When debugging on the host, we are most likely using the same shared
317*f6aab3d8Srobert // cache as our inferior. The dylibs from the shared cache might not
318*f6aab3d8Srobert // exist on the filesystem, so let's use the images in our own memory
319*f6aab3d8Srobert // to create the modules.
320*f6aab3d8Srobert
321*f6aab3d8Srobert // Check if the requested image is in our shared cache.
322*f6aab3d8Srobert SharedCacheImageInfo image_info =
323*f6aab3d8Srobert HostInfo::GetSharedCacheImageInfo(module_spec.GetFileSpec().GetPath());
324*f6aab3d8Srobert
325*f6aab3d8Srobert // If we found it and it has the correct UUID, let's proceed with
326*f6aab3d8Srobert // creating a module from the memory contents.
327*f6aab3d8Srobert if (image_info.uuid &&
328*f6aab3d8Srobert (!module_spec.GetUUID() || module_spec.GetUUID() == image_info.uuid)) {
329*f6aab3d8Srobert ModuleSpec shared_cache_spec(module_spec.GetFileSpec(), image_info.uuid,
330*f6aab3d8Srobert image_info.data_sp);
331*f6aab3d8Srobert err = ModuleList::GetSharedModule(shared_cache_spec, module_sp,
332*f6aab3d8Srobert module_search_paths_ptr, old_modules,
333*f6aab3d8Srobert did_create_ptr);
334*f6aab3d8Srobert if (module_sp) {
335*f6aab3d8Srobert LLDB_LOGF(log, "[%s] module %s was found in the in-memory shared cache",
336*f6aab3d8Srobert (IsHost() ? "host" : "remote"),
337*f6aab3d8Srobert module_spec.GetFileSpec().GetPath().c_str());
338*f6aab3d8Srobert return err;
339*f6aab3d8Srobert }
340*f6aab3d8Srobert }
341*f6aab3d8Srobert
342*f6aab3d8Srobert // We failed to find the module in our shared cache. Let's see if we have a
343*f6aab3d8Srobert // copy in our device support directory.
344*f6aab3d8Srobert FileSpec device_support_spec(GetDeviceSupportDirectoryForOSVersion());
345*f6aab3d8Srobert device_support_spec.AppendPathComponent("Symbols");
346*f6aab3d8Srobert device_support_spec.AppendPathComponent(
347*f6aab3d8Srobert module_spec.GetFileSpec().GetPath());
348*f6aab3d8Srobert FileSystem::Instance().Resolve(device_support_spec);
349*f6aab3d8Srobert if (FileSystem::Instance().Exists(device_support_spec)) {
350*f6aab3d8Srobert ModuleSpec local_spec(device_support_spec, module_spec.GetUUID());
351*f6aab3d8Srobert err = ModuleList::GetSharedModule(local_spec, module_sp,
352*f6aab3d8Srobert module_search_paths_ptr, old_modules,
353*f6aab3d8Srobert did_create_ptr);
354*f6aab3d8Srobert if (module_sp) {
355*f6aab3d8Srobert LLDB_LOGF(log,
356*f6aab3d8Srobert "[%s] module %s was found in Device Support "
357*f6aab3d8Srobert "directory: %s",
358*f6aab3d8Srobert (IsHost() ? "host" : "remote"),
359*f6aab3d8Srobert module_spec.GetFileSpec().GetPath().c_str(),
360*f6aab3d8Srobert local_spec.GetFileSpec().GetPath().c_str());
361*f6aab3d8Srobert return err;
362*f6aab3d8Srobert }
363*f6aab3d8Srobert }
364*f6aab3d8Srobert }
365*f6aab3d8Srobert
366*f6aab3d8Srobert err = ModuleList::GetSharedModule(module_spec, module_sp,
367*f6aab3d8Srobert module_search_paths_ptr, old_modules,
368*f6aab3d8Srobert did_create_ptr);
369*f6aab3d8Srobert if (module_sp)
370*f6aab3d8Srobert return err;
371*f6aab3d8Srobert
372*f6aab3d8Srobert if (!IsHost()) {
373*f6aab3d8Srobert std::string cache_path(GetLocalCacheDirectory());
374*f6aab3d8Srobert // Only search for a locally cached file if we have a valid cache path
375*f6aab3d8Srobert if (!cache_path.empty()) {
376*f6aab3d8Srobert std::string module_path(module_spec.GetFileSpec().GetPath());
377*f6aab3d8Srobert cache_path.append(module_path);
378*f6aab3d8Srobert FileSpec module_cache_spec(cache_path);
379*f6aab3d8Srobert
380*f6aab3d8Srobert // if rsync is supported, always bring in the file - rsync will be very
381*f6aab3d8Srobert // efficient when files are the same on the local and remote end of the
382*f6aab3d8Srobert // connection
383*f6aab3d8Srobert if (this->GetSupportsRSync()) {
384*f6aab3d8Srobert err = BringInRemoteFile(this, module_spec, module_cache_spec);
385*f6aab3d8Srobert if (err.Fail())
386*f6aab3d8Srobert return err;
387*f6aab3d8Srobert if (FileSystem::Instance().Exists(module_cache_spec)) {
388*f6aab3d8Srobert Log *log = GetLog(LLDBLog::Platform);
389*f6aab3d8Srobert LLDB_LOGF(log, "[%s] module %s/%s was rsynced and is now there",
390*f6aab3d8Srobert (IsHost() ? "host" : "remote"),
391*f6aab3d8Srobert module_spec.GetFileSpec().GetDirectory().AsCString(),
392*f6aab3d8Srobert module_spec.GetFileSpec().GetFilename().AsCString());
393*f6aab3d8Srobert ModuleSpec local_spec(module_cache_spec,
394*f6aab3d8Srobert module_spec.GetArchitecture());
395*f6aab3d8Srobert module_sp = std::make_shared<Module>(local_spec);
396*f6aab3d8Srobert module_sp->SetPlatformFileSpec(module_spec.GetFileSpec());
397*f6aab3d8Srobert return Status();
398*f6aab3d8Srobert }
399*f6aab3d8Srobert }
400*f6aab3d8Srobert
401*f6aab3d8Srobert // try to find the module in the cache
402*f6aab3d8Srobert if (FileSystem::Instance().Exists(module_cache_spec)) {
403*f6aab3d8Srobert // get the local and remote MD5 and compare
404*f6aab3d8Srobert if (m_remote_platform_sp) {
405*f6aab3d8Srobert // when going over the *slow* GDB remote transfer mechanism we first
406*f6aab3d8Srobert // check the hashes of the files - and only do the actual transfer if
407*f6aab3d8Srobert // they differ
408*f6aab3d8Srobert uint64_t high_local, high_remote, low_local, low_remote;
409*f6aab3d8Srobert auto MD5 = llvm::sys::fs::md5_contents(module_cache_spec.GetPath());
410*f6aab3d8Srobert if (!MD5)
411*f6aab3d8Srobert return Status(MD5.getError());
412*f6aab3d8Srobert std::tie(high_local, low_local) = MD5->words();
413*f6aab3d8Srobert
414*f6aab3d8Srobert m_remote_platform_sp->CalculateMD5(module_spec.GetFileSpec(),
415*f6aab3d8Srobert low_remote, high_remote);
416*f6aab3d8Srobert if (low_local != low_remote || high_local != high_remote) {
417*f6aab3d8Srobert // bring in the remote file
418*f6aab3d8Srobert Log *log = GetLog(LLDBLog::Platform);
419*f6aab3d8Srobert LLDB_LOGF(log,
420*f6aab3d8Srobert "[%s] module %s/%s needs to be replaced from remote copy",
421*f6aab3d8Srobert (IsHost() ? "host" : "remote"),
422*f6aab3d8Srobert module_spec.GetFileSpec().GetDirectory().AsCString(),
423*f6aab3d8Srobert module_spec.GetFileSpec().GetFilename().AsCString());
424*f6aab3d8Srobert Status err =
425*f6aab3d8Srobert BringInRemoteFile(this, module_spec, module_cache_spec);
426*f6aab3d8Srobert if (err.Fail())
427*f6aab3d8Srobert return err;
428*f6aab3d8Srobert }
429*f6aab3d8Srobert }
430*f6aab3d8Srobert
431*f6aab3d8Srobert ModuleSpec local_spec(module_cache_spec, module_spec.GetArchitecture());
432*f6aab3d8Srobert module_sp = std::make_shared<Module>(local_spec);
433*f6aab3d8Srobert module_sp->SetPlatformFileSpec(module_spec.GetFileSpec());
434*f6aab3d8Srobert Log *log = GetLog(LLDBLog::Platform);
435*f6aab3d8Srobert LLDB_LOGF(log, "[%s] module %s/%s was found in the cache",
436*f6aab3d8Srobert (IsHost() ? "host" : "remote"),
437*f6aab3d8Srobert module_spec.GetFileSpec().GetDirectory().AsCString(),
438*f6aab3d8Srobert module_spec.GetFileSpec().GetFilename().AsCString());
439*f6aab3d8Srobert return Status();
440*f6aab3d8Srobert }
441*f6aab3d8Srobert
442*f6aab3d8Srobert // bring in the remote module file
443*f6aab3d8Srobert LLDB_LOGF(log, "[%s] module %s/%s needs to come in remotely",
444*f6aab3d8Srobert (IsHost() ? "host" : "remote"),
445*f6aab3d8Srobert module_spec.GetFileSpec().GetDirectory().AsCString(),
446*f6aab3d8Srobert module_spec.GetFileSpec().GetFilename().AsCString());
447*f6aab3d8Srobert Status err = BringInRemoteFile(this, module_spec, module_cache_spec);
448*f6aab3d8Srobert if (err.Fail())
449*f6aab3d8Srobert return err;
450*f6aab3d8Srobert if (FileSystem::Instance().Exists(module_cache_spec)) {
451*f6aab3d8Srobert Log *log = GetLog(LLDBLog::Platform);
452*f6aab3d8Srobert LLDB_LOGF(log, "[%s] module %s/%s is now cached and fine",
453*f6aab3d8Srobert (IsHost() ? "host" : "remote"),
454*f6aab3d8Srobert module_spec.GetFileSpec().GetDirectory().AsCString(),
455*f6aab3d8Srobert module_spec.GetFileSpec().GetFilename().AsCString());
456*f6aab3d8Srobert ModuleSpec local_spec(module_cache_spec, module_spec.GetArchitecture());
457*f6aab3d8Srobert module_sp = std::make_shared<Module>(local_spec);
458*f6aab3d8Srobert module_sp->SetPlatformFileSpec(module_spec.GetFileSpec());
459*f6aab3d8Srobert return Status();
460*f6aab3d8Srobert } else
461*f6aab3d8Srobert return Status("unable to obtain valid module file");
462*f6aab3d8Srobert } else
463*f6aab3d8Srobert return Status("no cache path");
464*f6aab3d8Srobert } else
465*f6aab3d8Srobert return Status("unable to resolve module");
466*f6aab3d8Srobert }
467