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/Module.h"
20 #include "lldb/Core/ModuleList.h"
21 #include "lldb/Core/PluginManager.h"
22 #include "lldb/Core/StreamString.h"
23 #include "lldb/Host/FileSpec.h"
24 #include "lldb/Host/Host.h"
25 #include "lldb/Target/Process.h"
26 #include "lldb/Target/Target.h"
27 
28 using namespace lldb;
29 using namespace lldb_private;
30 
31 PlatformRemoteiOS::SDKDirectoryInfo::SDKDirectoryInfo (const lldb_private::FileSpec &sdk_dir) :
32     directory(sdk_dir),
33     build(),
34     version_major(0),
35     version_minor(0),
36     version_update(0),
37     user_cached(false)
38 {
39     const char *dirname_cstr = sdk_dir.GetFilename().GetCString();
40     const char *pos = Args::StringToVersion (dirname_cstr,
41                                              version_major,
42                                              version_minor,
43                                              version_update);
44 
45     if (pos && pos[0] == ' ' && pos[1] == '(')
46     {
47         const char *build_start = pos + 2;
48         const char *end_paren = strchr (build_start, ')');
49         if (end_paren && build_start < end_paren)
50             build.SetCStringWithLength(build_start, end_paren - build_start);
51     }
52 }
53 
54 //------------------------------------------------------------------
55 // Static Variables
56 //------------------------------------------------------------------
57 static uint32_t g_initialize_count = 0;
58 
59 //------------------------------------------------------------------
60 // Static Functions
61 //------------------------------------------------------------------
62 void
63 PlatformRemoteiOS::Initialize ()
64 {
65     if (g_initialize_count++ == 0)
66     {
67         PluginManager::RegisterPlugin (PlatformRemoteiOS::GetShortPluginNameStatic(),
68                                        PlatformRemoteiOS::GetDescriptionStatic(),
69                                        PlatformRemoteiOS::CreateInstance);
70     }
71 }
72 
73 void
74 PlatformRemoteiOS::Terminate ()
75 {
76     if (g_initialize_count > 0)
77     {
78         if (--g_initialize_count == 0)
79         {
80             PluginManager::UnregisterPlugin (PlatformRemoteiOS::CreateInstance);
81         }
82     }
83 }
84 
85 Platform*
86 PlatformRemoteiOS::CreateInstance (bool force, const ArchSpec *arch)
87 {
88     bool create = force;
89     if (create == false && arch && arch->IsValid())
90     {
91         switch (arch->GetMachine())
92         {
93         case llvm::Triple::arm:
94         case llvm::Triple::thumb:
95             {
96                 const llvm::Triple &triple = arch->GetTriple();
97                 llvm::Triple::VendorType vendor = triple.getVendor();
98                 switch (vendor)
99                 {
100                     case llvm::Triple::Apple:
101                         create = true;
102                         break;
103 
104                     case llvm::Triple::UnknownArch:
105                         create = !arch->TripleVendorWasSpecified();
106                         break;
107 
108                     default:
109                         break;
110                 }
111 
112                 if (create)
113                 {
114                     switch (triple.getOS())
115                     {
116                         case llvm::Triple::Darwin:  // Deprecated, but still support Darwin for historical reasons
117                         case llvm::Triple::IOS:     // This is the right triple value for iOS debugging
118                             break;
119 
120                         case llvm::Triple::UnknownOS:
121                             create = !arch->TripleOSWasSpecified();
122                             break;
123 
124                         default:
125                             create = false;
126                             break;
127                     }
128                 }
129             }
130             break;
131         default:
132             break;
133         }
134     }
135 
136     if (create)
137         return new PlatformRemoteiOS ();
138     return NULL;
139 }
140 
141 
142 const char *
143 PlatformRemoteiOS::GetPluginNameStatic ()
144 {
145     return "PlatformRemoteiOS";
146 }
147 
148 const char *
149 PlatformRemoteiOS::GetShortPluginNameStatic()
150 {
151     return "remote-ios";
152 }
153 
154 const char *
155 PlatformRemoteiOS::GetDescriptionStatic()
156 {
157     return "Remote iOS platform plug-in.";
158 }
159 
160 
161 //------------------------------------------------------------------
162 /// Default Constructor
163 //------------------------------------------------------------------
164 PlatformRemoteiOS::PlatformRemoteiOS () :
165     PlatformDarwin (false),    // This is a remote platform
166     m_sdk_directory_infos(),
167     m_device_support_directory(),
168     m_device_support_directory_for_os_version (),
169     m_build_update(),
170     m_last_module_sdk_idx(UINT32_MAX)
171 {
172 }
173 
174 //------------------------------------------------------------------
175 /// Destructor.
176 ///
177 /// The destructor is virtual since this class is designed to be
178 /// inherited from by the plug-in instance.
179 //------------------------------------------------------------------
180 PlatformRemoteiOS::~PlatformRemoteiOS()
181 {
182 }
183 
184 
185 void
186 PlatformRemoteiOS::GetStatus (Stream &strm)
187 {
188     Platform::GetStatus (strm);
189     const char *sdk_directory = GetDeviceSupportDirectoryForOSVersion();
190     if (sdk_directory)
191         strm.Printf ("  SDK Path: \"%s\"\n", sdk_directory);
192     else
193         strm.PutCString ("  SDK Path: error: unable to locate SDK\n");
194 
195     const uint32_t num_sdk_infos = m_sdk_directory_infos.size();
196     for (uint32_t i=0; i<num_sdk_infos; ++i)
197     {
198         const SDKDirectoryInfo &sdk_dir_info = m_sdk_directory_infos[i];
199         strm.Printf (" SDK Roots: [%2u] \"%s/%s\"\n",
200                      i,
201                      sdk_dir_info.directory.GetDirectory().GetCString(),
202                      sdk_dir_info.directory.GetFilename().GetCString());
203     }
204 }
205 
206 
207 Error
208 PlatformRemoteiOS::ResolveExecutable (const FileSpec &exe_file,
209                                       const ArchSpec &exe_arch,
210                                       lldb::ModuleSP &exe_module_sp,
211                                       const FileSpecList *module_search_paths_ptr)
212 {
213     Error error;
214     // Nothing special to do here, just use the actual file and architecture
215 
216     FileSpec resolved_exe_file (exe_file);
217 
218     // If we have "ls" as the exe_file, resolve the executable loation based on
219     // the current path variables
220     // TODO: resolve bare executables in the Platform SDK
221 //    if (!resolved_exe_file.Exists())
222 //        resolved_exe_file.ResolveExecutableLocation ();
223 
224     // Resolve any executable within a bundle on MacOSX
225     // TODO: verify that this handles shallow bundles, if not then implement one ourselves
226     Host::ResolveExecutableInBundle (resolved_exe_file);
227 
228     if (resolved_exe_file.Exists())
229     {
230         if (exe_arch.IsValid())
231         {
232             ModuleSpec module_spec (resolved_exe_file, exe_arch);
233             error = ModuleList::GetSharedModule (module_spec,
234                                                  exe_module_sp,
235                                                  NULL,
236                                                  NULL,
237                                                  NULL);
238 
239             if (exe_module_sp && exe_module_sp->GetObjectFile())
240                 return error;
241             exe_module_sp.reset();
242         }
243         // No valid architecture was specified or the exact ARM slice wasn't
244         // found so ask the platform for the architectures that we should be
245         // using (in the correct order) and see if we can find a match that way
246         StreamString arch_names;
247         ArchSpec platform_arch;
248         for (uint32_t idx = 0; GetSupportedArchitectureAtIndex (idx, platform_arch); ++idx)
249         {
250             ModuleSpec module_spec (resolved_exe_file, platform_arch);
251             error = ModuleList::GetSharedModule (module_spec,
252                                                  exe_module_sp,
253                                                  NULL,
254                                                  NULL,
255                                                  NULL);
256             // Did we find an executable using one of the
257             if (error.Success())
258             {
259                 if (exe_module_sp && exe_module_sp->GetObjectFile())
260                     break;
261                 else
262                     error.SetErrorToGenericError();
263             }
264 
265             if (idx > 0)
266                 arch_names.PutCString (", ");
267             arch_names.PutCString (platform_arch.GetArchitectureName());
268         }
269 
270         if (error.Fail() || !exe_module_sp)
271         {
272             error.SetErrorStringWithFormat ("'%s%s%s' doesn't contain any '%s' platform architectures: %s",
273                                             exe_file.GetDirectory().AsCString(""),
274                                             exe_file.GetDirectory() ? "/" : "",
275                                             exe_file.GetFilename().AsCString(""),
276                                             GetShortPluginName(),
277                                             arch_names.GetString().c_str());
278         }
279     }
280     else
281     {
282         error.SetErrorStringWithFormat ("'%s%s%s' does not exist",
283                                         exe_file.GetDirectory().AsCString(""),
284                                         exe_file.GetDirectory() ? "/" : "",
285                                         exe_file.GetFilename().AsCString(""));
286     }
287 
288     return error;
289 }
290 
291 FileSpec::EnumerateDirectoryResult
292 PlatformRemoteiOS::GetContainedFilesIntoVectorOfStringsCallback (void *baton,
293                                                                  FileSpec::FileType file_type,
294                                                                  const FileSpec &file_spec)
295 {
296     ((PlatformRemoteiOS::SDKDirectoryInfoCollection *)baton)->push_back(PlatformRemoteiOS::SDKDirectoryInfo(file_spec));
297     return FileSpec::eEnumerateDirectoryResultNext;
298 }
299 
300 bool
301 PlatformRemoteiOS::UpdateSDKDirectoryInfosInNeeded()
302 {
303     if (m_sdk_directory_infos.empty())
304     {
305         const char *device_support_dir = GetDeviceSupportDirectory();
306         if (device_support_dir)
307         {
308             const bool find_directories = true;
309             const bool find_files = false;
310             const bool find_other = false;
311             FileSpec::EnumerateDirectory (m_device_support_directory.c_str(),
312                                           find_directories,
313                                           find_files,
314                                           find_other,
315                                           GetContainedFilesIntoVectorOfStringsCallback,
316                                           &m_sdk_directory_infos);
317 
318             const uint32_t num_installed = m_sdk_directory_infos.size();
319             FileSpec local_sdk_cache("~/Library/Developer/Xcode/iOS DeviceSupport", true);
320             if (local_sdk_cache.Exists())
321             {
322                 char path[PATH_MAX];
323                 if (local_sdk_cache.GetPath(path, sizeof(path)))
324                 {
325                     FileSpec::EnumerateDirectory (path,
326                                                   find_directories,
327                                                   find_files,
328                                                   find_other,
329                                                   GetContainedFilesIntoVectorOfStringsCallback,
330                                                   &m_sdk_directory_infos);
331                     const uint32_t num_sdk_infos = m_sdk_directory_infos.size();
332                     // First try for an exact match of major, minor and update
333                     for (uint32_t i=num_installed; i<num_sdk_infos; ++i)
334                     {
335                         m_sdk_directory_infos[i].user_cached = true;
336                     }
337                 }
338             }
339         }
340     }
341     return !m_sdk_directory_infos.empty();
342 }
343 
344 const PlatformRemoteiOS::SDKDirectoryInfo *
345 PlatformRemoteiOS::GetSDKDirectoryForCurrentOSVersion ()
346 {
347     uint32_t i;
348     if (UpdateSDKDirectoryInfosInNeeded())
349     {
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         {
358             for (i=0; i<num_sdk_infos; ++i)
359                 check_sdk_info[i] = m_sdk_directory_infos[i].build == build;
360         }
361 
362         // If we are connected we can find the version of the OS the platform
363         // us running on and select the right SDK
364         uint32_t major, minor, update;
365         if (GetOSVersion(major, minor, update))
366         {
367             if (UpdateSDKDirectoryInfosInNeeded())
368             {
369                 // First try for an exact match of major, minor and update
370                 for (i=0; i<num_sdk_infos; ++i)
371                 {
372                     if (check_sdk_info[i])
373                     {
374                         if (m_sdk_directory_infos[i].version_major == major &&
375                             m_sdk_directory_infos[i].version_minor == minor &&
376                             m_sdk_directory_infos[i].version_update == update)
377                         {
378                             return &m_sdk_directory_infos[i];
379                         }
380                     }
381                 }
382                 // First try for an exact match of major and minor
383                 for (i=0; i<num_sdk_infos; ++i)
384                 {
385                     if (check_sdk_info[i])
386                     {
387                         if (m_sdk_directory_infos[i].version_major == major &&
388                             m_sdk_directory_infos[i].version_minor == minor)
389                         {
390                             return &m_sdk_directory_infos[i];
391                         }
392                     }
393                 }
394                 // Lastly try to match of major version only..
395                 for (i=0; i<num_sdk_infos; ++i)
396                 {
397                     if (check_sdk_info[i])
398                     {
399                         if (m_sdk_directory_infos[i].version_major == major)
400                         {
401                             return &m_sdk_directory_infos[i];
402                         }
403                     }
404                 }
405             }
406         }
407         else if (build)
408         {
409             // No version, just a build number, search for the first one that matches
410             for (i=0; i<num_sdk_infos; ++i)
411                 if (check_sdk_info[i])
412                     return &m_sdk_directory_infos[i];
413         }
414     }
415     return NULL;
416 }
417 
418 const PlatformRemoteiOS::SDKDirectoryInfo *
419 PlatformRemoteiOS::GetSDKDirectoryForLatestOSVersion ()
420 {
421     const PlatformRemoteiOS::SDKDirectoryInfo *result = NULL;
422     if (UpdateSDKDirectoryInfosInNeeded())
423     {
424         const uint32_t num_sdk_infos = m_sdk_directory_infos.size();
425         // First try for an exact match of major, minor and update
426         for (uint32_t i=0; i<num_sdk_infos; ++i)
427         {
428             const SDKDirectoryInfo &sdk_dir_info = m_sdk_directory_infos[i];
429             if (sdk_dir_info.version_major != UINT32_MAX)
430             {
431                 if (result == NULL || sdk_dir_info.version_major > result->version_major)
432                 {
433                     result = &sdk_dir_info;
434                 }
435                 else if (sdk_dir_info.version_major == result->version_major)
436                 {
437                     if (sdk_dir_info.version_minor > result->version_minor)
438                     {
439                         result = &sdk_dir_info;
440                     }
441                     else if (sdk_dir_info.version_minor == result->version_minor)
442                     {
443                         if (sdk_dir_info.version_update > result->version_update)
444                         {
445                             result = &sdk_dir_info;
446                         }
447                     }
448                 }
449             }
450         }
451     }
452     return result;
453 }
454 
455 
456 
457 const char *
458 PlatformRemoteiOS::GetDeviceSupportDirectory()
459 {
460     if (m_device_support_directory.empty())
461     {
462         const char *device_support_dir = GetDeveloperDirectory();
463         if (device_support_dir)
464         {
465             m_device_support_directory.assign (device_support_dir);
466             m_device_support_directory.append ("/Platforms/iPhoneOS.platform/DeviceSupport");
467         }
468         else
469         {
470             // Assign a single NULL character so we know we tried to find the device
471             // support directory and we don't keep trying to find it over and over.
472             m_device_support_directory.assign (1, '\0');
473         }
474     }
475     // We should have put a single NULL character into m_device_support_directory
476     // or it should have a valid path if the code gets here
477     assert (m_device_support_directory.empty() == false);
478     if (m_device_support_directory[0])
479         return m_device_support_directory.c_str();
480     return NULL;
481 }
482 
483 
484 const char *
485 PlatformRemoteiOS::GetDeviceSupportDirectoryForOSVersion()
486 {
487     if (m_sdk_sysroot)
488         return m_sdk_sysroot.GetCString();
489 
490     if (m_device_support_directory_for_os_version.empty())
491     {
492         const PlatformRemoteiOS::SDKDirectoryInfo *sdk_dir_info = GetSDKDirectoryForCurrentOSVersion ();
493         if (sdk_dir_info == NULL)
494             sdk_dir_info = GetSDKDirectoryForLatestOSVersion ();
495         if (sdk_dir_info)
496         {
497             char path[PATH_MAX];
498             if (sdk_dir_info->directory.GetPath(path, sizeof(path)))
499             {
500                 m_device_support_directory_for_os_version = path;
501                 return m_device_support_directory_for_os_version.c_str();
502             }
503         }
504         else
505         {
506             // Assign a single NULL character so we know we tried to find the device
507             // support directory and we don't keep trying to find it over and over.
508             m_device_support_directory_for_os_version.assign (1, '\0');
509         }
510     }
511     // We should have put a single NULL character into m_device_support_directory_for_os_version
512     // or it should have a valid path if the code gets here
513     assert (m_device_support_directory_for_os_version.empty() == false);
514     if (m_device_support_directory_for_os_version[0])
515         return m_device_support_directory_for_os_version.c_str();
516     return NULL;
517 }
518 
519 uint32_t
520 PlatformRemoteiOS::FindFileInAllSDKs (const char *platform_file_path,
521                                       FileSpecList &file_list)
522 {
523     if (platform_file_path && platform_file_path[0] && UpdateSDKDirectoryInfosInNeeded())
524     {
525         const uint32_t num_sdk_infos = m_sdk_directory_infos.size();
526         lldb_private::FileSpec local_file;
527         // First try for an exact match of major, minor and update
528         for (uint32_t sdk_idx=0; sdk_idx<num_sdk_infos; ++sdk_idx)
529         {
530             if (GetFileInSDK (platform_file_path,
531                               sdk_idx,
532                               local_file))
533             {
534                 file_list.Append(local_file);
535             }
536         }
537     }
538     return file_list.GetSize();
539 }
540 
541 bool
542 PlatformRemoteiOS::GetFileInSDK (const char *platform_file_path,
543                                  uint32_t sdk_idx,
544                                  lldb_private::FileSpec &local_file)
545 {
546     if (sdk_idx < m_sdk_directory_infos.size())
547     {
548         char sdkroot_path[PATH_MAX];
549         const SDKDirectoryInfo &sdk_dir_info = m_sdk_directory_infos[sdk_idx];
550         if (sdk_dir_info.directory.GetPath(sdkroot_path, sizeof(sdkroot_path)))
551         {
552             const bool symbols_dirs_only = true;
553 
554             return GetFileInSDKRoot (platform_file_path,
555                                      sdkroot_path,
556                                      symbols_dirs_only,
557                                      local_file);
558         }
559     }
560     return false;
561 }
562 
563 
564 bool
565 PlatformRemoteiOS::GetFileInSDKRoot (const char *platform_file_path,
566                                      const char *sdkroot_path,
567                                      bool symbols_dirs_only,
568                                      lldb_private::FileSpec &local_file)
569 {
570     if (sdkroot_path && sdkroot_path[0] && platform_file_path && platform_file_path[0])
571     {
572         char resolved_path[PATH_MAX];
573 
574         if (!symbols_dirs_only)
575         {
576             ::snprintf (resolved_path,
577                         sizeof(resolved_path),
578                         "%s/%s",
579                         sdkroot_path,
580                         platform_file_path);
581 
582             local_file.SetFile(resolved_path, true);
583             if (local_file.Exists())
584                 return true;
585         }
586 
587         ::snprintf (resolved_path,
588                     sizeof(resolved_path),
589                     "%s/Symbols.Internal/%s",
590                     sdkroot_path,
591                     platform_file_path);
592 
593         local_file.SetFile(resolved_path, true);
594         if (local_file.Exists())
595             return true;
596         ::snprintf (resolved_path,
597                     sizeof(resolved_path),
598                     "%s/Symbols/%s",
599                     sdkroot_path,
600                     platform_file_path);
601 
602         local_file.SetFile(resolved_path, true);
603         if (local_file.Exists())
604             return true;
605     }
606     return false;
607 }
608 
609 
610 Error
611 PlatformRemoteiOS::GetSymbolFile (const FileSpec &platform_file,
612                                   const UUID *uuid_ptr,
613                                   FileSpec &local_file)
614 {
615     Error error;
616     char platform_file_path[PATH_MAX];
617     if (platform_file.GetPath(platform_file_path, sizeof(platform_file_path)))
618     {
619         char resolved_path[PATH_MAX];
620 
621         const char * os_version_dir = GetDeviceSupportDirectoryForOSVersion();
622         if (os_version_dir)
623         {
624             ::snprintf (resolved_path,
625                         sizeof(resolved_path),
626                         "%s/%s",
627                         os_version_dir,
628                         platform_file_path);
629 
630             local_file.SetFile(resolved_path, true);
631             if (local_file.Exists())
632                 return error;
633 
634             ::snprintf (resolved_path,
635                         sizeof(resolved_path),
636                         "%s/Symbols.Internal/%s",
637                         os_version_dir,
638                         platform_file_path);
639 
640             local_file.SetFile(resolved_path, true);
641             if (local_file.Exists())
642                 return error;
643             ::snprintf (resolved_path,
644                         sizeof(resolved_path),
645                         "%s/Symbols/%s",
646                         os_version_dir,
647                         platform_file_path);
648 
649             local_file.SetFile(resolved_path, true);
650             if (local_file.Exists())
651                 return error;
652 
653         }
654         local_file = platform_file;
655         if (local_file.Exists())
656             return error;
657 
658         error.SetErrorStringWithFormat ("unable to locate a platform file for '%s' in platform '%s'",
659                                         platform_file_path,
660                                         GetPluginName());
661     }
662     else
663     {
664         error.SetErrorString ("invalid platform file argument");
665     }
666     return error;
667 }
668 
669 Error
670 PlatformRemoteiOS::GetSharedModule (const ModuleSpec &module_spec,
671                                     ModuleSP &module_sp,
672                                     const FileSpecList *module_search_paths_ptr,
673                                     ModuleSP *old_module_sp_ptr,
674                                     bool *did_create_ptr)
675 {
676     // For iOS, the SDK files are all cached locally on the host
677     // system. So first we ask for the file in the cached SDK,
678     // then we attempt to get a shared module for the right architecture
679     // with the right UUID.
680     const FileSpec &platform_file = module_spec.GetFileSpec();
681 
682     FileSpec local_file;
683     const UUID *module_uuid_ptr = module_spec.GetUUIDPtr();
684     Error error (GetSymbolFile (platform_file, module_uuid_ptr, local_file));
685     if (error.Success())
686     {
687         error = ResolveExecutable (local_file, module_spec.GetArchitecture(), module_sp, NULL);
688         if (module_sp && ((module_uuid_ptr == NULL) || (module_sp->GetUUID() == *module_uuid_ptr)))
689         {
690             //printf ("found in user specified SDK\n");
691             error.Clear();
692             return error;
693         }
694 
695         char platform_file_path[PATH_MAX];
696         if (platform_file.GetPath(platform_file_path, sizeof(platform_file_path)))
697         {
698             FileSpec local_file;
699             const uint32_t num_sdk_infos = m_sdk_directory_infos.size();
700             // Try the last SDK index if it is set as most files from an SDK
701             // will tend to be valid in that same SDK.
702             if (m_last_module_sdk_idx < num_sdk_infos)
703             {
704                 if (GetFileInSDK (platform_file_path, m_last_module_sdk_idx, local_file))
705                 {
706                     //printf ("sdk[%u] last: '%s/%s'\n", m_last_module_sdk_idx, local_file.GetDirectory().GetCString(), local_file.GetFilename().GetCString());
707                     module_sp.reset();
708                     error = ResolveExecutable (local_file,
709                                                module_spec.GetArchitecture(),
710                                                module_sp,
711                                                NULL);
712                     if (module_sp && ((module_uuid_ptr == NULL) || (module_sp->GetUUID() == *module_uuid_ptr)))
713                     {
714                         //printf ("sdk[%u] last found\n", m_last_module_sdk_idx);
715                         error.Clear();
716                         return error;
717                     }
718                 }
719             }
720 
721             // First try for an exact match of major, minor and update
722             for (uint32_t sdk_idx=0; sdk_idx<num_sdk_infos; ++sdk_idx)
723             {
724                 if (m_last_module_sdk_idx == sdk_idx)
725                 {
726                     // Skip the last module SDK index if we already searched
727                     // it above
728                     continue;
729                 }
730                 if (GetFileInSDK (platform_file_path, sdk_idx, local_file))
731                 {
732                     //printf ("sdk[%u]: '%s/%s'\n", sdk_idx, local_file.GetDirectory().GetCString(), local_file.GetFilename().GetCString());
733 
734                     error = ResolveExecutable (local_file,
735                                                module_spec.GetArchitecture(),
736                                                module_sp,
737                                                NULL);
738                     if (module_sp && ((module_uuid_ptr == NULL) || (module_sp->GetUUID() == *module_uuid_ptr)))
739                     {
740                         // Remember the index of the last SDK that we found a file
741                         // in in case the wrong SDK was selected.
742                         m_last_module_sdk_idx = sdk_idx;
743                         //printf ("sdk[%u]: found (setting last to %u)\n", sdk_idx, m_last_module_sdk_idx);
744                         error.Clear();
745                         return error;
746                     }
747                 }
748             }
749         }
750         // Not the module we are looking for... Nothing to see here...
751         module_sp.reset();
752     }
753 
754     const bool always_create = false;
755     error = ModuleList::GetSharedModule (module_spec,
756                                          module_sp,
757                                          module_search_paths_ptr,
758                                          old_module_sp_ptr,
759                                          did_create_ptr,
760                                          always_create);
761 
762     if (module_sp)
763         module_sp->SetPlatformFileSpec(platform_file);
764 
765     return error;
766 }
767 
768 
769 uint32_t
770 PlatformRemoteiOS::FindProcesses (const ProcessInstanceInfoMatch &match_info,
771                                   ProcessInstanceInfoList &process_infos)
772 {
773     // TODO: if connected, send a packet to get the remote process infos by name
774     process_infos.Clear();
775     return 0;
776 }
777 
778 bool
779 PlatformRemoteiOS::GetProcessInfo (lldb::pid_t pid, ProcessInstanceInfo &process_info)
780 {
781     // TODO: if connected, send a packet to get the remote process info
782     process_info.Clear();
783     return false;
784 }
785 
786 bool
787 PlatformRemoteiOS::GetSupportedArchitectureAtIndex (uint32_t idx, ArchSpec &arch)
788 {
789     return ARMGetSupportedArchitectureAtIndex (idx, arch);
790 }
791