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