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