1 //===-- PlatformRemoteDarwinDevice.cpp -----------------------------------*- C++ -*-===//
2 //
3 //                     The LLVM Compiler Infrastructure
4 //
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
7 //
8 //===----------------------------------------------------------------------===//
9 
10 #include "PlatformRemoteDarwinDevice.h"
11 
12 // C Includes
13 // C++ Includes
14 // Other libraries and framework includes
15 // Project includes
16 #include "lldb/Breakpoint/BreakpointLocation.h"
17 #include "lldb/Core/Module.h"
18 #include "lldb/Core/ModuleList.h"
19 #include "lldb/Core/ModuleSpec.h"
20 #include "lldb/Core/PluginManager.h"
21 #include "lldb/Host/FileSystem.h"
22 #include "lldb/Host/Host.h"
23 #include "lldb/Target/Process.h"
24 #include "lldb/Target/Target.h"
25 #include "lldb/Utility/FileSpec.h"
26 #include "lldb/Utility/Log.h"
27 #include "lldb/Utility/Status.h"
28 #include "lldb/Utility/StreamString.h"
29 
30 using namespace lldb;
31 using namespace lldb_private;
32 
33 PlatformRemoteDarwinDevice::SDKDirectoryInfo::SDKDirectoryInfo(
34     const lldb_private::FileSpec &sdk_dir)
35     : directory(sdk_dir), build(), user_cached(false) {
36   llvm::StringRef dirname_str = sdk_dir.GetFilename().GetStringRef();
37   llvm::StringRef build_str;
38   std::tie(version, build_str) = ParseVersionBuildDir(dirname_str);
39   build.SetString(build_str);
40 }
41 
42 //------------------------------------------------------------------
43 /// Default Constructor
44 //------------------------------------------------------------------
45 PlatformRemoteDarwinDevice::PlatformRemoteDarwinDevice()
46     : PlatformDarwin(false), // This is a remote platform
47       m_sdk_directory_infos(), m_device_support_directory(),
48       m_device_support_directory_for_os_version(), m_build_update(),
49       m_last_module_sdk_idx(UINT32_MAX),
50       m_connected_module_sdk_idx(UINT32_MAX) {}
51 
52 //------------------------------------------------------------------
53 /// Destructor.
54 ///
55 /// The destructor is virtual since this class is designed to be
56 /// inherited from by the plug-in instance.
57 //------------------------------------------------------------------
58 PlatformRemoteDarwinDevice::~PlatformRemoteDarwinDevice() {}
59 
60 void PlatformRemoteDarwinDevice::GetStatus(Stream &strm) {
61   Platform::GetStatus(strm);
62   const char *sdk_directory = GetDeviceSupportDirectoryForOSVersion();
63   if (sdk_directory)
64     strm.Printf("  SDK Path: \"%s\"\n", sdk_directory);
65   else
66     strm.PutCString("  SDK Path: error: unable to locate SDK\n");
67 
68   const uint32_t num_sdk_infos = m_sdk_directory_infos.size();
69   for (uint32_t i = 0; i < num_sdk_infos; ++i) {
70     const SDKDirectoryInfo &sdk_dir_info = m_sdk_directory_infos[i];
71     strm.Printf(" SDK Roots: [%2u] \"%s\"\n", i,
72                 sdk_dir_info.directory.GetPath().c_str());
73   }
74 }
75 
76 Status PlatformRemoteDarwinDevice::ResolveExecutable(
77     const ModuleSpec &ms, lldb::ModuleSP &exe_module_sp,
78     const FileSpecList *module_search_paths_ptr) {
79   Status error;
80   // Nothing special to do here, just use the actual file and architecture
81 
82   ModuleSpec resolved_module_spec(ms);
83 
84   // Resolve any executable within a bundle on MacOSX
85   // TODO: verify that this handles shallow bundles, if not then implement one
86   // ourselves
87   Host::ResolveExecutableInBundle(resolved_module_spec.GetFileSpec());
88 
89   if (FileSystem::Instance().Exists(resolved_module_spec.GetFileSpec())) {
90     if (resolved_module_spec.GetArchitecture().IsValid() ||
91         resolved_module_spec.GetUUID().IsValid()) {
92       error = ModuleList::GetSharedModule(resolved_module_spec, exe_module_sp,
93                                           NULL, NULL, NULL);
94 
95       if (exe_module_sp && exe_module_sp->GetObjectFile())
96         return error;
97       exe_module_sp.reset();
98     }
99     // No valid architecture was specified or the exact ARM slice wasn't found
100     // so ask the platform for the architectures that we should be using (in
101     // the correct order) and see if we can find a match that way
102     StreamString arch_names;
103     for (uint32_t idx = 0; GetSupportedArchitectureAtIndex(
104              idx, resolved_module_spec.GetArchitecture());
105          ++idx) {
106       error = ModuleList::GetSharedModule(resolved_module_spec, exe_module_sp,
107                                           NULL, NULL, NULL);
108       // Did we find an executable using one of the
109       if (error.Success()) {
110         if (exe_module_sp && exe_module_sp->GetObjectFile())
111           break;
112         else
113           error.SetErrorToGenericError();
114       }
115 
116       if (idx > 0)
117         arch_names.PutCString(", ");
118       arch_names.PutCString(
119           resolved_module_spec.GetArchitecture().GetArchitectureName());
120     }
121 
122     if (error.Fail() || !exe_module_sp) {
123       if (FileSystem::Instance().Readable(resolved_module_spec.GetFileSpec())) {
124         error.SetErrorStringWithFormat(
125             "'%s' doesn't contain any '%s' platform architectures: %s",
126             resolved_module_spec.GetFileSpec().GetPath().c_str(),
127             GetPluginName().GetCString(), arch_names.GetData());
128       } else {
129         error.SetErrorStringWithFormat(
130             "'%s' is not readable",
131             resolved_module_spec.GetFileSpec().GetPath().c_str());
132       }
133     }
134   } else {
135     error.SetErrorStringWithFormat(
136         "'%s' does not exist",
137         resolved_module_spec.GetFileSpec().GetPath().c_str());
138   }
139 
140   return error;
141 }
142 
143 FileSystem::EnumerateDirectoryResult
144 PlatformRemoteDarwinDevice::GetContainedFilesIntoVectorOfStringsCallback(
145     void *baton, llvm::sys::fs::file_type ft, llvm::StringRef path) {
146   ((PlatformRemoteDarwinDevice::SDKDirectoryInfoCollection *)baton)
147       ->push_back(
148           PlatformRemoteDarwinDevice::SDKDirectoryInfo(FileSpec(path, false)));
149   return FileSystem::eEnumerateDirectoryResultNext;
150 }
151 
152 bool PlatformRemoteDarwinDevice::UpdateSDKDirectoryInfosIfNeeded() {
153   Log *log = lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_HOST);
154   std::lock_guard<std::mutex> guard(m_sdk_dir_mutex);
155   if (m_sdk_directory_infos.empty()) {
156     // A --sysroot option was supplied - add it to our list of SDKs to check
157     if (m_sdk_sysroot) {
158       FileSpec sdk_sysroot_fspec(m_sdk_sysroot.GetCString(), true);
159       const SDKDirectoryInfo sdk_sysroot_directory_info(sdk_sysroot_fspec);
160       m_sdk_directory_infos.push_back(sdk_sysroot_directory_info);
161       if (log) {
162         log->Printf("PlatformRemoteDarwinDevice::UpdateSDKDirectoryInfosIfNeeded added "
163                     "--sysroot SDK directory %s",
164                     m_sdk_sysroot.GetCString());
165       }
166       return true;
167     }
168     const char *device_support_dir = GetDeviceSupportDirectory();
169     if (log) {
170       log->Printf("PlatformRemoteDarwinDevice::UpdateSDKDirectoryInfosIfNeeded Got "
171                   "DeviceSupport directory %s",
172                   device_support_dir);
173     }
174     if (device_support_dir) {
175       const bool find_directories = true;
176       const bool find_files = false;
177       const bool find_other = false;
178 
179       SDKDirectoryInfoCollection builtin_sdk_directory_infos;
180       FileSystem::Instance().EnumerateDirectory(
181           m_device_support_directory, find_directories, find_files, find_other,
182           GetContainedFilesIntoVectorOfStringsCallback,
183           &builtin_sdk_directory_infos);
184 
185       // Only add SDK directories that have symbols in them, some SDKs only
186       // contain developer disk images and no symbols, so they aren't useful to
187       // us.
188       FileSpec sdk_symbols_symlink_fspec;
189       for (const auto &sdk_directory_info : builtin_sdk_directory_infos) {
190         sdk_symbols_symlink_fspec = sdk_directory_info.directory;
191         sdk_symbols_symlink_fspec.AppendPathComponent("Symbols");
192         if (FileSystem::Instance().Exists(sdk_symbols_symlink_fspec)) {
193           m_sdk_directory_infos.push_back(sdk_directory_info);
194           if (log) {
195             log->Printf("PlatformRemoteDarwinDevice::UpdateSDKDirectoryInfosIfNeeded "
196                         "added builtin SDK directory %s",
197                         sdk_symbols_symlink_fspec.GetPath().c_str());
198           }
199         }
200       }
201 
202       std::vector<std::string>  device_support_dirnames;
203       GetDeviceSupportDirectoryNames (device_support_dirnames);
204 
205       for (std::string &dirname : device_support_dirnames)
206       {
207         const uint32_t num_installed = m_sdk_directory_infos.size();
208         std::string local_sdk_cache_str = "~/Library/Developer/Xcode/";
209         local_sdk_cache_str += dirname;
210         FileSpec local_sdk_cache(local_sdk_cache_str.c_str(), true);
211         if (FileSystem::Instance().Exists(local_sdk_cache)) {
212           if (log) {
213             log->Printf("PlatformRemoteDarwinDevice::UpdateSDKDirectoryInfosIfNeeded "
214                         "searching %s for additional SDKs",
215                         local_sdk_cache.GetPath().c_str());
216           }
217             char path[PATH_MAX];
218             if (local_sdk_cache.GetPath(path, sizeof(path))) {
219               FileSystem::Instance().EnumerateDirectory(
220                   path, find_directories, find_files, find_other,
221                   GetContainedFilesIntoVectorOfStringsCallback,
222                   &m_sdk_directory_infos);
223               const uint32_t num_sdk_infos = m_sdk_directory_infos.size();
224               // First try for an exact match of major, minor and update
225               for (uint32_t i = num_installed; i < num_sdk_infos; ++i) {
226                 m_sdk_directory_infos[i].user_cached = true;
227                 if (log) {
228                 log->Printf("PlatformRemoteDarwinDevice::UpdateSDKDirectoryInfosIfNeeded "
229                             "user SDK directory %s",
230                             m_sdk_directory_infos[i].directory.GetPath().c_str());
231                 }
232             }
233           }
234         }
235       }
236 
237       const char *addtional_platform_dirs = getenv("PLATFORM_SDK_DIRECTORY");
238       if (addtional_platform_dirs) {
239         SDKDirectoryInfoCollection env_var_sdk_directory_infos;
240         FileSystem::Instance().EnumerateDirectory(
241             addtional_platform_dirs, find_directories, find_files, find_other,
242             GetContainedFilesIntoVectorOfStringsCallback,
243             &env_var_sdk_directory_infos);
244         FileSpec sdk_symbols_symlink_fspec;
245         for (const auto &sdk_directory_info : env_var_sdk_directory_infos) {
246           sdk_symbols_symlink_fspec = sdk_directory_info.directory;
247           sdk_symbols_symlink_fspec.AppendPathComponent("Symbols");
248           if (FileSystem::Instance().Exists(sdk_symbols_symlink_fspec)) {
249             m_sdk_directory_infos.push_back(sdk_directory_info);
250             if (log) {
251               log->Printf("PlatformRemoteDarwinDevice::UpdateSDKDirectoryInfosIfNeeded "
252                           "added env var SDK directory %s",
253                           sdk_symbols_symlink_fspec.GetPath().c_str());
254             }
255           }
256         }
257       }
258 
259     }
260   }
261   return !m_sdk_directory_infos.empty();
262 }
263 
264 const PlatformRemoteDarwinDevice::SDKDirectoryInfo *
265 PlatformRemoteDarwinDevice::GetSDKDirectoryForCurrentOSVersion() {
266   uint32_t i;
267   if (UpdateSDKDirectoryInfosIfNeeded()) {
268     const uint32_t num_sdk_infos = m_sdk_directory_infos.size();
269 
270     // Check to see if the user specified a build string. If they did, then be
271     // sure to match it.
272     std::vector<bool> check_sdk_info(num_sdk_infos, true);
273     ConstString build(m_sdk_build);
274     if (build) {
275       for (i = 0; i < num_sdk_infos; ++i)
276         check_sdk_info[i] = m_sdk_directory_infos[i].build == build;
277     }
278 
279     // If we are connected we can find the version of the OS the platform us
280     // running on and select the right SDK
281     llvm::VersionTuple version = GetOSVersion();
282     if (!version.empty()) {
283       if (UpdateSDKDirectoryInfosIfNeeded()) {
284         // First try for an exact match of major, minor and update
285         for (i = 0; i < num_sdk_infos; ++i) {
286           if (check_sdk_info[i]) {
287             if (m_sdk_directory_infos[i].version == version)
288               return &m_sdk_directory_infos[i];
289           }
290         }
291         // First try for an exact match of major and minor
292         for (i = 0; i < num_sdk_infos; ++i) {
293           if (check_sdk_info[i]) {
294             if (m_sdk_directory_infos[i].version.getMajor() ==
295                     version.getMajor() &&
296                 m_sdk_directory_infos[i].version.getMinor() ==
297                     version.getMinor()) {
298               return &m_sdk_directory_infos[i];
299             }
300           }
301         }
302         // Lastly try to match of major version only..
303         for (i = 0; i < num_sdk_infos; ++i) {
304           if (check_sdk_info[i]) {
305             if (m_sdk_directory_infos[i].version.getMajor() ==
306                 version.getMajor()) {
307               return &m_sdk_directory_infos[i];
308             }
309           }
310         }
311       }
312     } else if (build) {
313       // No version, just a build number, search for the first one that matches
314       for (i = 0; i < num_sdk_infos; ++i)
315         if (check_sdk_info[i])
316           return &m_sdk_directory_infos[i];
317     }
318   }
319   return NULL;
320 }
321 
322 const PlatformRemoteDarwinDevice::SDKDirectoryInfo *
323 PlatformRemoteDarwinDevice::GetSDKDirectoryForLatestOSVersion() {
324   const PlatformRemoteDarwinDevice::SDKDirectoryInfo *result = NULL;
325   if (UpdateSDKDirectoryInfosIfNeeded()) {
326     auto max = std::max_element(
327         m_sdk_directory_infos.begin(), m_sdk_directory_infos.end(),
328         [](const SDKDirectoryInfo &a, const SDKDirectoryInfo &b) {
329           return a.version < b.version;
330         });
331     if (max != m_sdk_directory_infos.end())
332       result = &*max;
333   }
334   return result;
335 }
336 
337 const char *PlatformRemoteDarwinDevice::GetDeviceSupportDirectory() {
338   std::string platform_dir = "/Platforms/" + GetPlatformName() + "/DeviceSupport";
339   if (m_device_support_directory.empty()) {
340     const char *device_support_dir = GetDeveloperDirectory();
341     if (device_support_dir) {
342       m_device_support_directory.assign(device_support_dir);
343       m_device_support_directory.append(platform_dir.c_str());
344     } else {
345       // Assign a single NULL character so we know we tried to find the device
346       // support directory and we don't keep trying to find it over and over.
347       m_device_support_directory.assign(1, '\0');
348     }
349   }
350   // We should have put a single NULL character into m_device_support_directory
351   // or it should have a valid path if the code gets here
352   assert(m_device_support_directory.empty() == false);
353   if (m_device_support_directory[0])
354     return m_device_support_directory.c_str();
355   return NULL;
356 }
357 
358 const char *PlatformRemoteDarwinDevice::GetDeviceSupportDirectoryForOSVersion() {
359   if (m_sdk_sysroot)
360     return m_sdk_sysroot.GetCString();
361 
362   if (m_device_support_directory_for_os_version.empty()) {
363     const PlatformRemoteDarwinDevice::SDKDirectoryInfo *sdk_dir_info =
364         GetSDKDirectoryForCurrentOSVersion();
365     if (sdk_dir_info == NULL)
366       sdk_dir_info = GetSDKDirectoryForLatestOSVersion();
367     if (sdk_dir_info) {
368       char path[PATH_MAX];
369       if (sdk_dir_info->directory.GetPath(path, sizeof(path))) {
370         m_device_support_directory_for_os_version = path;
371         return m_device_support_directory_for_os_version.c_str();
372       }
373     } else {
374       // Assign a single NULL character so we know we tried to find the device
375       // support directory and we don't keep trying to find it over and over.
376       m_device_support_directory_for_os_version.assign(1, '\0');
377     }
378   }
379   // We should have put a single NULL character into
380   // m_device_support_directory_for_os_version or it should have a valid path
381   // if the code gets here
382   assert(m_device_support_directory_for_os_version.empty() == false);
383   if (m_device_support_directory_for_os_version[0])
384     return m_device_support_directory_for_os_version.c_str();
385   return NULL;
386 }
387 
388 uint32_t PlatformRemoteDarwinDevice::FindFileInAllSDKs(const char *platform_file_path,
389                                               FileSpecList &file_list) {
390   Log *log = lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_HOST);
391   if (platform_file_path && platform_file_path[0] &&
392       UpdateSDKDirectoryInfosIfNeeded()) {
393     const uint32_t num_sdk_infos = m_sdk_directory_infos.size();
394     lldb_private::FileSpec local_file;
395     // First try for an exact match of major, minor and update
396     for (uint32_t sdk_idx = 0; sdk_idx < num_sdk_infos; ++sdk_idx) {
397       LLDB_LOGV(log, "Searching for {0} in sdk path {1}", platform_file_path,
398                 m_sdk_directory_infos[sdk_idx].directory);
399       if (GetFileInSDK(platform_file_path, sdk_idx, local_file)) {
400         file_list.Append(local_file);
401       }
402     }
403   }
404   return file_list.GetSize();
405 }
406 
407 bool PlatformRemoteDarwinDevice::GetFileInSDK(const char *platform_file_path,
408                                      uint32_t sdk_idx,
409                                      lldb_private::FileSpec &local_file) {
410   Log *log = lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_HOST);
411   if (sdk_idx < m_sdk_directory_infos.size()) {
412     std::string sdkroot_path =
413         m_sdk_directory_infos[sdk_idx].directory.GetPath();
414     local_file.Clear();
415 
416     if (!sdkroot_path.empty() && platform_file_path && platform_file_path[0]) {
417       // We may need to interpose "/Symbols/" or "/Symbols.Internal/" between
418       // the
419       // SDK root directory and the file path.
420 
421       const char *paths_to_try[] = {"Symbols", "", "Symbols.Internal", nullptr};
422       for (size_t i = 0; paths_to_try[i] != nullptr; i++) {
423         local_file.SetFile(sdkroot_path, false, FileSpec::Style::native);
424         if (paths_to_try[i][0] != '\0')
425           local_file.AppendPathComponent(paths_to_try[i]);
426         local_file.AppendPathComponent(platform_file_path);
427         local_file.ResolvePath();
428         if (FileSystem::Instance().Exists(local_file)) {
429           if (log)
430             log->Printf("Found a copy of %s in the SDK dir %s/%s",
431                         platform_file_path, sdkroot_path.c_str(),
432                         paths_to_try[i]);
433           return true;
434         }
435         local_file.Clear();
436       }
437     }
438   }
439   return false;
440 }
441 
442 Status PlatformRemoteDarwinDevice::GetSymbolFile(const FileSpec &platform_file,
443                                                  const UUID *uuid_ptr,
444                                                  FileSpec &local_file) {
445   Log *log = lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_HOST);
446   Status error;
447   char platform_file_path[PATH_MAX];
448   if (platform_file.GetPath(platform_file_path, sizeof(platform_file_path))) {
449     char resolved_path[PATH_MAX];
450 
451     const char *os_version_dir = GetDeviceSupportDirectoryForOSVersion();
452     if (os_version_dir) {
453       ::snprintf(resolved_path, sizeof(resolved_path), "%s/%s", os_version_dir,
454                  platform_file_path);
455 
456       local_file.SetFile(resolved_path, true, FileSpec::Style::native);
457       if (FileSystem::Instance().Exists(local_file)) {
458         if (log) {
459           log->Printf("Found a copy of %s in the DeviceSupport dir %s",
460                       platform_file_path, os_version_dir);
461         }
462         return error;
463       }
464 
465       ::snprintf(resolved_path, sizeof(resolved_path), "%s/Symbols.Internal/%s",
466                  os_version_dir, platform_file_path);
467 
468       local_file.SetFile(resolved_path, true, FileSpec::Style::native);
469       if (FileSystem::Instance().Exists(local_file)) {
470         if (log) {
471           log->Printf(
472               "Found a copy of %s in the DeviceSupport dir %s/Symbols.Internal",
473               platform_file_path, os_version_dir);
474         }
475         return error;
476       }
477       ::snprintf(resolved_path, sizeof(resolved_path), "%s/Symbols/%s",
478                  os_version_dir, platform_file_path);
479 
480       local_file.SetFile(resolved_path, true, FileSpec::Style::native);
481       if (FileSystem::Instance().Exists(local_file)) {
482         if (log) {
483           log->Printf("Found a copy of %s in the DeviceSupport dir %s/Symbols",
484                       platform_file_path, os_version_dir);
485         }
486         return error;
487       }
488     }
489     local_file = platform_file;
490     if (FileSystem::Instance().Exists(local_file))
491       return error;
492 
493     error.SetErrorStringWithFormat(
494         "unable to locate a platform file for '%s' in platform '%s'",
495         platform_file_path, GetPluginName().GetCString());
496   } else {
497     error.SetErrorString("invalid platform file argument");
498   }
499   return error;
500 }
501 
502 Status PlatformRemoteDarwinDevice::GetSharedModule(
503     const ModuleSpec &module_spec, Process *process, ModuleSP &module_sp,
504     const FileSpecList *module_search_paths_ptr, ModuleSP *old_module_sp_ptr,
505     bool *did_create_ptr) {
506   // For iOS, the SDK files are all cached locally on the host system. So first
507   // we ask for the file in the cached SDK, then we attempt to get a shared
508   // module for the right architecture with the right UUID.
509   const FileSpec &platform_file = module_spec.GetFileSpec();
510   Log *log = lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_HOST);
511 
512   Status error;
513   char platform_file_path[PATH_MAX];
514 
515   if (platform_file.GetPath(platform_file_path, sizeof(platform_file_path))) {
516     ModuleSpec platform_module_spec(module_spec);
517 
518     UpdateSDKDirectoryInfosIfNeeded();
519 
520     const uint32_t num_sdk_infos = m_sdk_directory_infos.size();
521 
522     // If we are connected we migth be able to correctly deduce the SDK
523     // directory using the OS build.
524     const uint32_t connected_sdk_idx = GetConnectedSDKIndex();
525     if (connected_sdk_idx < num_sdk_infos) {
526       LLDB_LOGV(log, "Searching for {0} in sdk path {1}", platform_file,
527                 m_sdk_directory_infos[connected_sdk_idx].directory);
528       if (GetFileInSDK(platform_file_path, connected_sdk_idx,
529                        platform_module_spec.GetFileSpec())) {
530         module_sp.reset();
531         error = ResolveExecutable(platform_module_spec, module_sp, NULL);
532         if (module_sp) {
533           m_last_module_sdk_idx = connected_sdk_idx;
534           error.Clear();
535           return error;
536         }
537       }
538     }
539 
540     // Try the last SDK index if it is set as most files from an SDK will tend
541     // to be valid in that same SDK.
542     if (m_last_module_sdk_idx < num_sdk_infos) {
543       LLDB_LOGV(log, "Searching for {0} in sdk path {1}", platform_file,
544                 m_sdk_directory_infos[m_last_module_sdk_idx].directory);
545       if (GetFileInSDK(platform_file_path, m_last_module_sdk_idx,
546                        platform_module_spec.GetFileSpec())) {
547         module_sp.reset();
548         error = ResolveExecutable(platform_module_spec, module_sp, NULL);
549         if (module_sp) {
550           error.Clear();
551           return error;
552         }
553       }
554     }
555 
556     // First try for an exact match of major, minor and update: If a particalar
557     // SDK version was specified via --version or --build, look for a match on
558     // disk.
559     const SDKDirectoryInfo *current_sdk_info =
560         GetSDKDirectoryForCurrentOSVersion();
561     const uint32_t current_sdk_idx =
562         GetSDKIndexBySDKDirectoryInfo(current_sdk_info);
563     if (current_sdk_idx < num_sdk_infos &&
564         current_sdk_idx != m_last_module_sdk_idx) {
565       LLDB_LOGV(log, "Searching for {0} in sdk path {1}", platform_file,
566                 m_sdk_directory_infos[current_sdk_idx].directory);
567       if (GetFileInSDK(platform_file_path, current_sdk_idx,
568                        platform_module_spec.GetFileSpec())) {
569         module_sp.reset();
570         error = ResolveExecutable(platform_module_spec, module_sp, NULL);
571         if (module_sp) {
572           m_last_module_sdk_idx = current_sdk_idx;
573           error.Clear();
574           return error;
575         }
576       }
577     }
578 
579     // Second try all SDKs that were found.
580     for (uint32_t sdk_idx = 0; sdk_idx < num_sdk_infos; ++sdk_idx) {
581       if (m_last_module_sdk_idx == sdk_idx) {
582         // Skip the last module SDK index if we already searched it above
583         continue;
584       }
585       LLDB_LOGV(log, "Searching for {0} in sdk path {1}", platform_file,
586                 m_sdk_directory_infos[sdk_idx].directory);
587       if (GetFileInSDK(platform_file_path, sdk_idx,
588                        platform_module_spec.GetFileSpec())) {
589         // printf ("sdk[%u]: '%s'\n", sdk_idx, local_file.GetPath().c_str());
590 
591         error = ResolveExecutable(platform_module_spec, module_sp, NULL);
592         if (module_sp) {
593           // Remember the index of the last SDK that we found a file in in case
594           // the wrong SDK was selected.
595           m_last_module_sdk_idx = sdk_idx;
596           error.Clear();
597           return error;
598         }
599       }
600     }
601   }
602   // Not the module we are looking for... Nothing to see here...
603   module_sp.reset();
604 
605   // This may not be an SDK-related module.  Try whether we can bring in the
606   // thing to our local cache.
607   error = GetSharedModuleWithLocalCache(module_spec, module_sp,
608                                         module_search_paths_ptr,
609                                         old_module_sp_ptr, did_create_ptr);
610   if (error.Success())
611     return error;
612 
613   // See if the file is present in any of the module_search_paths_ptr
614   // directories.
615   if (!module_sp)
616     error = PlatformDarwin::FindBundleBinaryInExecSearchPaths (module_spec, process, module_sp,
617             module_search_paths_ptr, old_module_sp_ptr, did_create_ptr);
618 
619   if (error.Success())
620     return error;
621 
622   const bool always_create = false;
623   error = ModuleList::GetSharedModule(
624       module_spec, module_sp, module_search_paths_ptr, old_module_sp_ptr,
625       did_create_ptr, always_create);
626 
627   if (module_sp)
628     module_sp->SetPlatformFileSpec(platform_file);
629 
630   return error;
631 }
632 
633 uint32_t PlatformRemoteDarwinDevice::GetConnectedSDKIndex() {
634   if (IsConnected()) {
635     if (m_connected_module_sdk_idx == UINT32_MAX) {
636       std::string build;
637       if (GetRemoteOSBuildString(build)) {
638         const uint32_t num_sdk_infos = m_sdk_directory_infos.size();
639         for (uint32_t i = 0; i < num_sdk_infos; ++i) {
640           const SDKDirectoryInfo &sdk_dir_info = m_sdk_directory_infos[i];
641           if (strstr(sdk_dir_info.directory.GetFilename().AsCString(""),
642                      build.c_str())) {
643             m_connected_module_sdk_idx = i;
644           }
645         }
646       }
647     }
648   } else {
649     m_connected_module_sdk_idx = UINT32_MAX;
650   }
651   return m_connected_module_sdk_idx;
652 }
653 
654 uint32_t PlatformRemoteDarwinDevice::GetSDKIndexBySDKDirectoryInfo(
655     const SDKDirectoryInfo *sdk_info) {
656   if (sdk_info == NULL) {
657     return UINT32_MAX;
658   }
659 
660   return sdk_info - &m_sdk_directory_infos[0];
661 }
662