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