1 //===-- Platform.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 "lldb/Target/Platform.h"
11 
12 // C Includes
13 // C++ Includes
14 // Other libraries and framework includes
15 // Project includes
16 #include "lldb/Breakpoint/BreakpointIDList.h"
17 #include "lldb/Core/DataBufferHeap.h"
18 #include "lldb/Core/Error.h"
19 #include "lldb/Core/Log.h"
20 #include "lldb/Core/ModuleSpec.h"
21 #include "lldb/Core/PluginManager.h"
22 #include "lldb/Core/StructuredData.h"
23 #include "lldb/Host/FileSpec.h"
24 #include "lldb/Host/FileSystem.h"
25 #include "lldb/Host/Host.h"
26 #include "lldb/Host/HostInfo.h"
27 #include "lldb/Target/Process.h"
28 #include "lldb/Target/Target.h"
29 #include "lldb/Utility/Utils.h"
30 
31 using namespace lldb;
32 using namespace lldb_private;
33 
34 static uint32_t g_initialize_count = 0;
35 
36 // Use a singleton function for g_local_platform_sp to avoid init
37 // constructors since LLDB is often part of a shared library
38 static PlatformSP&
39 GetHostPlatformSP ()
40 {
41     static PlatformSP g_platform_sp;
42     return g_platform_sp;
43 }
44 
45 const char *
46 Platform::GetHostPlatformName ()
47 {
48     return "host";
49 }
50 
51 //------------------------------------------------------------------
52 /// Get the native host platform plug-in.
53 ///
54 /// There should only be one of these for each host that LLDB runs
55 /// upon that should be statically compiled in and registered using
56 /// preprocessor macros or other similar build mechanisms.
57 ///
58 /// This platform will be used as the default platform when launching
59 /// or attaching to processes unless another platform is specified.
60 //------------------------------------------------------------------
61 PlatformSP
62 Platform::GetHostPlatform ()
63 {
64     return GetHostPlatformSP ();
65 }
66 
67 static std::vector<PlatformSP> &
68 GetPlatformList()
69 {
70     static std::vector<PlatformSP> g_platform_list;
71     return g_platform_list;
72 }
73 
74 static Mutex &
75 GetPlatformListMutex ()
76 {
77     static Mutex g_mutex(Mutex::eMutexTypeRecursive);
78     return g_mutex;
79 }
80 
81 void
82 Platform::Initialize ()
83 {
84     g_initialize_count++;
85 }
86 
87 void
88 Platform::Terminate ()
89 {
90     if (g_initialize_count > 0)
91     {
92         if (--g_initialize_count == 0)
93         {
94             Mutex::Locker locker(GetPlatformListMutex ());
95             GetPlatformList().clear();
96         }
97     }
98 }
99 
100 void
101 Platform::SetHostPlatform (const lldb::PlatformSP &platform_sp)
102 {
103     // The native platform should use its static void Platform::Initialize()
104     // function to register itself as the native platform.
105     GetHostPlatformSP () = platform_sp;
106 
107     if (platform_sp)
108     {
109         Mutex::Locker locker(GetPlatformListMutex ());
110         GetPlatformList().push_back(platform_sp);
111     }
112 }
113 
114 Error
115 Platform::GetFileWithUUID (const FileSpec &platform_file,
116                            const UUID *uuid_ptr,
117                            FileSpec &local_file)
118 {
119     // Default to the local case
120     local_file = platform_file;
121     return Error();
122 }
123 
124 FileSpecList
125 Platform::LocateExecutableScriptingResources (Target *target, Module &module, Stream* feedback_stream)
126 {
127     return FileSpecList();
128 }
129 
130 //PlatformSP
131 //Platform::FindPlugin (Process *process, const ConstString &plugin_name)
132 //{
133 //    PlatformCreateInstance create_callback = NULL;
134 //    if (plugin_name)
135 //    {
136 //        create_callback  = PluginManager::GetPlatformCreateCallbackForPluginName (plugin_name);
137 //        if (create_callback)
138 //        {
139 //            ArchSpec arch;
140 //            if (process)
141 //            {
142 //                arch = process->GetTarget().GetArchitecture();
143 //            }
144 //            PlatformSP platform_sp(create_callback(process, &arch));
145 //            if (platform_sp)
146 //                return platform_sp;
147 //        }
148 //    }
149 //    else
150 //    {
151 //        for (uint32_t idx = 0; (create_callback = PluginManager::GetPlatformCreateCallbackAtIndex(idx)) != NULL; ++idx)
152 //        {
153 //            PlatformSP platform_sp(create_callback(process, nullptr));
154 //            if (platform_sp)
155 //                return platform_sp;
156 //        }
157 //    }
158 //    return PlatformSP();
159 //}
160 
161 Error
162 Platform::GetSharedModule (const ModuleSpec &module_spec,
163                            ModuleSP &module_sp,
164                            const FileSpecList *module_search_paths_ptr,
165                            ModuleSP *old_module_sp_ptr,
166                            bool *did_create_ptr)
167 {
168     // Don't do any path remapping for the default implementation
169     // of the platform GetSharedModule function, just call through
170     // to our static ModuleList function. Platform subclasses that
171     // implement remote debugging, might have a developer kits
172     // installed that have cached versions of the files for the
173     // remote target, or might implement a download and cache
174     // locally implementation.
175     const bool always_create = false;
176     return ModuleList::GetSharedModule (module_spec,
177                                         module_sp,
178                                         module_search_paths_ptr,
179                                         old_module_sp_ptr,
180                                         did_create_ptr,
181                                         always_create);
182 }
183 
184 PlatformSP
185 Platform::Find (const ConstString &name)
186 {
187     if (name)
188     {
189         static ConstString g_host_platform_name ("host");
190         if (name == g_host_platform_name)
191             return GetHostPlatform();
192 
193         Mutex::Locker locker(GetPlatformListMutex ());
194         for (const auto &platform_sp : GetPlatformList())
195         {
196             if (platform_sp->GetName() == name)
197                 return platform_sp;
198         }
199     }
200     return PlatformSP();
201 }
202 
203 PlatformSP
204 Platform::Create (const ConstString &name, Error &error)
205 {
206     PlatformCreateInstance create_callback = NULL;
207     lldb::PlatformSP platform_sp;
208     if (name)
209     {
210         static ConstString g_host_platform_name ("host");
211         if (name == g_host_platform_name)
212             return GetHostPlatform();
213 
214         create_callback = PluginManager::GetPlatformCreateCallbackForPluginName (name);
215         if (create_callback)
216             platform_sp = create_callback(true, NULL);
217         else
218             error.SetErrorStringWithFormat ("unable to find a plug-in for the platform named \"%s\"", name.GetCString());
219     }
220     else
221         error.SetErrorString ("invalid platform name");
222 
223     if (platform_sp)
224     {
225         Mutex::Locker locker(GetPlatformListMutex ());
226         GetPlatformList().push_back(platform_sp);
227     }
228 
229     return platform_sp;
230 }
231 
232 
233 PlatformSP
234 Platform::Create (const ArchSpec &arch, ArchSpec *platform_arch_ptr, Error &error)
235 {
236     lldb::PlatformSP platform_sp;
237     if (arch.IsValid())
238     {
239         // Scope for locker
240         {
241             // First try exact arch matches across all platforms already created
242             Mutex::Locker locker(GetPlatformListMutex ());
243             for (const auto &platform_sp : GetPlatformList())
244             {
245                 if (platform_sp->IsCompatibleArchitecture(arch, true, platform_arch_ptr))
246                     return platform_sp;
247             }
248 
249             // Next try compatible arch matches across all platforms already created
250             for (const auto &platform_sp : GetPlatformList())
251             {
252                 if (platform_sp->IsCompatibleArchitecture(arch, false, platform_arch_ptr))
253                     return platform_sp;
254             }
255         }
256 
257         PlatformCreateInstance create_callback;
258         // First try exact arch matches across all platform plug-ins
259         uint32_t idx;
260         for (idx = 0; (create_callback = PluginManager::GetPlatformCreateCallbackAtIndex (idx)); ++idx)
261         {
262             if (create_callback)
263             {
264                 platform_sp = create_callback(false, &arch);
265                 if (platform_sp && platform_sp->IsCompatibleArchitecture(arch, true, platform_arch_ptr))
266                 {
267                     Mutex::Locker locker(GetPlatformListMutex ());
268                     GetPlatformList().push_back(platform_sp);
269                     return platform_sp;
270                 }
271             }
272         }
273         // Next try compatible arch matches across all platform plug-ins
274         for (idx = 0; (create_callback = PluginManager::GetPlatformCreateCallbackAtIndex (idx)); ++idx)
275         {
276             if (create_callback)
277             {
278                 platform_sp = create_callback(false, &arch);
279                 if (platform_sp && platform_sp->IsCompatibleArchitecture(arch, false, platform_arch_ptr))
280                 {
281                     Mutex::Locker locker(GetPlatformListMutex ());
282                     GetPlatformList().push_back(platform_sp);
283                     return platform_sp;
284                 }
285             }
286         }
287     }
288     else
289         error.SetErrorString ("invalid platform name");
290     if (platform_arch_ptr)
291         platform_arch_ptr->Clear();
292     platform_sp.reset();
293     return platform_sp;
294 }
295 
296 //------------------------------------------------------------------
297 /// Default Constructor
298 //------------------------------------------------------------------
299 Platform::Platform (bool is_host) :
300     m_is_host (is_host),
301     m_os_version_set_while_connected (false),
302     m_system_arch_set_while_connected (false),
303     m_sdk_sysroot (),
304     m_sdk_build (),
305     m_working_dir (),
306     m_remote_url (),
307     m_name (),
308     m_major_os_version (UINT32_MAX),
309     m_minor_os_version (UINT32_MAX),
310     m_update_os_version (UINT32_MAX),
311     m_system_arch(),
312     m_mutex (Mutex::eMutexTypeRecursive),
313     m_uid_map(),
314     m_gid_map(),
315     m_max_uid_name_len (0),
316     m_max_gid_name_len (0),
317     m_supports_rsync (false),
318     m_rsync_opts (),
319     m_rsync_prefix (),
320     m_supports_ssh (false),
321     m_ssh_opts (),
322     m_ignores_remote_hostname (false),
323     m_trap_handlers(),
324     m_calculated_trap_handlers (false)
325 {
326     Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_OBJECT));
327     if (log)
328         log->Printf ("%p Platform::Platform()", static_cast<void*>(this));
329 }
330 
331 //------------------------------------------------------------------
332 /// Destructor.
333 ///
334 /// The destructor is virtual since this class is designed to be
335 /// inherited from by the plug-in instance.
336 //------------------------------------------------------------------
337 Platform::~Platform()
338 {
339     Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_OBJECT));
340     if (log)
341         log->Printf ("%p Platform::~Platform()", static_cast<void*>(this));
342 }
343 
344 void
345 Platform::GetStatus (Stream &strm)
346 {
347     uint32_t major = UINT32_MAX;
348     uint32_t minor = UINT32_MAX;
349     uint32_t update = UINT32_MAX;
350     std::string s;
351     strm.Printf ("  Platform: %s\n", GetPluginName().GetCString());
352 
353     ArchSpec arch (GetSystemArchitecture());
354     if (arch.IsValid())
355     {
356         if (!arch.GetTriple().str().empty())
357         strm.Printf("    Triple: %s\n", arch.GetTriple().str().c_str());
358     }
359 
360     if (GetOSVersion(major, minor, update))
361     {
362         strm.Printf("OS Version: %u", major);
363         if (minor != UINT32_MAX)
364             strm.Printf(".%u", minor);
365         if (update != UINT32_MAX)
366             strm.Printf(".%u", update);
367 
368         if (GetOSBuildString (s))
369             strm.Printf(" (%s)", s.c_str());
370 
371         strm.EOL();
372     }
373 
374     if (GetOSKernelDescription (s))
375         strm.Printf("    Kernel: %s\n", s.c_str());
376 
377     if (IsHost())
378     {
379         strm.Printf("  Hostname: %s\n", GetHostname());
380     }
381     else
382     {
383         const bool is_connected = IsConnected();
384         if (is_connected)
385             strm.Printf("  Hostname: %s\n", GetHostname());
386         strm.Printf(" Connected: %s\n", is_connected ? "yes" : "no");
387     }
388 
389     if (GetWorkingDirectory())
390     {
391         strm.Printf("WorkingDir: %s\n", GetWorkingDirectory().GetCString());
392     }
393     if (!IsConnected())
394         return;
395 
396     std::string specific_info(GetPlatformSpecificConnectionInformation());
397 
398     if (specific_info.empty() == false)
399         strm.Printf("Platform-specific connection: %s\n", specific_info.c_str());
400 }
401 
402 
403 bool
404 Platform::GetOSVersion (uint32_t &major,
405                         uint32_t &minor,
406                         uint32_t &update)
407 {
408     Mutex::Locker locker (m_mutex);
409 
410     bool success = m_major_os_version != UINT32_MAX;
411     if (IsHost())
412     {
413         if (!success)
414         {
415             // We have a local host platform
416             success = HostInfo::GetOSVersion(m_major_os_version, m_minor_os_version, m_update_os_version);
417             m_os_version_set_while_connected = success;
418         }
419     }
420     else
421     {
422         // We have a remote platform. We can only fetch the remote
423         // OS version if we are connected, and we don't want to do it
424         // more than once.
425 
426         const bool is_connected = IsConnected();
427 
428         bool fetch = false;
429         if (success)
430         {
431             // We have valid OS version info, check to make sure it wasn't
432             // manually set prior to connecting. If it was manually set prior
433             // to connecting, then lets fetch the actual OS version info
434             // if we are now connected.
435             if (is_connected && !m_os_version_set_while_connected)
436                 fetch = true;
437         }
438         else
439         {
440             // We don't have valid OS version info, fetch it if we are connected
441             fetch = is_connected;
442         }
443 
444         if (fetch)
445         {
446             success = GetRemoteOSVersion ();
447             m_os_version_set_while_connected = success;
448         }
449     }
450 
451     if (success)
452     {
453         major = m_major_os_version;
454         minor = m_minor_os_version;
455         update = m_update_os_version;
456     }
457     return success;
458 }
459 
460 bool
461 Platform::GetOSBuildString (std::string &s)
462 {
463     s.clear();
464 
465     if (IsHost())
466 #if !defined(__linux__)
467         return HostInfo::GetOSBuildString(s);
468 #else
469         return false;
470 #endif
471     else
472         return GetRemoteOSBuildString (s);
473 }
474 
475 bool
476 Platform::GetOSKernelDescription (std::string &s)
477 {
478     if (IsHost())
479 #if !defined(__linux__)
480         return HostInfo::GetOSKernelDescription(s);
481 #else
482         return false;
483 #endif
484     else
485         return GetRemoteOSKernelDescription (s);
486 }
487 
488 void
489 Platform::AddClangModuleCompilationOptions (Target *target, std::vector<std::string> &options)
490 {
491     std::vector<std::string> default_compilation_options =
492     {
493         "-x", "c++", "-Xclang", "-nostdsysteminc", "-Xclang", "-nostdsysteminc"
494     };
495 
496     options.insert(options.end(),
497                    default_compilation_options.begin(),
498                    default_compilation_options.end());
499 }
500 
501 
502 ConstString
503 Platform::GetWorkingDirectory ()
504 {
505     if (IsHost())
506     {
507         char cwd[PATH_MAX];
508         if (getcwd(cwd, sizeof(cwd)))
509             return ConstString(cwd);
510         else
511             return ConstString();
512     }
513     else
514     {
515         if (!m_working_dir)
516             m_working_dir = GetRemoteWorkingDirectory();
517         return m_working_dir;
518     }
519 }
520 
521 
522 struct RecurseCopyBaton
523 {
524     const FileSpec& dst;
525     Platform *platform_ptr;
526     Error error;
527 };
528 
529 
530 static FileSpec::EnumerateDirectoryResult
531 RecurseCopy_Callback (void *baton,
532                       FileSpec::FileType file_type,
533                       const FileSpec &src)
534 {
535     RecurseCopyBaton* rc_baton = (RecurseCopyBaton*)baton;
536     switch (file_type)
537     {
538         case FileSpec::eFileTypePipe:
539         case FileSpec::eFileTypeSocket:
540             // we have no way to copy pipes and sockets - ignore them and continue
541             return FileSpec::eEnumerateDirectoryResultNext;
542             break;
543 
544         case FileSpec::eFileTypeDirectory:
545             {
546                 // make the new directory and get in there
547                 FileSpec dst_dir = rc_baton->dst;
548                 if (!dst_dir.GetFilename())
549                     dst_dir.GetFilename() = src.GetLastPathComponent();
550                 std::string dst_dir_path (dst_dir.GetPath());
551                 Error error = rc_baton->platform_ptr->MakeDirectory(dst_dir_path.c_str(), lldb::eFilePermissionsDirectoryDefault);
552                 if (error.Fail())
553                 {
554                     rc_baton->error.SetErrorStringWithFormat("unable to setup directory %s on remote end", dst_dir_path.c_str());
555                     return FileSpec::eEnumerateDirectoryResultQuit; // got an error, bail out
556                 }
557 
558                 // now recurse
559                 std::string src_dir_path (src.GetPath());
560 
561                 // Make a filespec that only fills in the directory of a FileSpec so
562                 // when we enumerate we can quickly fill in the filename for dst copies
563                 FileSpec recurse_dst;
564                 recurse_dst.GetDirectory().SetCString(dst_dir.GetPath().c_str());
565                 RecurseCopyBaton rc_baton2 = { recurse_dst, rc_baton->platform_ptr, Error() };
566                 FileSpec::EnumerateDirectory(src_dir_path.c_str(), true, true, true, RecurseCopy_Callback, &rc_baton2);
567                 if (rc_baton2.error.Fail())
568                 {
569                     rc_baton->error.SetErrorString(rc_baton2.error.AsCString());
570                     return FileSpec::eEnumerateDirectoryResultQuit; // got an error, bail out
571                 }
572                 return FileSpec::eEnumerateDirectoryResultNext;
573             }
574             break;
575 
576         case FileSpec::eFileTypeSymbolicLink:
577             {
578                 // copy the file and keep going
579                 FileSpec dst_file = rc_baton->dst;
580                 if (!dst_file.GetFilename())
581                     dst_file.GetFilename() = src.GetFilename();
582 
583                 char buf[PATH_MAX];
584 
585                 rc_baton->error = FileSystem::Readlink(src.GetPath().c_str(), buf, sizeof(buf));
586 
587                 if (rc_baton->error.Fail())
588                     return FileSpec::eEnumerateDirectoryResultQuit; // got an error, bail out
589 
590                 rc_baton->error = rc_baton->platform_ptr->CreateSymlink(dst_file.GetPath().c_str(), buf);
591 
592                 if (rc_baton->error.Fail())
593                     return FileSpec::eEnumerateDirectoryResultQuit; // got an error, bail out
594 
595                 return FileSpec::eEnumerateDirectoryResultNext;
596             }
597             break;
598         case FileSpec::eFileTypeRegular:
599             {
600                 // copy the file and keep going
601                 FileSpec dst_file = rc_baton->dst;
602                 if (!dst_file.GetFilename())
603                     dst_file.GetFilename() = src.GetFilename();
604                 Error err = rc_baton->platform_ptr->PutFile(src, dst_file);
605                 if (err.Fail())
606                 {
607                     rc_baton->error.SetErrorString(err.AsCString());
608                     return FileSpec::eEnumerateDirectoryResultQuit; // got an error, bail out
609                 }
610                 return FileSpec::eEnumerateDirectoryResultNext;
611             }
612             break;
613 
614         case FileSpec::eFileTypeInvalid:
615         case FileSpec::eFileTypeOther:
616         case FileSpec::eFileTypeUnknown:
617             rc_baton->error.SetErrorStringWithFormat("invalid file detected during copy: %s", src.GetPath().c_str());
618             return FileSpec::eEnumerateDirectoryResultQuit; // got an error, bail out
619             break;
620     }
621     llvm_unreachable("Unhandled FileSpec::FileType!");
622 }
623 
624 Error
625 Platform::Install (const FileSpec& src, const FileSpec& dst)
626 {
627     Error error;
628 
629     Log *log = GetLogIfAnyCategoriesSet(LIBLLDB_LOG_PLATFORM);
630     if (log)
631         log->Printf ("Platform::Install (src='%s', dst='%s')", src.GetPath().c_str(), dst.GetPath().c_str());
632     FileSpec fixed_dst(dst);
633 
634     if (!fixed_dst.GetFilename())
635         fixed_dst.GetFilename() = src.GetFilename();
636 
637     ConstString working_dir = GetWorkingDirectory();
638 
639     if (dst)
640     {
641         if (dst.GetDirectory())
642         {
643             const char first_dst_dir_char = dst.GetDirectory().GetCString()[0];
644             if (first_dst_dir_char == '/' || first_dst_dir_char  == '\\')
645             {
646                 fixed_dst.GetDirectory() = dst.GetDirectory();
647             }
648             // If the fixed destination file doesn't have a directory yet,
649             // then we must have a relative path. We will resolve this relative
650             // path against the platform's working directory
651             if (!fixed_dst.GetDirectory())
652             {
653                 FileSpec relative_spec;
654                 std::string path;
655                 if (working_dir)
656                 {
657                     relative_spec.SetFile(working_dir.GetCString(), false);
658                     relative_spec.AppendPathComponent(dst.GetPath().c_str());
659                     fixed_dst.GetDirectory() = relative_spec.GetDirectory();
660                 }
661                 else
662                 {
663                     error.SetErrorStringWithFormat("platform working directory must be valid for relative path '%s'", dst.GetPath().c_str());
664                     return error;
665                 }
666             }
667         }
668         else
669         {
670             if (working_dir)
671             {
672                 fixed_dst.GetDirectory() = working_dir;
673             }
674             else
675             {
676                 error.SetErrorStringWithFormat("platform working directory must be valid for relative path '%s'", dst.GetPath().c_str());
677                 return error;
678             }
679         }
680     }
681     else
682     {
683         if (working_dir)
684         {
685             fixed_dst.GetDirectory() = working_dir;
686         }
687         else
688         {
689             error.SetErrorStringWithFormat("platform working directory must be valid when destination directory is empty");
690             return error;
691         }
692     }
693 
694     if (log)
695         log->Printf ("Platform::Install (src='%s', dst='%s') fixed_dst='%s'", src.GetPath().c_str(), dst.GetPath().c_str(), fixed_dst.GetPath().c_str());
696 
697     if (GetSupportsRSync())
698     {
699         error = PutFile(src, dst);
700     }
701     else
702     {
703         switch (src.GetFileType())
704         {
705             case FileSpec::eFileTypeDirectory:
706                 {
707                     if (GetFileExists (fixed_dst))
708                         Unlink (fixed_dst.GetPath().c_str());
709                     uint32_t permissions = src.GetPermissions();
710                     if (permissions == 0)
711                         permissions = eFilePermissionsDirectoryDefault;
712                     std::string dst_dir_path(fixed_dst.GetPath());
713                     error = MakeDirectory(dst_dir_path.c_str(), permissions);
714                     if (error.Success())
715                     {
716                         // Make a filespec that only fills in the directory of a FileSpec so
717                         // when we enumerate we can quickly fill in the filename for dst copies
718                         FileSpec recurse_dst;
719                         recurse_dst.GetDirectory().SetCString(dst_dir_path.c_str());
720                         std::string src_dir_path (src.GetPath());
721                         RecurseCopyBaton baton = { recurse_dst, this, Error() };
722                         FileSpec::EnumerateDirectory(src_dir_path.c_str(), true, true, true, RecurseCopy_Callback, &baton);
723                         return baton.error;
724                     }
725                 }
726                 break;
727 
728             case FileSpec::eFileTypeRegular:
729                 if (GetFileExists (fixed_dst))
730                     Unlink (fixed_dst.GetPath().c_str());
731                 error = PutFile(src, fixed_dst);
732                 break;
733 
734             case FileSpec::eFileTypeSymbolicLink:
735                 {
736                     if (GetFileExists (fixed_dst))
737                         Unlink (fixed_dst.GetPath().c_str());
738                     char buf[PATH_MAX];
739                     error = FileSystem::Readlink(src.GetPath().c_str(), buf, sizeof(buf));
740                     if (error.Success())
741                         error = CreateSymlink(dst.GetPath().c_str(), buf);
742                 }
743                 break;
744             case FileSpec::eFileTypePipe:
745                 error.SetErrorString("platform install doesn't handle pipes");
746                 break;
747             case FileSpec::eFileTypeSocket:
748                 error.SetErrorString("platform install doesn't handle sockets");
749                 break;
750             case FileSpec::eFileTypeInvalid:
751             case FileSpec::eFileTypeUnknown:
752             case FileSpec::eFileTypeOther:
753                 error.SetErrorString("platform install doesn't handle non file or directory items");
754                 break;
755         }
756     }
757     return error;
758 }
759 
760 bool
761 Platform::SetWorkingDirectory (const ConstString &path)
762 {
763     if (IsHost())
764     {
765         Log *log = GetLogIfAnyCategoriesSet(LIBLLDB_LOG_PLATFORM);
766         if (log)
767             log->Printf("Platform::SetWorkingDirectory('%s')", path.GetCString());
768 #ifdef _WIN32
769         // Not implemented on Windows
770         return false;
771 #else
772         if (path)
773         {
774             if (chdir(path.GetCString()) == 0)
775                 return true;
776         }
777         return false;
778 #endif
779     }
780     else
781     {
782         m_working_dir.Clear();
783         return SetRemoteWorkingDirectory(path);
784     }
785 }
786 
787 Error
788 Platform::MakeDirectory (const char *path, uint32_t permissions)
789 {
790     if (IsHost())
791         return FileSystem::MakeDirectory(path, permissions);
792     else
793     {
794         Error error;
795         error.SetErrorStringWithFormat("remote platform %s doesn't support %s", GetPluginName().GetCString(), __PRETTY_FUNCTION__);
796         return error;
797     }
798 }
799 
800 Error
801 Platform::GetFilePermissions (const char *path, uint32_t &file_permissions)
802 {
803     if (IsHost())
804         return FileSystem::GetFilePermissions(path, file_permissions);
805     else
806     {
807         Error error;
808         error.SetErrorStringWithFormat("remote platform %s doesn't support %s", GetPluginName().GetCString(), __PRETTY_FUNCTION__);
809         return error;
810     }
811 }
812 
813 Error
814 Platform::SetFilePermissions (const char *path, uint32_t file_permissions)
815 {
816     if (IsHost())
817         return FileSystem::SetFilePermissions(path, file_permissions);
818     else
819     {
820         Error error;
821         error.SetErrorStringWithFormat("remote platform %s doesn't support %s", GetPluginName().GetCString(), __PRETTY_FUNCTION__);
822         return error;
823     }
824 }
825 
826 ConstString
827 Platform::GetName ()
828 {
829     return GetPluginName();
830 }
831 
832 const char *
833 Platform::GetHostname ()
834 {
835     if (IsHost())
836         return "127.0.0.1";
837 
838     if (m_name.empty())
839         return NULL;
840     return m_name.c_str();
841 }
842 
843 bool
844 Platform::SetRemoteWorkingDirectory(const ConstString &path)
845 {
846     Log *log = GetLogIfAnyCategoriesSet(LIBLLDB_LOG_PLATFORM);
847     if (log)
848         log->Printf("Platform::SetRemoteWorkingDirectory('%s')", path.GetCString());
849     m_working_dir = path;
850     return true;
851 }
852 
853 const char *
854 Platform::GetUserName (uint32_t uid)
855 {
856 #if !defined(LLDB_DISABLE_POSIX)
857     const char *user_name = GetCachedUserName(uid);
858     if (user_name)
859         return user_name;
860     if (IsHost())
861     {
862         std::string name;
863         if (HostInfo::LookupUserName(uid, name))
864             return SetCachedUserName (uid, name.c_str(), name.size());
865     }
866 #endif
867     return NULL;
868 }
869 
870 const char *
871 Platform::GetGroupName (uint32_t gid)
872 {
873 #if !defined(LLDB_DISABLE_POSIX)
874     const char *group_name = GetCachedGroupName(gid);
875     if (group_name)
876         return group_name;
877     if (IsHost())
878     {
879         std::string name;
880         if (HostInfo::LookupGroupName(gid, name))
881             return SetCachedGroupName (gid, name.c_str(), name.size());
882     }
883 #endif
884     return NULL;
885 }
886 
887 bool
888 Platform::SetOSVersion (uint32_t major,
889                         uint32_t minor,
890                         uint32_t update)
891 {
892     if (IsHost())
893     {
894         // We don't need anyone setting the OS version for the host platform,
895         // we should be able to figure it out by calling HostInfo::GetOSVersion(...).
896         return false;
897     }
898     else
899     {
900         // We have a remote platform, allow setting the target OS version if
901         // we aren't connected, since if we are connected, we should be able to
902         // request the remote OS version from the connected platform.
903         if (IsConnected())
904             return false;
905         else
906         {
907             // We aren't connected and we might want to set the OS version
908             // ahead of time before we connect so we can peruse files and
909             // use a local SDK or PDK cache of support files to disassemble
910             // or do other things.
911             m_major_os_version = major;
912             m_minor_os_version = minor;
913             m_update_os_version = update;
914             return true;
915         }
916     }
917     return false;
918 }
919 
920 
921 Error
922 Platform::ResolveExecutable (const ModuleSpec &module_spec,
923                              lldb::ModuleSP &exe_module_sp,
924                              const FileSpecList *module_search_paths_ptr)
925 {
926     Error error;
927     if (module_spec.GetFileSpec().Exists())
928     {
929         if (module_spec.GetArchitecture().IsValid())
930         {
931             error = ModuleList::GetSharedModule (module_spec,
932                                                  exe_module_sp,
933                                                  module_search_paths_ptr,
934                                                  NULL,
935                                                  NULL);
936         }
937         else
938         {
939             // No valid architecture was specified, ask the platform for
940             // the architectures that we should be using (in the correct order)
941             // and see if we can find a match that way
942             ModuleSpec arch_module_spec(module_spec);
943             for (uint32_t idx = 0; GetSupportedArchitectureAtIndex (idx, arch_module_spec.GetArchitecture()); ++idx)
944             {
945                 error = ModuleList::GetSharedModule (arch_module_spec,
946                                                      exe_module_sp,
947                                                      module_search_paths_ptr,
948                                                      NULL,
949                                                      NULL);
950                 // Did we find an executable using one of the
951                 if (error.Success() && exe_module_sp)
952                     break;
953             }
954         }
955     }
956     else
957     {
958         error.SetErrorStringWithFormat ("'%s' does not exist",
959                                         module_spec.GetFileSpec().GetPath().c_str());
960     }
961     return error;
962 }
963 
964 Error
965 Platform::ResolveSymbolFile (Target &target,
966                              const ModuleSpec &sym_spec,
967                              FileSpec &sym_file)
968 {
969     Error error;
970     if (sym_spec.GetSymbolFileSpec().Exists())
971         sym_file = sym_spec.GetSymbolFileSpec();
972     else
973         error.SetErrorString("unable to resolve symbol file");
974     return error;
975 
976 }
977 
978 
979 
980 bool
981 Platform::ResolveRemotePath (const FileSpec &platform_path,
982                              FileSpec &resolved_platform_path)
983 {
984     resolved_platform_path = platform_path;
985     return resolved_platform_path.ResolvePath();
986 }
987 
988 
989 const ArchSpec &
990 Platform::GetSystemArchitecture()
991 {
992     if (IsHost())
993     {
994         if (!m_system_arch.IsValid())
995         {
996             // We have a local host platform
997             m_system_arch = HostInfo::GetArchitecture();
998             m_system_arch_set_while_connected = m_system_arch.IsValid();
999         }
1000     }
1001     else
1002     {
1003         // We have a remote platform. We can only fetch the remote
1004         // system architecture if we are connected, and we don't want to do it
1005         // more than once.
1006 
1007         const bool is_connected = IsConnected();
1008 
1009         bool fetch = false;
1010         if (m_system_arch.IsValid())
1011         {
1012             // We have valid OS version info, check to make sure it wasn't
1013             // manually set prior to connecting. If it was manually set prior
1014             // to connecting, then lets fetch the actual OS version info
1015             // if we are now connected.
1016             if (is_connected && !m_system_arch_set_while_connected)
1017                 fetch = true;
1018         }
1019         else
1020         {
1021             // We don't have valid OS version info, fetch it if we are connected
1022             fetch = is_connected;
1023         }
1024 
1025         if (fetch)
1026         {
1027             m_system_arch = GetRemoteSystemArchitecture ();
1028             m_system_arch_set_while_connected = m_system_arch.IsValid();
1029         }
1030     }
1031     return m_system_arch;
1032 }
1033 
1034 
1035 Error
1036 Platform::ConnectRemote (Args& args)
1037 {
1038     Error error;
1039     if (IsHost())
1040         error.SetErrorStringWithFormat ("The currently selected platform (%s) is the host platform and is always connected.", GetPluginName().GetCString());
1041     else
1042         error.SetErrorStringWithFormat ("Platform::ConnectRemote() is not supported by %s", GetPluginName().GetCString());
1043     return error;
1044 }
1045 
1046 Error
1047 Platform::DisconnectRemote ()
1048 {
1049     Error error;
1050     if (IsHost())
1051         error.SetErrorStringWithFormat ("The currently selected platform (%s) is the host platform and is always connected.", GetPluginName().GetCString());
1052     else
1053         error.SetErrorStringWithFormat ("Platform::DisconnectRemote() is not supported by %s", GetPluginName().GetCString());
1054     return error;
1055 }
1056 
1057 bool
1058 Platform::GetProcessInfo (lldb::pid_t pid, ProcessInstanceInfo &process_info)
1059 {
1060     // Take care of the host case so that each subclass can just
1061     // call this function to get the host functionality.
1062     if (IsHost())
1063         return Host::GetProcessInfo (pid, process_info);
1064     return false;
1065 }
1066 
1067 uint32_t
1068 Platform::FindProcesses (const ProcessInstanceInfoMatch &match_info,
1069                          ProcessInstanceInfoList &process_infos)
1070 {
1071     // Take care of the host case so that each subclass can just
1072     // call this function to get the host functionality.
1073     uint32_t match_count = 0;
1074     if (IsHost())
1075         match_count = Host::FindProcesses (match_info, process_infos);
1076     return match_count;
1077 }
1078 
1079 
1080 Error
1081 Platform::LaunchProcess (ProcessLaunchInfo &launch_info)
1082 {
1083     Error error;
1084     Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_PLATFORM));
1085     if (log)
1086         log->Printf ("Platform::%s()", __FUNCTION__);
1087 
1088     // Take care of the host case so that each subclass can just
1089     // call this function to get the host functionality.
1090     if (IsHost())
1091     {
1092         if (::getenv ("LLDB_LAUNCH_FLAG_LAUNCH_IN_TTY"))
1093             launch_info.GetFlags().Set (eLaunchFlagLaunchInTTY);
1094 
1095         if (launch_info.GetFlags().Test (eLaunchFlagLaunchInShell))
1096         {
1097             const bool is_localhost = true;
1098             const bool will_debug = launch_info.GetFlags().Test(eLaunchFlagDebug);
1099             const bool first_arg_is_full_shell_command = false;
1100             uint32_t num_resumes = GetResumeCountForLaunchInfo (launch_info);
1101             if (log)
1102             {
1103                 const FileSpec &shell = launch_info.GetShell();
1104                 const char *shell_str = (shell) ? shell.GetPath().c_str() : "<null>";
1105                 log->Printf ("Platform::%s GetResumeCountForLaunchInfo() returned %" PRIu32 ", shell is '%s'",
1106                              __FUNCTION__,
1107                              num_resumes,
1108                              shell_str);
1109             }
1110 
1111             if (!launch_info.ConvertArgumentsForLaunchingInShell (error,
1112                                                                   is_localhost,
1113                                                                   will_debug,
1114                                                                   first_arg_is_full_shell_command,
1115                                                                   num_resumes))
1116                 return error;
1117         }
1118         else if (launch_info.GetFlags().Test(eLaunchFlagShellExpandArguments))
1119         {
1120             error = ShellExpandArguments(launch_info);
1121             if (error.Fail())
1122                 return error;
1123         }
1124 
1125         if (log)
1126             log->Printf ("Platform::%s final launch_info resume count: %" PRIu32, __FUNCTION__, launch_info.GetResumeCount ());
1127 
1128         error = Host::LaunchProcess (launch_info);
1129     }
1130     else
1131         error.SetErrorString ("base lldb_private::Platform class can't launch remote processes");
1132     return error;
1133 }
1134 
1135 Error
1136 Platform::ShellExpandArguments (ProcessLaunchInfo &launch_info)
1137 {
1138     if (IsHost())
1139         return Host::ShellExpandArguments(launch_info);
1140     return Error("base lldb_private::Platform class can't expand arguments");
1141 }
1142 
1143 Error
1144 Platform::KillProcess (const lldb::pid_t pid)
1145 {
1146     Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_PLATFORM));
1147     if (log)
1148         log->Printf ("Platform::%s, pid %" PRIu64, __FUNCTION__, pid);
1149 
1150     if (!IsHost ())
1151         return Error ("base lldb_private::Platform class can't launch remote processes");
1152 
1153     Host::Kill (pid, SIGTERM);
1154     return Error();
1155 }
1156 
1157 lldb::ProcessSP
1158 Platform::DebugProcess (ProcessLaunchInfo &launch_info,
1159                         Debugger &debugger,
1160                         Target *target,       // Can be NULL, if NULL create a new target, else use existing one
1161                         Error &error)
1162 {
1163     Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_PLATFORM));
1164     if (log)
1165         log->Printf ("Platform::%s entered (target %p)", __FUNCTION__, static_cast<void*>(target));
1166 
1167     ProcessSP process_sp;
1168     // Make sure we stop at the entry point
1169     launch_info.GetFlags ().Set (eLaunchFlagDebug);
1170     // We always launch the process we are going to debug in a separate process
1171     // group, since then we can handle ^C interrupts ourselves w/o having to worry
1172     // about the target getting them as well.
1173     launch_info.SetLaunchInSeparateProcessGroup(true);
1174 
1175     error = LaunchProcess (launch_info);
1176     if (error.Success())
1177     {
1178         if (log)
1179             log->Printf ("Platform::%s LaunchProcess() call succeeded (pid=%" PRIu64 ")", __FUNCTION__, launch_info.GetProcessID ());
1180         if (launch_info.GetProcessID() != LLDB_INVALID_PROCESS_ID)
1181         {
1182             ProcessAttachInfo attach_info (launch_info);
1183             process_sp = Attach (attach_info, debugger, target, error);
1184             if (process_sp)
1185             {
1186                 if (log)
1187                     log->Printf ("Platform::%s Attach() succeeded, Process plugin: %s", __FUNCTION__, process_sp->GetPluginName ().AsCString ());
1188                 launch_info.SetHijackListener(attach_info.GetHijackListener());
1189 
1190                 // Since we attached to the process, it will think it needs to detach
1191                 // if the process object just goes away without an explicit call to
1192                 // Process::Kill() or Process::Detach(), so let it know to kill the
1193                 // process if this happens.
1194                 process_sp->SetShouldDetach (false);
1195 
1196                 // If we didn't have any file actions, the pseudo terminal might
1197                 // have been used where the slave side was given as the file to
1198                 // open for stdin/out/err after we have already opened the master
1199                 // so we can read/write stdin/out/err.
1200                 int pty_fd = launch_info.GetPTY().ReleaseMasterFileDescriptor();
1201                 if (pty_fd != lldb_utility::PseudoTerminal::invalid_fd)
1202                 {
1203                     process_sp->SetSTDIOFileDescriptor(pty_fd);
1204                 }
1205             }
1206             else
1207             {
1208                 if (log)
1209                     log->Printf ("Platform::%s Attach() failed: %s", __FUNCTION__, error.AsCString ());
1210             }
1211         }
1212         else
1213         {
1214             if (log)
1215                 log->Printf ("Platform::%s LaunchProcess() returned launch_info with invalid process id", __FUNCTION__);
1216         }
1217     }
1218     else
1219     {
1220         if (log)
1221             log->Printf ("Platform::%s LaunchProcess() failed: %s", __FUNCTION__, error.AsCString ());
1222     }
1223 
1224     return process_sp;
1225 }
1226 
1227 
1228 lldb::PlatformSP
1229 Platform::GetPlatformForArchitecture (const ArchSpec &arch, ArchSpec *platform_arch_ptr)
1230 {
1231     lldb::PlatformSP platform_sp;
1232     Error error;
1233     if (arch.IsValid())
1234         platform_sp = Platform::Create (arch, platform_arch_ptr, error);
1235     return platform_sp;
1236 }
1237 
1238 
1239 //------------------------------------------------------------------
1240 /// Lets a platform answer if it is compatible with a given
1241 /// architecture and the target triple contained within.
1242 //------------------------------------------------------------------
1243 bool
1244 Platform::IsCompatibleArchitecture (const ArchSpec &arch, bool exact_arch_match, ArchSpec *compatible_arch_ptr)
1245 {
1246     // If the architecture is invalid, we must answer true...
1247     if (arch.IsValid())
1248     {
1249         ArchSpec platform_arch;
1250         // Try for an exact architecture match first.
1251         if (exact_arch_match)
1252         {
1253             for (uint32_t arch_idx=0; GetSupportedArchitectureAtIndex (arch_idx, platform_arch); ++arch_idx)
1254             {
1255                 if (arch.IsExactMatch(platform_arch))
1256                 {
1257                     if (compatible_arch_ptr)
1258                         *compatible_arch_ptr = platform_arch;
1259                     return true;
1260                 }
1261             }
1262         }
1263         else
1264         {
1265             for (uint32_t arch_idx=0; GetSupportedArchitectureAtIndex (arch_idx, platform_arch); ++arch_idx)
1266             {
1267                 if (arch.IsCompatibleMatch(platform_arch))
1268                 {
1269                     if (compatible_arch_ptr)
1270                         *compatible_arch_ptr = platform_arch;
1271                     return true;
1272                 }
1273             }
1274         }
1275     }
1276     if (compatible_arch_ptr)
1277         compatible_arch_ptr->Clear();
1278     return false;
1279 }
1280 
1281 Error
1282 Platform::PutFile (const FileSpec& source,
1283                    const FileSpec& destination,
1284                    uint32_t uid,
1285                    uint32_t gid)
1286 {
1287     Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_PLATFORM));
1288     if (log)
1289         log->Printf("[PutFile] Using block by block transfer....\n");
1290 
1291     uint32_t source_open_options = File::eOpenOptionRead | File::eOpenOptionCloseOnExec;
1292     if (source.GetFileType() == FileSpec::eFileTypeSymbolicLink)
1293         source_open_options |= File::eOpenoptionDontFollowSymlinks;
1294 
1295     File source_file(source, source_open_options, lldb::eFilePermissionsUserRW);
1296     Error error;
1297     uint32_t permissions = source_file.GetPermissions(error);
1298     if (permissions == 0)
1299         permissions = lldb::eFilePermissionsFileDefault;
1300 
1301     if (!source_file.IsValid())
1302         return Error("PutFile: unable to open source file");
1303     lldb::user_id_t dest_file = OpenFile (destination,
1304                                           File::eOpenOptionCanCreate |
1305                                           File::eOpenOptionWrite |
1306                                           File::eOpenOptionTruncate |
1307                                           File::eOpenOptionCloseOnExec,
1308                                           permissions,
1309                                           error);
1310     if (log)
1311         log->Printf ("dest_file = %" PRIu64 "\n", dest_file);
1312 
1313     if (error.Fail())
1314         return error;
1315     if (dest_file == UINT64_MAX)
1316         return Error("unable to open target file");
1317     lldb::DataBufferSP buffer_sp(new DataBufferHeap(1024, 0));
1318     uint64_t offset = 0;
1319     for (;;)
1320     {
1321         size_t bytes_read = buffer_sp->GetByteSize();
1322         error = source_file.Read(buffer_sp->GetBytes(), bytes_read);
1323         if (error.Fail() || bytes_read == 0)
1324             break;
1325 
1326         const uint64_t bytes_written = WriteFile(dest_file, offset,
1327             buffer_sp->GetBytes(), bytes_read, error);
1328         if (error.Fail())
1329             break;
1330 
1331         offset += bytes_written;
1332         if (bytes_written != bytes_read)
1333         {
1334             // We didn't write the correct number of bytes, so adjust
1335             // the file position in the source file we are reading from...
1336             source_file.SeekFromStart(offset);
1337         }
1338     }
1339     CloseFile(dest_file, error);
1340 
1341     if (uid == UINT32_MAX && gid == UINT32_MAX)
1342         return error;
1343 
1344     // TODO: ChownFile?
1345 
1346     return error;
1347 }
1348 
1349 Error
1350 Platform::GetFile (const FileSpec& source,
1351                    const FileSpec& destination)
1352 {
1353     Error error("unimplemented");
1354     return error;
1355 }
1356 
1357 Error
1358 Platform::CreateSymlink (const char *src, // The name of the link is in src
1359                          const char *dst)// The symlink points to dst
1360 {
1361     Error error("unimplemented");
1362     return error;
1363 }
1364 
1365 bool
1366 Platform::GetFileExists (const lldb_private::FileSpec& file_spec)
1367 {
1368     return false;
1369 }
1370 
1371 Error
1372 Platform::Unlink (const char *path)
1373 {
1374     Error error("unimplemented");
1375     return error;
1376 }
1377 
1378 
1379 
1380 lldb_private::Error
1381 Platform::RunShellCommand (const char *command,           // Shouldn't be NULL
1382                            const char *working_dir,       // Pass NULL to use the current working directory
1383                            int *status_ptr,               // Pass NULL if you don't want the process exit status
1384                            int *signo_ptr,                // Pass NULL if you don't want the signal that caused the process to exit
1385                            std::string *command_output,   // Pass NULL if you don't want the command output
1386                            uint32_t timeout_sec)          // Timeout in seconds to wait for shell program to finish
1387 {
1388     if (IsHost())
1389         return Host::RunShellCommand (command, working_dir, status_ptr, signo_ptr, command_output, timeout_sec);
1390     else
1391         return Error("unimplemented");
1392 }
1393 
1394 
1395 bool
1396 Platform::CalculateMD5 (const FileSpec& file_spec,
1397                         uint64_t &low,
1398                         uint64_t &high)
1399 {
1400     if (IsHost())
1401         return FileSystem::CalculateMD5(file_spec, low, high);
1402     else
1403         return false;
1404 }
1405 
1406 Error
1407 Platform::LaunchNativeProcess (
1408     ProcessLaunchInfo &launch_info,
1409     lldb_private::NativeProcessProtocol::NativeDelegate &native_delegate,
1410     NativeProcessProtocolSP &process_sp)
1411 {
1412     // Platforms should override this implementation if they want to
1413     // support lldb-gdbserver.
1414     return Error("unimplemented");
1415 }
1416 
1417 Error
1418 Platform::AttachNativeProcess (lldb::pid_t pid,
1419                                lldb_private::NativeProcessProtocol::NativeDelegate &native_delegate,
1420                                NativeProcessProtocolSP &process_sp)
1421 {
1422     // Platforms should override this implementation if they want to
1423     // support lldb-gdbserver.
1424     return Error("unimplemented");
1425 }
1426 
1427 void
1428 Platform::SetLocalCacheDirectory (const char* local)
1429 {
1430     m_local_cache_directory.assign(local);
1431 }
1432 
1433 const char*
1434 Platform::GetLocalCacheDirectory ()
1435 {
1436     return m_local_cache_directory.c_str();
1437 }
1438 
1439 static OptionDefinition
1440 g_rsync_option_table[] =
1441 {
1442     {   LLDB_OPT_SET_ALL, false, "rsync"                  , 'r', OptionParser::eNoArgument,       NULL, NULL, 0, eArgTypeNone         , "Enable rsync." },
1443     {   LLDB_OPT_SET_ALL, false, "rsync-opts"             , 'R', OptionParser::eRequiredArgument, NULL, NULL, 0, eArgTypeCommandName  , "Platform-specific options required for rsync to work." },
1444     {   LLDB_OPT_SET_ALL, false, "rsync-prefix"           , 'P', OptionParser::eRequiredArgument, NULL, NULL, 0, eArgTypeCommandName  , "Platform-specific rsync prefix put before the remote path." },
1445     {   LLDB_OPT_SET_ALL, false, "ignore-remote-hostname" , 'i', OptionParser::eNoArgument,       NULL, NULL, 0, eArgTypeNone         , "Do not automatically fill in the remote hostname when composing the rsync command." },
1446 };
1447 
1448 static OptionDefinition
1449 g_ssh_option_table[] =
1450 {
1451     {   LLDB_OPT_SET_ALL, false, "ssh"                    , 's', OptionParser::eNoArgument,       NULL, NULL, 0, eArgTypeNone         , "Enable SSH." },
1452     {   LLDB_OPT_SET_ALL, false, "ssh-opts"               , 'S', OptionParser::eRequiredArgument, NULL, NULL, 0, eArgTypeCommandName  , "Platform-specific options required for SSH to work." },
1453 };
1454 
1455 static OptionDefinition
1456 g_caching_option_table[] =
1457 {
1458     {   LLDB_OPT_SET_ALL, false, "local-cache-dir"        , 'c', OptionParser::eRequiredArgument, NULL, NULL, 0, eArgTypePath         , "Path in which to store local copies of files." },
1459 };
1460 
1461 OptionGroupPlatformRSync::OptionGroupPlatformRSync ()
1462 {
1463 }
1464 
1465 OptionGroupPlatformRSync::~OptionGroupPlatformRSync ()
1466 {
1467 }
1468 
1469 const lldb_private::OptionDefinition*
1470 OptionGroupPlatformRSync::GetDefinitions ()
1471 {
1472     return g_rsync_option_table;
1473 }
1474 
1475 void
1476 OptionGroupPlatformRSync::OptionParsingStarting (CommandInterpreter &interpreter)
1477 {
1478     m_rsync = false;
1479     m_rsync_opts.clear();
1480     m_rsync_prefix.clear();
1481     m_ignores_remote_hostname = false;
1482 }
1483 
1484 lldb_private::Error
1485 OptionGroupPlatformRSync::SetOptionValue (CommandInterpreter &interpreter,
1486                 uint32_t option_idx,
1487                 const char *option_arg)
1488 {
1489     Error error;
1490     char short_option = (char) GetDefinitions()[option_idx].short_option;
1491     switch (short_option)
1492     {
1493         case 'r':
1494             m_rsync = true;
1495             break;
1496 
1497         case 'R':
1498             m_rsync_opts.assign(option_arg);
1499             break;
1500 
1501         case 'P':
1502             m_rsync_prefix.assign(option_arg);
1503             break;
1504 
1505         case 'i':
1506             m_ignores_remote_hostname = true;
1507             break;
1508 
1509         default:
1510             error.SetErrorStringWithFormat ("unrecognized option '%c'", short_option);
1511             break;
1512     }
1513 
1514     return error;
1515 }
1516 
1517 uint32_t
1518 OptionGroupPlatformRSync::GetNumDefinitions ()
1519 {
1520     return llvm::array_lengthof(g_rsync_option_table);
1521 }
1522 
1523 lldb::BreakpointSP
1524 Platform::SetThreadCreationBreakpoint (lldb_private::Target &target)
1525 {
1526     return lldb::BreakpointSP();
1527 }
1528 
1529 OptionGroupPlatformSSH::OptionGroupPlatformSSH ()
1530 {
1531 }
1532 
1533 OptionGroupPlatformSSH::~OptionGroupPlatformSSH ()
1534 {
1535 }
1536 
1537 const lldb_private::OptionDefinition*
1538 OptionGroupPlatformSSH::GetDefinitions ()
1539 {
1540     return g_ssh_option_table;
1541 }
1542 
1543 void
1544 OptionGroupPlatformSSH::OptionParsingStarting (CommandInterpreter &interpreter)
1545 {
1546     m_ssh = false;
1547     m_ssh_opts.clear();
1548 }
1549 
1550 lldb_private::Error
1551 OptionGroupPlatformSSH::SetOptionValue (CommandInterpreter &interpreter,
1552                                           uint32_t option_idx,
1553                                           const char *option_arg)
1554 {
1555     Error error;
1556     char short_option = (char) GetDefinitions()[option_idx].short_option;
1557     switch (short_option)
1558     {
1559         case 's':
1560             m_ssh = true;
1561             break;
1562 
1563         case 'S':
1564             m_ssh_opts.assign(option_arg);
1565             break;
1566 
1567         default:
1568             error.SetErrorStringWithFormat ("unrecognized option '%c'", short_option);
1569             break;
1570     }
1571 
1572     return error;
1573 }
1574 
1575 uint32_t
1576 OptionGroupPlatformSSH::GetNumDefinitions ()
1577 {
1578     return llvm::array_lengthof(g_ssh_option_table);
1579 }
1580 
1581 OptionGroupPlatformCaching::OptionGroupPlatformCaching ()
1582 {
1583 }
1584 
1585 OptionGroupPlatformCaching::~OptionGroupPlatformCaching ()
1586 {
1587 }
1588 
1589 const lldb_private::OptionDefinition*
1590 OptionGroupPlatformCaching::GetDefinitions ()
1591 {
1592     return g_caching_option_table;
1593 }
1594 
1595 void
1596 OptionGroupPlatformCaching::OptionParsingStarting (CommandInterpreter &interpreter)
1597 {
1598     m_cache_dir.clear();
1599 }
1600 
1601 lldb_private::Error
1602 OptionGroupPlatformCaching::SetOptionValue (CommandInterpreter &interpreter,
1603                                         uint32_t option_idx,
1604                                         const char *option_arg)
1605 {
1606     Error error;
1607     char short_option = (char) GetDefinitions()[option_idx].short_option;
1608     switch (short_option)
1609     {
1610         case 'c':
1611             m_cache_dir.assign(option_arg);
1612             break;
1613 
1614         default:
1615             error.SetErrorStringWithFormat ("unrecognized option '%c'", short_option);
1616             break;
1617     }
1618 
1619     return error;
1620 }
1621 
1622 uint32_t
1623 OptionGroupPlatformCaching::GetNumDefinitions ()
1624 {
1625     return llvm::array_lengthof(g_caching_option_table);
1626 }
1627 
1628 size_t
1629 Platform::GetEnvironment (StringList &environment)
1630 {
1631     environment.Clear();
1632     return false;
1633 }
1634 
1635 const std::vector<ConstString> &
1636 Platform::GetTrapHandlerSymbolNames ()
1637 {
1638     if (!m_calculated_trap_handlers)
1639     {
1640         Mutex::Locker locker (m_mutex);
1641         if (!m_calculated_trap_handlers)
1642         {
1643             CalculateTrapHandlerSymbolNames();
1644             m_calculated_trap_handlers = true;
1645         }
1646     }
1647     return m_trap_handlers;
1648 }
1649 
1650