]> CyberLeo.Net >> Repos - FreeBSD/FreeBSD.git/blob - source/Plugins/Platform/MacOSX/PlatformRemoteiOS.cpp
Vendor import of lldb trunk r290819:
[FreeBSD/FreeBSD.git] / source / Plugins / Platform / MacOSX / PlatformRemoteiOS.cpp
1 //===-- PlatformRemoteiOS.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 "PlatformRemoteiOS.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/ArchSpec.h"
18 #include "lldb/Core/Error.h"
19 #include "lldb/Core/Log.h"
20 #include "lldb/Core/Module.h"
21 #include "lldb/Core/ModuleList.h"
22 #include "lldb/Core/ModuleSpec.h"
23 #include "lldb/Core/PluginManager.h"
24 #include "lldb/Core/StreamString.h"
25 #include "lldb/Host/FileSpec.h"
26 #include "lldb/Host/Host.h"
27 #include "lldb/Target/Process.h"
28 #include "lldb/Target/Target.h"
29
30 using namespace lldb;
31 using namespace lldb_private;
32
33 PlatformRemoteiOS::SDKDirectoryInfo::SDKDirectoryInfo(
34     const lldb_private::FileSpec &sdk_dir)
35     : directory(sdk_dir), build(), version_major(0), version_minor(0),
36       version_update(0), user_cached(false) {
37   llvm::StringRef dirname_str = sdk_dir.GetFilename().GetStringRef();
38   llvm::StringRef build_str;
39   std::tie(version_major, version_minor, version_update, build_str) =
40       ParseVersionBuildDir(dirname_str);
41   build.SetString(build_str);
42 }
43
44 //------------------------------------------------------------------
45 // Static Variables
46 //------------------------------------------------------------------
47 static uint32_t g_initialize_count = 0;
48
49 //------------------------------------------------------------------
50 // Static Functions
51 //------------------------------------------------------------------
52 void PlatformRemoteiOS::Initialize() {
53   PlatformDarwin::Initialize();
54
55   if (g_initialize_count++ == 0) {
56     PluginManager::RegisterPlugin(PlatformRemoteiOS::GetPluginNameStatic(),
57                                   PlatformRemoteiOS::GetDescriptionStatic(),
58                                   PlatformRemoteiOS::CreateInstance);
59   }
60 }
61
62 void PlatformRemoteiOS::Terminate() {
63   if (g_initialize_count > 0) {
64     if (--g_initialize_count == 0) {
65       PluginManager::UnregisterPlugin(PlatformRemoteiOS::CreateInstance);
66     }
67   }
68
69   PlatformDarwin::Terminate();
70 }
71
72 PlatformSP PlatformRemoteiOS::CreateInstance(bool force, const ArchSpec *arch) {
73   Log *log(GetLogIfAllCategoriesSet(LIBLLDB_LOG_PLATFORM));
74   if (log) {
75     const char *arch_name;
76     if (arch && arch->GetArchitectureName())
77       arch_name = arch->GetArchitectureName();
78     else
79       arch_name = "<null>";
80
81     const char *triple_cstr =
82         arch ? arch->GetTriple().getTriple().c_str() : "<null>";
83
84     log->Printf("PlatformRemoteiOS::%s(force=%s, arch={%s,%s})", __FUNCTION__,
85                 force ? "true" : "false", arch_name, triple_cstr);
86   }
87
88   bool create = force;
89   if (create == false && arch && arch->IsValid()) {
90     switch (arch->GetMachine()) {
91     case llvm::Triple::arm:
92     case llvm::Triple::aarch64:
93     case llvm::Triple::thumb: {
94       const llvm::Triple &triple = arch->GetTriple();
95       llvm::Triple::VendorType vendor = triple.getVendor();
96       switch (vendor) {
97       case llvm::Triple::Apple:
98         create = true;
99         break;
100
101 #if defined(__APPLE__)
102       // Only accept "unknown" for the vendor if the host is Apple and
103       // it "unknown" wasn't specified (it was just returned because it
104       // was NOT specified)
105       case llvm::Triple::UnknownArch:
106         create = !arch->TripleVendorWasSpecified();
107         break;
108
109 #endif
110       default:
111         break;
112       }
113       if (create) {
114         switch (triple.getOS()) {
115         case llvm::Triple::Darwin: // Deprecated, but still support Darwin for
116                                    // historical reasons
117         case llvm::Triple::IOS:    // This is the right triple value for iOS
118                                    // debugging
119           break;
120
121         default:
122           create = false;
123           break;
124         }
125       }
126     } break;
127     default:
128       break;
129     }
130   }
131
132   if (create) {
133     if (log)
134       log->Printf("PlatformRemoteiOS::%s() creating platform", __FUNCTION__);
135
136     return lldb::PlatformSP(new PlatformRemoteiOS());
137   }
138
139   if (log)
140     log->Printf("PlatformRemoteiOS::%s() aborting creation of platform",
141                 __FUNCTION__);
142
143   return lldb::PlatformSP();
144 }
145
146 lldb_private::ConstString PlatformRemoteiOS::GetPluginNameStatic() {
147   static ConstString g_name("remote-ios");
148   return g_name;
149 }
150
151 const char *PlatformRemoteiOS::GetDescriptionStatic() {
152   return "Remote iOS platform plug-in.";
153 }
154
155 //------------------------------------------------------------------
156 /// Default Constructor
157 //------------------------------------------------------------------
158 PlatformRemoteiOS::PlatformRemoteiOS()
159     : PlatformDarwin(false), // This is a remote platform
160       m_sdk_directory_infos(), m_device_support_directory(),
161       m_device_support_directory_for_os_version(), m_build_update(),
162       m_last_module_sdk_idx(UINT32_MAX),
163       m_connected_module_sdk_idx(UINT32_MAX) {}
164
165 //------------------------------------------------------------------
166 /// Destructor.
167 ///
168 /// The destructor is virtual since this class is designed to be
169 /// inherited from by the plug-in instance.
170 //------------------------------------------------------------------
171 PlatformRemoteiOS::~PlatformRemoteiOS() {}
172
173 void PlatformRemoteiOS::GetStatus(Stream &strm) {
174   Platform::GetStatus(strm);
175   const char *sdk_directory = GetDeviceSupportDirectoryForOSVersion();
176   if (sdk_directory)
177     strm.Printf("  SDK Path: \"%s\"\n", sdk_directory);
178   else
179     strm.PutCString("  SDK Path: error: unable to locate SDK\n");
180
181   const uint32_t num_sdk_infos = m_sdk_directory_infos.size();
182   for (uint32_t i = 0; i < num_sdk_infos; ++i) {
183     const SDKDirectoryInfo &sdk_dir_info = m_sdk_directory_infos[i];
184     strm.Printf(" SDK Roots: [%2u] \"%s\"\n", i,
185                 sdk_dir_info.directory.GetPath().c_str());
186   }
187 }
188
189 Error PlatformRemoteiOS::ResolveExecutable(
190     const ModuleSpec &ms, lldb::ModuleSP &exe_module_sp,
191     const FileSpecList *module_search_paths_ptr) {
192   Error error;
193   // Nothing special to do here, just use the actual file and architecture
194
195   ModuleSpec resolved_module_spec(ms);
196
197   // Resolve any executable within a bundle on MacOSX
198   // TODO: verify that this handles shallow bundles, if not then implement one
199   // ourselves
200   Host::ResolveExecutableInBundle(resolved_module_spec.GetFileSpec());
201
202   if (resolved_module_spec.GetFileSpec().Exists()) {
203     if (resolved_module_spec.GetArchitecture().IsValid() ||
204         resolved_module_spec.GetUUID().IsValid()) {
205       error = ModuleList::GetSharedModule(resolved_module_spec, exe_module_sp,
206                                           NULL, NULL, NULL);
207
208       if (exe_module_sp && exe_module_sp->GetObjectFile())
209         return error;
210       exe_module_sp.reset();
211     }
212     // No valid architecture was specified or the exact ARM slice wasn't
213     // found so ask the platform for the architectures that we should be
214     // using (in the correct order) and see if we can find a match that way
215     StreamString arch_names;
216     for (uint32_t idx = 0; GetSupportedArchitectureAtIndex(
217              idx, resolved_module_spec.GetArchitecture());
218          ++idx) {
219       error = ModuleList::GetSharedModule(resolved_module_spec, exe_module_sp,
220                                           NULL, NULL, NULL);
221       // Did we find an executable using one of the
222       if (error.Success()) {
223         if (exe_module_sp && exe_module_sp->GetObjectFile())
224           break;
225         else
226           error.SetErrorToGenericError();
227       }
228
229       if (idx > 0)
230         arch_names.PutCString(", ");
231       arch_names.PutCString(
232           resolved_module_spec.GetArchitecture().GetArchitectureName());
233     }
234
235     if (error.Fail() || !exe_module_sp) {
236       if (resolved_module_spec.GetFileSpec().Readable()) {
237         error.SetErrorStringWithFormat(
238             "'%s' doesn't contain any '%s' platform architectures: %s",
239             resolved_module_spec.GetFileSpec().GetPath().c_str(),
240             GetPluginName().GetCString(), arch_names.GetData());
241       } else {
242         error.SetErrorStringWithFormat(
243             "'%s' is not readable",
244             resolved_module_spec.GetFileSpec().GetPath().c_str());
245       }
246     }
247   } else {
248     error.SetErrorStringWithFormat(
249         "'%s' does not exist",
250         resolved_module_spec.GetFileSpec().GetPath().c_str());
251   }
252
253   return error;
254 }
255
256 FileSpec::EnumerateDirectoryResult
257 PlatformRemoteiOS::GetContainedFilesIntoVectorOfStringsCallback(
258     void *baton, FileSpec::FileType file_type, const FileSpec &file_spec) {
259   ((PlatformRemoteiOS::SDKDirectoryInfoCollection *)baton)
260       ->push_back(PlatformRemoteiOS::SDKDirectoryInfo(file_spec));
261   return FileSpec::eEnumerateDirectoryResultNext;
262 }
263
264 bool PlatformRemoteiOS::UpdateSDKDirectoryInfosIfNeeded() {
265   Log *log = lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_HOST);
266   std::lock_guard<std::mutex> guard(m_sdk_dir_mutex);
267   if (m_sdk_directory_infos.empty()) {
268     // A --sysroot option was supplied - add it to our list of SDKs to check
269     if (m_sdk_sysroot) {
270       FileSpec sdk_sysroot_fspec(m_sdk_sysroot.GetCString(), true);
271       const SDKDirectoryInfo sdk_sysroot_directory_info(sdk_sysroot_fspec);
272       m_sdk_directory_infos.push_back(sdk_sysroot_directory_info);
273       if (log) {
274         log->Printf("PlatformRemoteiOS::UpdateSDKDirectoryInfosIfNeeded added "
275                     "--sysroot SDK directory %s",
276                     m_sdk_sysroot.GetCString());
277       }
278       return true;
279     }
280     const char *device_support_dir = GetDeviceSupportDirectory();
281     if (log) {
282       log->Printf("PlatformRemoteiOS::UpdateSDKDirectoryInfosIfNeeded Got "
283                   "DeviceSupport directory %s",
284                   device_support_dir);
285     }
286     if (device_support_dir) {
287       const bool find_directories = true;
288       const bool find_files = false;
289       const bool find_other = false;
290
291       SDKDirectoryInfoCollection builtin_sdk_directory_infos;
292       FileSpec::EnumerateDirectory(m_device_support_directory, find_directories,
293                                    find_files, find_other,
294                                    GetContainedFilesIntoVectorOfStringsCallback,
295                                    &builtin_sdk_directory_infos);
296
297       // Only add SDK directories that have symbols in them, some SDKs only
298       // contain
299       // developer disk images and no symbols, so they aren't useful to us.
300       FileSpec sdk_symbols_symlink_fspec;
301       for (const auto &sdk_directory_info : builtin_sdk_directory_infos) {
302         sdk_symbols_symlink_fspec = sdk_directory_info.directory;
303         sdk_symbols_symlink_fspec.AppendPathComponent("Symbols");
304         if (sdk_symbols_symlink_fspec.Exists()) {
305           m_sdk_directory_infos.push_back(sdk_directory_info);
306           if (log) {
307             log->Printf("PlatformRemoteiOS::UpdateSDKDirectoryInfosIfNeeded "
308                         "added builtin SDK directory %s",
309                         sdk_symbols_symlink_fspec.GetPath().c_str());
310           }
311         }
312       }
313
314       const uint32_t num_installed = m_sdk_directory_infos.size();
315       FileSpec local_sdk_cache("~/Library/Developer/Xcode/iOS DeviceSupport",
316                                true);
317       if (local_sdk_cache.Exists()) {
318         if (log) {
319           log->Printf("PlatformRemoteiOS::UpdateSDKDirectoryInfosIfNeeded "
320                       "searching %s for additional SDKs",
321                       local_sdk_cache.GetPath().c_str());
322         }
323         char path[PATH_MAX];
324         if (local_sdk_cache.GetPath(path, sizeof(path))) {
325           FileSpec::EnumerateDirectory(
326               path, find_directories, find_files, find_other,
327               GetContainedFilesIntoVectorOfStringsCallback,
328               &m_sdk_directory_infos);
329           const uint32_t num_sdk_infos = m_sdk_directory_infos.size();
330           // First try for an exact match of major, minor and update
331           for (uint32_t i = num_installed; i < num_sdk_infos; ++i) {
332             m_sdk_directory_infos[i].user_cached = true;
333             if (log) {
334               log->Printf("PlatformRemoteiOS::UpdateSDKDirectoryInfosIfNeeded "
335                           "user SDK directory %s",
336                           m_sdk_directory_infos[i].directory.GetPath().c_str());
337             }
338           }
339         }
340       }
341     }
342   }
343   return !m_sdk_directory_infos.empty();
344 }
345
346 const PlatformRemoteiOS::SDKDirectoryInfo *
347 PlatformRemoteiOS::GetSDKDirectoryForCurrentOSVersion() {
348   uint32_t i;
349   if (UpdateSDKDirectoryInfosIfNeeded()) {
350     const uint32_t num_sdk_infos = m_sdk_directory_infos.size();
351
352     // Check to see if the user specified a build string. If they did, then
353     // be sure to match it.
354     std::vector<bool> check_sdk_info(num_sdk_infos, true);
355     ConstString build(m_sdk_build);
356     if (build) {
357       for (i = 0; i < num_sdk_infos; ++i)
358         check_sdk_info[i] = m_sdk_directory_infos[i].build == build;
359     }
360
361     // If we are connected we can find the version of the OS the platform
362     // us running on and select the right SDK
363     uint32_t major, minor, update;
364     if (GetOSVersion(major, minor, update)) {
365       if (UpdateSDKDirectoryInfosIfNeeded()) {
366         // First try for an exact match of major, minor and update
367         for (i = 0; i < num_sdk_infos; ++i) {
368           if (check_sdk_info[i]) {
369             if (m_sdk_directory_infos[i].version_major == major &&
370                 m_sdk_directory_infos[i].version_minor == minor &&
371                 m_sdk_directory_infos[i].version_update == update) {
372               return &m_sdk_directory_infos[i];
373             }
374           }
375         }
376         // First try for an exact match of major and minor
377         for (i = 0; i < num_sdk_infos; ++i) {
378           if (check_sdk_info[i]) {
379             if (m_sdk_directory_infos[i].version_major == major &&
380                 m_sdk_directory_infos[i].version_minor == minor) {
381               return &m_sdk_directory_infos[i];
382             }
383           }
384         }
385         // Lastly try to match of major version only..
386         for (i = 0; i < num_sdk_infos; ++i) {
387           if (check_sdk_info[i]) {
388             if (m_sdk_directory_infos[i].version_major == major) {
389               return &m_sdk_directory_infos[i];
390             }
391           }
392         }
393       }
394     } else if (build) {
395       // No version, just a build number, search for the first one that matches
396       for (i = 0; i < num_sdk_infos; ++i)
397         if (check_sdk_info[i])
398           return &m_sdk_directory_infos[i];
399     }
400   }
401   return NULL;
402 }
403
404 const PlatformRemoteiOS::SDKDirectoryInfo *
405 PlatformRemoteiOS::GetSDKDirectoryForLatestOSVersion() {
406   const PlatformRemoteiOS::SDKDirectoryInfo *result = NULL;
407   if (UpdateSDKDirectoryInfosIfNeeded()) {
408     const uint32_t num_sdk_infos = m_sdk_directory_infos.size();
409     // First try for an exact match of major, minor and update
410     for (uint32_t i = 0; i < num_sdk_infos; ++i) {
411       const SDKDirectoryInfo &sdk_dir_info = m_sdk_directory_infos[i];
412       if (sdk_dir_info.version_major != UINT32_MAX) {
413         if (result == NULL ||
414             sdk_dir_info.version_major > result->version_major) {
415           result = &sdk_dir_info;
416         } else if (sdk_dir_info.version_major == result->version_major) {
417           if (sdk_dir_info.version_minor > result->version_minor) {
418             result = &sdk_dir_info;
419           } else if (sdk_dir_info.version_minor == result->version_minor) {
420             if (sdk_dir_info.version_update > result->version_update) {
421               result = &sdk_dir_info;
422             }
423           }
424         }
425       }
426     }
427   }
428   return result;
429 }
430
431 const char *PlatformRemoteiOS::GetDeviceSupportDirectory() {
432   if (m_device_support_directory.empty()) {
433     const char *device_support_dir = GetDeveloperDirectory();
434     if (device_support_dir) {
435       m_device_support_directory.assign(device_support_dir);
436       m_device_support_directory.append(
437           "/Platforms/iPhoneOS.platform/DeviceSupport");
438     } else {
439       // Assign a single NULL character so we know we tried to find the device
440       // support directory and we don't keep trying to find it over and over.
441       m_device_support_directory.assign(1, '\0');
442     }
443   }
444   // We should have put a single NULL character into m_device_support_directory
445   // or it should have a valid path if the code gets here
446   assert(m_device_support_directory.empty() == false);
447   if (m_device_support_directory[0])
448     return m_device_support_directory.c_str();
449   return NULL;
450 }
451
452 const char *PlatformRemoteiOS::GetDeviceSupportDirectoryForOSVersion() {
453   if (m_sdk_sysroot)
454     return m_sdk_sysroot.GetCString();
455
456   if (m_device_support_directory_for_os_version.empty()) {
457     const PlatformRemoteiOS::SDKDirectoryInfo *sdk_dir_info =
458         GetSDKDirectoryForCurrentOSVersion();
459     if (sdk_dir_info == NULL)
460       sdk_dir_info = GetSDKDirectoryForLatestOSVersion();
461     if (sdk_dir_info) {
462       char path[PATH_MAX];
463       if (sdk_dir_info->directory.GetPath(path, sizeof(path))) {
464         m_device_support_directory_for_os_version = path;
465         return m_device_support_directory_for_os_version.c_str();
466       }
467     } else {
468       // Assign a single NULL character so we know we tried to find the device
469       // support directory and we don't keep trying to find it over and over.
470       m_device_support_directory_for_os_version.assign(1, '\0');
471     }
472   }
473   // We should have put a single NULL character into
474   // m_device_support_directory_for_os_version
475   // or it should have a valid path if the code gets here
476   assert(m_device_support_directory_for_os_version.empty() == false);
477   if (m_device_support_directory_for_os_version[0])
478     return m_device_support_directory_for_os_version.c_str();
479   return NULL;
480 }
481
482 uint32_t PlatformRemoteiOS::FindFileInAllSDKs(const char *platform_file_path,
483                                               FileSpecList &file_list) {
484   Log *log = lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_HOST |
485                                                     LIBLLDB_LOG_VERBOSE);
486   if (platform_file_path && platform_file_path[0] &&
487       UpdateSDKDirectoryInfosIfNeeded()) {
488     const uint32_t num_sdk_infos = m_sdk_directory_infos.size();
489     lldb_private::FileSpec local_file;
490     // First try for an exact match of major, minor and update
491     for (uint32_t sdk_idx = 0; sdk_idx < num_sdk_infos; ++sdk_idx) {
492       if (log) {
493         log->Printf("Searching for %s in sdk path %s", platform_file_path,
494                     m_sdk_directory_infos[sdk_idx].directory.GetPath().c_str());
495       }
496       if (GetFileInSDK(platform_file_path, sdk_idx, local_file)) {
497         file_list.Append(local_file);
498       }
499     }
500   }
501   return file_list.GetSize();
502 }
503
504 bool PlatformRemoteiOS::GetFileInSDK(const char *platform_file_path,
505                                      uint32_t sdk_idx,
506                                      lldb_private::FileSpec &local_file) {
507   Log *log = lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_HOST);
508   if (sdk_idx < m_sdk_directory_infos.size()) {
509     std::string sdkroot_path =
510         m_sdk_directory_infos[sdk_idx].directory.GetPath();
511     local_file.Clear();
512
513     if (!sdkroot_path.empty() && platform_file_path && platform_file_path[0]) {
514       // We may need to interpose "/Symbols/" or "/Symbols.Internal/" between
515       // the
516       // SDK root directory and the file path.
517
518       const char *paths_to_try[] = {"Symbols", "", "Symbols.Internal", nullptr};
519       for (size_t i = 0; paths_to_try[i] != nullptr; i++) {
520         local_file.SetFile(sdkroot_path, false);
521         if (paths_to_try[i][0] != '\0')
522           local_file.AppendPathComponent(paths_to_try[i]);
523         local_file.AppendPathComponent(platform_file_path);
524         local_file.ResolvePath();
525         if (local_file.Exists()) {
526           if (log)
527             log->Printf("Found a copy of %s in the SDK dir %s/%s",
528                         platform_file_path, sdkroot_path.c_str(),
529                         paths_to_try[i]);
530           return true;
531         }
532         local_file.Clear();
533       }
534     }
535   }
536   return false;
537 }
538
539 Error PlatformRemoteiOS::GetSymbolFile(const FileSpec &platform_file,
540                                        const UUID *uuid_ptr,
541                                        FileSpec &local_file) {
542   Log *log = lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_HOST);
543   Error error;
544   char platform_file_path[PATH_MAX];
545   if (platform_file.GetPath(platform_file_path, sizeof(platform_file_path))) {
546     char resolved_path[PATH_MAX];
547
548     const char *os_version_dir = GetDeviceSupportDirectoryForOSVersion();
549     if (os_version_dir) {
550       ::snprintf(resolved_path, sizeof(resolved_path), "%s/%s", os_version_dir,
551                  platform_file_path);
552
553       local_file.SetFile(resolved_path, true);
554       if (local_file.Exists()) {
555         if (log) {
556           log->Printf("Found a copy of %s in the DeviceSupport dir %s",
557                       platform_file_path, os_version_dir);
558         }
559         return error;
560       }
561
562       ::snprintf(resolved_path, sizeof(resolved_path), "%s/Symbols.Internal/%s",
563                  os_version_dir, platform_file_path);
564
565       local_file.SetFile(resolved_path, true);
566       if (local_file.Exists()) {
567         if (log) {
568           log->Printf(
569               "Found a copy of %s in the DeviceSupport dir %s/Symbols.Internal",
570               platform_file_path, os_version_dir);
571         }
572         return error;
573       }
574       ::snprintf(resolved_path, sizeof(resolved_path), "%s/Symbols/%s",
575                  os_version_dir, platform_file_path);
576
577       local_file.SetFile(resolved_path, true);
578       if (local_file.Exists()) {
579         if (log) {
580           log->Printf("Found a copy of %s in the DeviceSupport dir %s/Symbols",
581                       platform_file_path, os_version_dir);
582         }
583         return error;
584       }
585     }
586     local_file = platform_file;
587     if (local_file.Exists())
588       return error;
589
590     error.SetErrorStringWithFormat(
591         "unable to locate a platform file for '%s' in platform '%s'",
592         platform_file_path, GetPluginName().GetCString());
593   } else {
594     error.SetErrorString("invalid platform file argument");
595   }
596   return error;
597 }
598
599 Error PlatformRemoteiOS::GetSharedModule(
600     const ModuleSpec &module_spec, Process *process, ModuleSP &module_sp,
601     const FileSpecList *module_search_paths_ptr, ModuleSP *old_module_sp_ptr,
602     bool *did_create_ptr) {
603   // For iOS, the SDK files are all cached locally on the host
604   // system. So first we ask for the file in the cached SDK,
605   // then we attempt to get a shared module for the right architecture
606   // with the right UUID.
607   const FileSpec &platform_file = module_spec.GetFileSpec();
608   Log *log = lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_HOST |
609                                                     LIBLLDB_LOG_VERBOSE);
610
611   Error error;
612   char platform_file_path[PATH_MAX];
613
614   if (platform_file.GetPath(platform_file_path, sizeof(platform_file_path))) {
615     ModuleSpec platform_module_spec(module_spec);
616
617     UpdateSDKDirectoryInfosIfNeeded();
618
619     const uint32_t num_sdk_infos = m_sdk_directory_infos.size();
620
621     // If we are connected we migth be able to correctly deduce the SDK
622     // directory
623     // using the OS build.
624     const uint32_t connected_sdk_idx = GetConnectedSDKIndex();
625     if (connected_sdk_idx < num_sdk_infos) {
626       if (log) {
627         log->Printf("Searching for %s in sdk path %s", platform_file_path,
628                     m_sdk_directory_infos[connected_sdk_idx]
629                         .directory.GetPath()
630                         .c_str());
631       }
632       if (GetFileInSDK(platform_file_path, connected_sdk_idx,
633                        platform_module_spec.GetFileSpec())) {
634         module_sp.reset();
635         error = ResolveExecutable(platform_module_spec, module_sp, NULL);
636         if (module_sp) {
637           m_last_module_sdk_idx = connected_sdk_idx;
638           error.Clear();
639           return error;
640         }
641       }
642     }
643
644     // Try the last SDK index if it is set as most files from an SDK
645     // will tend to be valid in that same SDK.
646     if (m_last_module_sdk_idx < num_sdk_infos) {
647       if (log) {
648         log->Printf("Searching for %s in sdk path %s", platform_file_path,
649                     m_sdk_directory_infos[m_last_module_sdk_idx]
650                         .directory.GetPath()
651                         .c_str());
652       }
653       if (GetFileInSDK(platform_file_path, m_last_module_sdk_idx,
654                        platform_module_spec.GetFileSpec())) {
655         module_sp.reset();
656         error = ResolveExecutable(platform_module_spec, module_sp, NULL);
657         if (module_sp) {
658           error.Clear();
659           return error;
660         }
661       }
662     }
663
664     // First try for an exact match of major, minor and update:
665     // If a particalar SDK version was specified via --version or --build, look
666     // for a match on disk.
667     const SDKDirectoryInfo *current_sdk_info =
668         GetSDKDirectoryForCurrentOSVersion();
669     const uint32_t current_sdk_idx =
670         GetSDKIndexBySDKDirectoryInfo(current_sdk_info);
671     if (current_sdk_idx < num_sdk_infos &&
672         current_sdk_idx != m_last_module_sdk_idx) {
673       if (log) {
674         log->Printf(
675             "Searching for %s in sdk path %s", platform_file_path,
676             m_sdk_directory_infos[current_sdk_idx].directory.GetPath().c_str());
677       }
678       if (GetFileInSDK(platform_file_path, current_sdk_idx,
679                        platform_module_spec.GetFileSpec())) {
680         module_sp.reset();
681         error = ResolveExecutable(platform_module_spec, module_sp, NULL);
682         if (module_sp) {
683           m_last_module_sdk_idx = current_sdk_idx;
684           error.Clear();
685           return error;
686         }
687       }
688     }
689
690     // Second try all SDKs that were found.
691     for (uint32_t sdk_idx = 0; sdk_idx < num_sdk_infos; ++sdk_idx) {
692       if (m_last_module_sdk_idx == sdk_idx) {
693         // Skip the last module SDK index if we already searched
694         // it above
695         continue;
696       }
697       if (log) {
698         log->Printf("Searching for %s in sdk path %s", platform_file_path,
699                     m_sdk_directory_infos[sdk_idx].directory.GetPath().c_str());
700       }
701       if (GetFileInSDK(platform_file_path, sdk_idx,
702                        platform_module_spec.GetFileSpec())) {
703         // printf ("sdk[%u]: '%s'\n", sdk_idx, local_file.GetPath().c_str());
704
705         error = ResolveExecutable(platform_module_spec, module_sp, NULL);
706         if (module_sp) {
707           // Remember the index of the last SDK that we found a file
708           // in in case the wrong SDK was selected.
709           m_last_module_sdk_idx = sdk_idx;
710           error.Clear();
711           return error;
712         }
713       }
714     }
715   }
716   // Not the module we are looking for... Nothing to see here...
717   module_sp.reset();
718
719   // This may not be an SDK-related module.  Try whether we can bring in the
720   // thing to our local cache.
721   error = GetSharedModuleWithLocalCache(module_spec, module_sp,
722                                         module_search_paths_ptr,
723                                         old_module_sp_ptr, did_create_ptr);
724   if (error.Success())
725     return error;
726
727   // See if the file is present in any of the module_search_paths_ptr
728   // directories.
729   if (!module_sp && module_search_paths_ptr && platform_file) {
730     // create a vector of all the file / directory names in platform_file
731     // e.g. this might be
732     // /System/Library/PrivateFrameworks/UIFoundation.framework/UIFoundation
733     //
734     // We'll need to look in the module_search_paths_ptr directories for
735     // both "UIFoundation" and "UIFoundation.framework" -- most likely the
736     // latter will be the one we find there.
737
738     FileSpec platform_pull_apart(platform_file);
739     std::vector<std::string> path_parts;
740     ConstString unix_root_dir("/");
741     while (true) {
742       ConstString part = platform_pull_apart.GetLastPathComponent();
743       platform_pull_apart.RemoveLastPathComponent();
744       if (part.IsEmpty() || part == unix_root_dir)
745         break;
746       path_parts.push_back(part.AsCString());
747     }
748     const size_t path_parts_size = path_parts.size();
749
750     size_t num_module_search_paths = module_search_paths_ptr->GetSize();
751     for (size_t i = 0; i < num_module_search_paths; ++i) {
752       Log *log_verbose = lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_HOST |
753                                                     LIBLLDB_LOG_VERBOSE);
754       if (log_verbose)
755           log_verbose->Printf ("PlatformRemoteiOS::GetSharedModule searching for binary in search-path %s", module_search_paths_ptr->GetFileSpecAtIndex(i).GetPath().c_str());
756       // Create a new FileSpec with this module_search_paths_ptr
757       // plus just the filename ("UIFoundation"), then the parent
758       // dir plus filename ("UIFoundation.framework/UIFoundation")
759       // etc - up to four names (to handle "Foo.framework/Contents/MacOS/Foo")
760
761       for (size_t j = 0; j < 4 && j < path_parts_size - 1; ++j) {
762         FileSpec path_to_try(module_search_paths_ptr->GetFileSpecAtIndex(i));
763
764         // Add the components backwards.  For
765         // .../PrivateFrameworks/UIFoundation.framework/UIFoundation
766         // path_parts is
767         //   [0] UIFoundation
768         //   [1] UIFoundation.framework
769         //   [2] PrivateFrameworks
770         //
771         // and if 'j' is 2, we want to append path_parts[1] and then
772         // path_parts[0], aka
773         // 'UIFoundation.framework/UIFoundation', to the module_search_paths_ptr
774         // path.
775
776         for (int k = j; k >= 0; --k) {
777           path_to_try.AppendPathComponent(path_parts[k]);
778         }
779
780         if (path_to_try.Exists()) {
781           ModuleSpec new_module_spec(module_spec);
782           new_module_spec.GetFileSpec() = path_to_try;
783           Error new_error(Platform::GetSharedModule(
784               new_module_spec, process, module_sp, NULL, old_module_sp_ptr,
785               did_create_ptr));
786
787           if (module_sp) {
788             module_sp->SetPlatformFileSpec(path_to_try);
789             return new_error;
790           }
791         }
792       }
793     }
794   }
795
796   const bool always_create = false;
797   error = ModuleList::GetSharedModule(
798       module_spec, module_sp, module_search_paths_ptr, old_module_sp_ptr,
799       did_create_ptr, always_create);
800
801   if (module_sp)
802     module_sp->SetPlatformFileSpec(platform_file);
803
804   return error;
805 }
806
807 bool PlatformRemoteiOS::GetSupportedArchitectureAtIndex(uint32_t idx,
808                                                         ArchSpec &arch) {
809   return ARMGetSupportedArchitectureAtIndex(idx, arch);
810 }
811
812 uint32_t PlatformRemoteiOS::GetConnectedSDKIndex() {
813   if (IsConnected()) {
814     if (m_connected_module_sdk_idx == UINT32_MAX) {
815       std::string build;
816       if (GetRemoteOSBuildString(build)) {
817         const uint32_t num_sdk_infos = m_sdk_directory_infos.size();
818         for (uint32_t i = 0; i < num_sdk_infos; ++i) {
819           const SDKDirectoryInfo &sdk_dir_info = m_sdk_directory_infos[i];
820           if (strstr(sdk_dir_info.directory.GetFilename().AsCString(""),
821                      build.c_str())) {
822             m_connected_module_sdk_idx = i;
823           }
824         }
825       }
826     }
827   } else {
828     m_connected_module_sdk_idx = UINT32_MAX;
829   }
830   return m_connected_module_sdk_idx;
831 }
832
833 uint32_t PlatformRemoteiOS::GetSDKIndexBySDKDirectoryInfo(
834     const SDKDirectoryInfo *sdk_info) {
835   if (sdk_info == NULL) {
836     return UINT32_MAX;
837   }
838
839   return sdk_info - &m_sdk_directory_infos[0];
840 }