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         strm.Printf("    Triple: %s\n", arch.GetTriple().str().c_str());
479     }
480 
481     if (GetOSVersion(major, minor, update))
482     {
483         strm.Printf("OS Version: %u", major);
484         if (minor != UINT32_MAX)
485             strm.Printf(".%u", minor);
486         if (update != UINT32_MAX)
487             strm.Printf(".%u", update);
488 
489         if (GetOSBuildString (s))
490             strm.Printf(" (%s)", s.c_str());
491 
492         strm.EOL();
493     }
494 
495     if (GetOSKernelDescription (s))
496         strm.Printf("    Kernel: %s\n", s.c_str());
497 
498     if (IsHost())
499     {
500         strm.Printf("  Hostname: %s\n", GetHostname());
501     }
502     else
503     {
504         const bool is_connected = IsConnected();
505         if (is_connected)
506             strm.Printf("  Hostname: %s\n", GetHostname());
507         strm.Printf(" Connected: %s\n", is_connected ? "yes" : "no");
508     }
509 
510     if (GetWorkingDirectory())
511     {
512         strm.Printf("WorkingDir: %s\n", GetWorkingDirectory().GetCString());
513     }
514     if (!IsConnected())
515         return;
516 
517     std::string specific_info(GetPlatformSpecificConnectionInformation());
518 
519     if (specific_info.empty() == false)
520         strm.Printf("Platform-specific connection: %s\n", specific_info.c_str());
521 }
522 
523 
524 bool
525 Platform::GetOSVersion (uint32_t &major,
526                         uint32_t &minor,
527                         uint32_t &update)
528 {
529     Mutex::Locker locker (m_mutex);
530 
531     bool success = m_major_os_version != UINT32_MAX;
532     if (IsHost())
533     {
534         if (!success)
535         {
536             // We have a local host platform
537             success = HostInfo::GetOSVersion(m_major_os_version, m_minor_os_version, m_update_os_version);
538             m_os_version_set_while_connected = success;
539         }
540     }
541     else
542     {
543         // We have a remote platform. We can only fetch the remote
544         // OS version if we are connected, and we don't want to do it
545         // more than once.
546 
547         const bool is_connected = IsConnected();
548 
549         bool fetch = false;
550         if (success)
551         {
552             // We have valid OS version info, check to make sure it wasn't
553             // manually set prior to connecting. If it was manually set prior
554             // to connecting, then lets fetch the actual OS version info
555             // if we are now connected.
556             if (is_connected && !m_os_version_set_while_connected)
557                 fetch = true;
558         }
559         else
560         {
561             // We don't have valid OS version info, fetch it if we are connected
562             fetch = is_connected;
563         }
564 
565         if (fetch)
566         {
567             success = GetRemoteOSVersion ();
568             m_os_version_set_while_connected = success;
569         }
570     }
571 
572     if (success)
573     {
574         major = m_major_os_version;
575         minor = m_minor_os_version;
576         update = m_update_os_version;
577     }
578     return success;
579 }
580 
581 bool
582 Platform::GetOSBuildString (std::string &s)
583 {
584     s.clear();
585 
586     if (IsHost())
587 #if !defined(__linux__)
588         return HostInfo::GetOSBuildString(s);
589 #else
590         return false;
591 #endif
592     else
593         return GetRemoteOSBuildString (s);
594 }
595 
596 bool
597 Platform::GetOSKernelDescription (std::string &s)
598 {
599     if (IsHost())
600 #if !defined(__linux__)
601         return HostInfo::GetOSKernelDescription(s);
602 #else
603         return false;
604 #endif
605     else
606         return GetRemoteOSKernelDescription (s);
607 }
608 
609 void
610 Platform::AddClangModuleCompilationOptions (Target *target, std::vector<std::string> &options)
611 {
612     std::vector<std::string> default_compilation_options =
613     {
614         "-x", "c++", "-Xclang", "-nostdsysteminc", "-Xclang", "-nostdsysteminc"
615     };
616 
617     options.insert(options.end(),
618                    default_compilation_options.begin(),
619                    default_compilation_options.end());
620 }
621 
622 
623 FileSpec
624 Platform::GetWorkingDirectory ()
625 {
626     if (IsHost())
627     {
628         char cwd[PATH_MAX];
629         if (getcwd(cwd, sizeof(cwd)))
630             return FileSpec{cwd, true};
631         else
632             return FileSpec{};
633     }
634     else
635     {
636         if (!m_working_dir)
637             m_working_dir = GetRemoteWorkingDirectory();
638         return m_working_dir;
639     }
640 }
641 
642 
643 struct RecurseCopyBaton
644 {
645     const FileSpec& dst;
646     Platform *platform_ptr;
647     Error error;
648 };
649 
650 
651 static FileSpec::EnumerateDirectoryResult
652 RecurseCopy_Callback (void *baton,
653                       FileSpec::FileType file_type,
654                       const FileSpec &src)
655 {
656     RecurseCopyBaton* rc_baton = (RecurseCopyBaton*)baton;
657     switch (file_type)
658     {
659         case FileSpec::eFileTypePipe:
660         case FileSpec::eFileTypeSocket:
661             // we have no way to copy pipes and sockets - ignore them and continue
662             return FileSpec::eEnumerateDirectoryResultNext;
663             break;
664 
665         case FileSpec::eFileTypeDirectory:
666             {
667                 // make the new directory and get in there
668                 FileSpec dst_dir = rc_baton->dst;
669                 if (!dst_dir.GetFilename())
670                     dst_dir.GetFilename() = src.GetLastPathComponent();
671                 Error error = rc_baton->platform_ptr->MakeDirectory(dst_dir, lldb::eFilePermissionsDirectoryDefault);
672                 if (error.Fail())
673                 {
674                     rc_baton->error.SetErrorStringWithFormat("unable to setup directory %s on remote end",
675                             dst_dir.GetCString());
676                     return FileSpec::eEnumerateDirectoryResultQuit; // got an error, bail out
677                 }
678 
679                 // now recurse
680                 std::string src_dir_path (src.GetPath());
681 
682                 // Make a filespec that only fills in the directory of a FileSpec so
683                 // when we enumerate we can quickly fill in the filename for dst copies
684                 FileSpec recurse_dst;
685                 recurse_dst.GetDirectory().SetCString(dst_dir.GetPath().c_str());
686                 RecurseCopyBaton rc_baton2 = { recurse_dst, rc_baton->platform_ptr, Error() };
687                 FileSpec::EnumerateDirectory(src_dir_path.c_str(), true, true, true, RecurseCopy_Callback, &rc_baton2);
688                 if (rc_baton2.error.Fail())
689                 {
690                     rc_baton->error.SetErrorString(rc_baton2.error.AsCString());
691                     return FileSpec::eEnumerateDirectoryResultQuit; // got an error, bail out
692                 }
693                 return FileSpec::eEnumerateDirectoryResultNext;
694             }
695             break;
696 
697         case FileSpec::eFileTypeSymbolicLink:
698             {
699                 // copy the file and keep going
700                 FileSpec dst_file = rc_baton->dst;
701                 if (!dst_file.GetFilename())
702                     dst_file.GetFilename() = src.GetFilename();
703 
704                 FileSpec src_resolved;
705 
706                 rc_baton->error = FileSystem::Readlink(src, src_resolved);
707 
708                 if (rc_baton->error.Fail())
709                     return FileSpec::eEnumerateDirectoryResultQuit; // got an error, bail out
710 
711                 rc_baton->error = rc_baton->platform_ptr->CreateSymlink(dst_file, src_resolved);
712 
713                 if (rc_baton->error.Fail())
714                     return FileSpec::eEnumerateDirectoryResultQuit; // got an error, bail out
715 
716                 return FileSpec::eEnumerateDirectoryResultNext;
717             }
718             break;
719         case FileSpec::eFileTypeRegular:
720             {
721                 // copy the file and keep going
722                 FileSpec dst_file = rc_baton->dst;
723                 if (!dst_file.GetFilename())
724                     dst_file.GetFilename() = src.GetFilename();
725                 Error err = rc_baton->platform_ptr->PutFile(src, dst_file);
726                 if (err.Fail())
727                 {
728                     rc_baton->error.SetErrorString(err.AsCString());
729                     return FileSpec::eEnumerateDirectoryResultQuit; // got an error, bail out
730                 }
731                 return FileSpec::eEnumerateDirectoryResultNext;
732             }
733             break;
734 
735         case FileSpec::eFileTypeInvalid:
736         case FileSpec::eFileTypeOther:
737         case FileSpec::eFileTypeUnknown:
738             rc_baton->error.SetErrorStringWithFormat("invalid file detected during copy: %s", src.GetPath().c_str());
739             return FileSpec::eEnumerateDirectoryResultQuit; // got an error, bail out
740             break;
741     }
742     llvm_unreachable("Unhandled FileSpec::FileType!");
743 }
744 
745 Error
746 Platform::Install (const FileSpec& src, const FileSpec& dst)
747 {
748     Error error;
749 
750     Log *log = GetLogIfAnyCategoriesSet(LIBLLDB_LOG_PLATFORM);
751     if (log)
752         log->Printf ("Platform::Install (src='%s', dst='%s')", src.GetPath().c_str(), dst.GetPath().c_str());
753     FileSpec fixed_dst(dst);
754 
755     if (!fixed_dst.GetFilename())
756         fixed_dst.GetFilename() = src.GetFilename();
757 
758     FileSpec working_dir = GetWorkingDirectory();
759 
760     if (dst)
761     {
762         if (dst.GetDirectory())
763         {
764             const char first_dst_dir_char = dst.GetDirectory().GetCString()[0];
765             if (first_dst_dir_char == '/' || first_dst_dir_char  == '\\')
766             {
767                 fixed_dst.GetDirectory() = dst.GetDirectory();
768             }
769             // If the fixed destination file doesn't have a directory yet,
770             // then we must have a relative path. We will resolve this relative
771             // path against the platform's working directory
772             if (!fixed_dst.GetDirectory())
773             {
774                 FileSpec relative_spec;
775                 std::string path;
776                 if (working_dir)
777                 {
778                     relative_spec = working_dir;
779                     relative_spec.AppendPathComponent(dst.GetPath());
780                     fixed_dst.GetDirectory() = relative_spec.GetDirectory();
781                 }
782                 else
783                 {
784                     error.SetErrorStringWithFormat("platform working directory must be valid for relative path '%s'", dst.GetPath().c_str());
785                     return error;
786                 }
787             }
788         }
789         else
790         {
791             if (working_dir)
792             {
793                 fixed_dst.GetDirectory().SetCString(working_dir.GetCString());
794             }
795             else
796             {
797                 error.SetErrorStringWithFormat("platform working directory must be valid for relative path '%s'", dst.GetPath().c_str());
798                 return error;
799             }
800         }
801     }
802     else
803     {
804         if (working_dir)
805         {
806             fixed_dst.GetDirectory().SetCString(working_dir.GetCString());
807         }
808         else
809         {
810             error.SetErrorStringWithFormat("platform working directory must be valid when destination directory is empty");
811             return error;
812         }
813     }
814 
815     if (log)
816         log->Printf ("Platform::Install (src='%s', dst='%s') fixed_dst='%s'", src.GetPath().c_str(), dst.GetPath().c_str(), fixed_dst.GetPath().c_str());
817 
818     if (GetSupportsRSync())
819     {
820         error = PutFile(src, dst);
821     }
822     else
823     {
824         switch (src.GetFileType())
825         {
826             case FileSpec::eFileTypeDirectory:
827                 {
828                     if (GetFileExists (fixed_dst))
829                         Unlink(fixed_dst);
830                     uint32_t permissions = src.GetPermissions();
831                     if (permissions == 0)
832                         permissions = eFilePermissionsDirectoryDefault;
833                     error = MakeDirectory(fixed_dst, permissions);
834                     if (error.Success())
835                     {
836                         // Make a filespec that only fills in the directory of a FileSpec so
837                         // when we enumerate we can quickly fill in the filename for dst copies
838                         FileSpec recurse_dst;
839                         recurse_dst.GetDirectory().SetCString(fixed_dst.GetCString());
840                         std::string src_dir_path (src.GetPath());
841                         RecurseCopyBaton baton = { recurse_dst, this, Error() };
842                         FileSpec::EnumerateDirectory(src_dir_path.c_str(), true, true, true, RecurseCopy_Callback, &baton);
843                         return baton.error;
844                     }
845                 }
846                 break;
847 
848             case FileSpec::eFileTypeRegular:
849                 if (GetFileExists (fixed_dst))
850                     Unlink(fixed_dst);
851                 error = PutFile(src, fixed_dst);
852                 break;
853 
854             case FileSpec::eFileTypeSymbolicLink:
855                 {
856                     if (GetFileExists (fixed_dst))
857                         Unlink(fixed_dst);
858                     FileSpec src_resolved;
859                     error = FileSystem::Readlink(src, src_resolved);
860                     if (error.Success())
861                         error = CreateSymlink(dst, src_resolved);
862                 }
863                 break;
864             case FileSpec::eFileTypePipe:
865                 error.SetErrorString("platform install doesn't handle pipes");
866                 break;
867             case FileSpec::eFileTypeSocket:
868                 error.SetErrorString("platform install doesn't handle sockets");
869                 break;
870             case FileSpec::eFileTypeInvalid:
871             case FileSpec::eFileTypeUnknown:
872             case FileSpec::eFileTypeOther:
873                 error.SetErrorString("platform install doesn't handle non file or directory items");
874                 break;
875         }
876     }
877     return error;
878 }
879 
880 bool
881 Platform::SetWorkingDirectory(const FileSpec &file_spec)
882 {
883     if (IsHost())
884     {
885         Log *log = GetLogIfAnyCategoriesSet(LIBLLDB_LOG_PLATFORM);
886         if (log)
887             log->Printf("Platform::SetWorkingDirectory('%s')",
888                     file_spec.GetCString());
889         if (file_spec)
890         {
891             if (::chdir(file_spec.GetCString()) == 0)
892                 return true;
893         }
894         return false;
895     }
896     else
897     {
898         m_working_dir.Clear();
899         return SetRemoteWorkingDirectory(file_spec);
900     }
901 }
902 
903 Error
904 Platform::MakeDirectory(const FileSpec &file_spec, uint32_t permissions)
905 {
906     if (IsHost())
907         return FileSystem::MakeDirectory(file_spec, permissions);
908     else
909     {
910         Error error;
911         error.SetErrorStringWithFormat("remote platform %s doesn't support %s", GetPluginName().GetCString(), __PRETTY_FUNCTION__);
912         return error;
913     }
914 }
915 
916 Error
917 Platform::GetFilePermissions(const FileSpec &file_spec, uint32_t &file_permissions)
918 {
919     if (IsHost())
920         return FileSystem::GetFilePermissions(file_spec, file_permissions);
921     else
922     {
923         Error error;
924         error.SetErrorStringWithFormat("remote platform %s doesn't support %s", GetPluginName().GetCString(), __PRETTY_FUNCTION__);
925         return error;
926     }
927 }
928 
929 Error
930 Platform::SetFilePermissions(const FileSpec &file_spec, uint32_t file_permissions)
931 {
932     if (IsHost())
933         return FileSystem::SetFilePermissions(file_spec, file_permissions);
934     else
935     {
936         Error error;
937         error.SetErrorStringWithFormat("remote platform %s doesn't support %s", GetPluginName().GetCString(), __PRETTY_FUNCTION__);
938         return error;
939     }
940 }
941 
942 ConstString
943 Platform::GetName ()
944 {
945     return GetPluginName();
946 }
947 
948 const char *
949 Platform::GetHostname ()
950 {
951     if (IsHost())
952         return "127.0.0.1";
953 
954     if (m_name.empty())
955         return NULL;
956     return m_name.c_str();
957 }
958 
959 ConstString
960 Platform::GetFullNameForDylib (ConstString basename)
961 {
962     return basename;
963 }
964 
965 bool
966 Platform::SetRemoteWorkingDirectory(const FileSpec &working_dir)
967 {
968     Log *log = GetLogIfAnyCategoriesSet(LIBLLDB_LOG_PLATFORM);
969     if (log)
970         log->Printf("Platform::SetRemoteWorkingDirectory('%s')",
971                 working_dir.GetCString());
972     m_working_dir = working_dir;
973     return true;
974 }
975 
976 const char *
977 Platform::GetUserName (uint32_t uid)
978 {
979 #if !defined(LLDB_DISABLE_POSIX)
980     const char *user_name = GetCachedUserName(uid);
981     if (user_name)
982         return user_name;
983     if (IsHost())
984     {
985         std::string name;
986         if (HostInfo::LookupUserName(uid, name))
987             return SetCachedUserName (uid, name.c_str(), name.size());
988     }
989 #endif
990     return NULL;
991 }
992 
993 const char *
994 Platform::GetGroupName (uint32_t gid)
995 {
996 #if !defined(LLDB_DISABLE_POSIX)
997     const char *group_name = GetCachedGroupName(gid);
998     if (group_name)
999         return group_name;
1000     if (IsHost())
1001     {
1002         std::string name;
1003         if (HostInfo::LookupGroupName(gid, name))
1004             return SetCachedGroupName (gid, name.c_str(), name.size());
1005     }
1006 #endif
1007     return NULL;
1008 }
1009 
1010 bool
1011 Platform::SetOSVersion (uint32_t major,
1012                         uint32_t minor,
1013                         uint32_t update)
1014 {
1015     if (IsHost())
1016     {
1017         // We don't need anyone setting the OS version for the host platform,
1018         // we should be able to figure it out by calling HostInfo::GetOSVersion(...).
1019         return false;
1020     }
1021     else
1022     {
1023         // We have a remote platform, allow setting the target OS version if
1024         // we aren't connected, since if we are connected, we should be able to
1025         // request the remote OS version from the connected platform.
1026         if (IsConnected())
1027             return false;
1028         else
1029         {
1030             // We aren't connected and we might want to set the OS version
1031             // ahead of time before we connect so we can peruse files and
1032             // use a local SDK or PDK cache of support files to disassemble
1033             // or do other things.
1034             m_major_os_version = major;
1035             m_minor_os_version = minor;
1036             m_update_os_version = update;
1037             return true;
1038         }
1039     }
1040     return false;
1041 }
1042 
1043 
1044 Error
1045 Platform::ResolveExecutable (const ModuleSpec &module_spec,
1046                              lldb::ModuleSP &exe_module_sp,
1047                              const FileSpecList *module_search_paths_ptr)
1048 {
1049     Error error;
1050     if (module_spec.GetFileSpec().Exists())
1051     {
1052         if (module_spec.GetArchitecture().IsValid())
1053         {
1054             error = ModuleList::GetSharedModule (module_spec,
1055                                                  exe_module_sp,
1056                                                  module_search_paths_ptr,
1057                                                  NULL,
1058                                                  NULL);
1059         }
1060         else
1061         {
1062             // No valid architecture was specified, ask the platform for
1063             // the architectures that we should be using (in the correct order)
1064             // and see if we can find a match that way
1065             ModuleSpec arch_module_spec(module_spec);
1066             for (uint32_t idx = 0; GetSupportedArchitectureAtIndex (idx, arch_module_spec.GetArchitecture()); ++idx)
1067             {
1068                 error = ModuleList::GetSharedModule (arch_module_spec,
1069                                                      exe_module_sp,
1070                                                      module_search_paths_ptr,
1071                                                      NULL,
1072                                                      NULL);
1073                 // Did we find an executable using one of the
1074                 if (error.Success() && exe_module_sp)
1075                     break;
1076             }
1077         }
1078     }
1079     else
1080     {
1081         error.SetErrorStringWithFormat ("'%s' does not exist",
1082                                         module_spec.GetFileSpec().GetPath().c_str());
1083     }
1084     return error;
1085 }
1086 
1087 Error
1088 Platform::ResolveSymbolFile (Target &target,
1089                              const ModuleSpec &sym_spec,
1090                              FileSpec &sym_file)
1091 {
1092     Error error;
1093     if (sym_spec.GetSymbolFileSpec().Exists())
1094         sym_file = sym_spec.GetSymbolFileSpec();
1095     else
1096         error.SetErrorString("unable to resolve symbol file");
1097     return error;
1098 
1099 }
1100 
1101 
1102 
1103 bool
1104 Platform::ResolveRemotePath (const FileSpec &platform_path,
1105                              FileSpec &resolved_platform_path)
1106 {
1107     resolved_platform_path = platform_path;
1108     return resolved_platform_path.ResolvePath();
1109 }
1110 
1111 
1112 const ArchSpec &
1113 Platform::GetSystemArchitecture()
1114 {
1115     if (IsHost())
1116     {
1117         if (!m_system_arch.IsValid())
1118         {
1119             // We have a local host platform
1120             m_system_arch = HostInfo::GetArchitecture();
1121             m_system_arch_set_while_connected = m_system_arch.IsValid();
1122         }
1123     }
1124     else
1125     {
1126         // We have a remote platform. We can only fetch the remote
1127         // system architecture if we are connected, and we don't want to do it
1128         // more than once.
1129 
1130         const bool is_connected = IsConnected();
1131 
1132         bool fetch = false;
1133         if (m_system_arch.IsValid())
1134         {
1135             // We have valid OS version info, check to make sure it wasn't
1136             // manually set prior to connecting. If it was manually set prior
1137             // to connecting, then lets fetch the actual OS version info
1138             // if we are now connected.
1139             if (is_connected && !m_system_arch_set_while_connected)
1140                 fetch = true;
1141         }
1142         else
1143         {
1144             // We don't have valid OS version info, fetch it if we are connected
1145             fetch = is_connected;
1146         }
1147 
1148         if (fetch)
1149         {
1150             m_system_arch = GetRemoteSystemArchitecture ();
1151             m_system_arch_set_while_connected = m_system_arch.IsValid();
1152         }
1153     }
1154     return m_system_arch;
1155 }
1156 
1157 
1158 Error
1159 Platform::ConnectRemote (Args& args)
1160 {
1161     Error error;
1162     if (IsHost())
1163         error.SetErrorStringWithFormat ("The currently selected platform (%s) is the host platform and is always connected.", GetPluginName().GetCString());
1164     else
1165         error.SetErrorStringWithFormat ("Platform::ConnectRemote() is not supported by %s", GetPluginName().GetCString());
1166     return error;
1167 }
1168 
1169 Error
1170 Platform::DisconnectRemote ()
1171 {
1172     Error error;
1173     if (IsHost())
1174         error.SetErrorStringWithFormat ("The currently selected platform (%s) is the host platform and is always connected.", GetPluginName().GetCString());
1175     else
1176         error.SetErrorStringWithFormat ("Platform::DisconnectRemote() is not supported by %s", GetPluginName().GetCString());
1177     return error;
1178 }
1179 
1180 bool
1181 Platform::GetProcessInfo (lldb::pid_t pid, ProcessInstanceInfo &process_info)
1182 {
1183     // Take care of the host case so that each subclass can just
1184     // call this function to get the host functionality.
1185     if (IsHost())
1186         return Host::GetProcessInfo (pid, process_info);
1187     return false;
1188 }
1189 
1190 uint32_t
1191 Platform::FindProcesses (const ProcessInstanceInfoMatch &match_info,
1192                          ProcessInstanceInfoList &process_infos)
1193 {
1194     // Take care of the host case so that each subclass can just
1195     // call this function to get the host functionality.
1196     uint32_t match_count = 0;
1197     if (IsHost())
1198         match_count = Host::FindProcesses (match_info, process_infos);
1199     return match_count;
1200 }
1201 
1202 
1203 Error
1204 Platform::LaunchProcess (ProcessLaunchInfo &launch_info)
1205 {
1206     Error error;
1207     Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_PLATFORM));
1208     if (log)
1209         log->Printf ("Platform::%s()", __FUNCTION__);
1210 
1211     // Take care of the host case so that each subclass can just
1212     // call this function to get the host functionality.
1213     if (IsHost())
1214     {
1215         if (::getenv ("LLDB_LAUNCH_FLAG_LAUNCH_IN_TTY"))
1216             launch_info.GetFlags().Set (eLaunchFlagLaunchInTTY);
1217 
1218         if (launch_info.GetFlags().Test (eLaunchFlagLaunchInShell))
1219         {
1220             const bool is_localhost = true;
1221             const bool will_debug = launch_info.GetFlags().Test(eLaunchFlagDebug);
1222             const bool first_arg_is_full_shell_command = false;
1223             uint32_t num_resumes = GetResumeCountForLaunchInfo (launch_info);
1224             if (log)
1225             {
1226                 const FileSpec &shell = launch_info.GetShell();
1227                 const char *shell_str = (shell) ? shell.GetPath().c_str() : "<null>";
1228                 log->Printf ("Platform::%s GetResumeCountForLaunchInfo() returned %" PRIu32 ", shell is '%s'",
1229                              __FUNCTION__,
1230                              num_resumes,
1231                              shell_str);
1232             }
1233 
1234             if (!launch_info.ConvertArgumentsForLaunchingInShell (error,
1235                                                                   is_localhost,
1236                                                                   will_debug,
1237                                                                   first_arg_is_full_shell_command,
1238                                                                   num_resumes))
1239                 return error;
1240         }
1241         else if (launch_info.GetFlags().Test(eLaunchFlagShellExpandArguments))
1242         {
1243             error = ShellExpandArguments(launch_info);
1244             if (error.Fail())
1245                 return error;
1246         }
1247 
1248         if (log)
1249             log->Printf ("Platform::%s final launch_info resume count: %" PRIu32, __FUNCTION__, launch_info.GetResumeCount ());
1250 
1251         error = Host::LaunchProcess (launch_info);
1252     }
1253     else
1254         error.SetErrorString ("base lldb_private::Platform class can't launch remote processes");
1255     return error;
1256 }
1257 
1258 Error
1259 Platform::ShellExpandArguments (ProcessLaunchInfo &launch_info)
1260 {
1261     if (IsHost())
1262         return Host::ShellExpandArguments(launch_info);
1263     return Error("base lldb_private::Platform class can't expand arguments");
1264 }
1265 
1266 Error
1267 Platform::KillProcess (const lldb::pid_t pid)
1268 {
1269     Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_PLATFORM));
1270     if (log)
1271         log->Printf ("Platform::%s, pid %" PRIu64, __FUNCTION__, pid);
1272 
1273     // Try to find a process plugin to handle this Kill request.  If we can't, fall back to
1274     // the default OS implementation.
1275     size_t num_debuggers = Debugger::GetNumDebuggers();
1276     for (size_t didx = 0; didx < num_debuggers; ++didx)
1277     {
1278         DebuggerSP debugger = Debugger::GetDebuggerAtIndex(didx);
1279         lldb_private::TargetList &targets = debugger->GetTargetList();
1280         for (int tidx = 0; tidx < targets.GetNumTargets(); ++tidx)
1281         {
1282             ProcessSP process = targets.GetTargetAtIndex(tidx)->GetProcessSP();
1283             if (process->GetID() == pid)
1284                 return process->Destroy(true);
1285         }
1286     }
1287 
1288     if (!IsHost())
1289     {
1290         return Error("base lldb_private::Platform class can't kill remote processes unless "
1291                      "they are controlled by a process plugin");
1292     }
1293     Host::Kill(pid, SIGTERM);
1294     return Error();
1295 }
1296 
1297 lldb::ProcessSP
1298 Platform::DebugProcess (ProcessLaunchInfo &launch_info,
1299                         Debugger &debugger,
1300                         Target *target,       // Can be NULL, if NULL create a new target, else use existing one
1301                         Error &error)
1302 {
1303     Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_PLATFORM));
1304     if (log)
1305         log->Printf ("Platform::%s entered (target %p)", __FUNCTION__, static_cast<void*>(target));
1306 
1307     ProcessSP process_sp;
1308     // Make sure we stop at the entry point
1309     launch_info.GetFlags ().Set (eLaunchFlagDebug);
1310     // We always launch the process we are going to debug in a separate process
1311     // group, since then we can handle ^C interrupts ourselves w/o having to worry
1312     // about the target getting them as well.
1313     launch_info.SetLaunchInSeparateProcessGroup(true);
1314 
1315     error = LaunchProcess (launch_info);
1316     if (error.Success())
1317     {
1318         if (log)
1319             log->Printf ("Platform::%s LaunchProcess() call succeeded (pid=%" PRIu64 ")", __FUNCTION__, launch_info.GetProcessID ());
1320         if (launch_info.GetProcessID() != LLDB_INVALID_PROCESS_ID)
1321         {
1322             ProcessAttachInfo attach_info (launch_info);
1323             process_sp = Attach (attach_info, debugger, target, error);
1324             if (process_sp)
1325             {
1326                 if (log)
1327                     log->Printf ("Platform::%s Attach() succeeded, Process plugin: %s", __FUNCTION__, process_sp->GetPluginName ().AsCString ());
1328                 launch_info.SetHijackListener(attach_info.GetHijackListener());
1329 
1330                 // Since we attached to the process, it will think it needs to detach
1331                 // if the process object just goes away without an explicit call to
1332                 // Process::Kill() or Process::Detach(), so let it know to kill the
1333                 // process if this happens.
1334                 process_sp->SetShouldDetach (false);
1335 
1336                 // If we didn't have any file actions, the pseudo terminal might
1337                 // have been used where the slave side was given as the file to
1338                 // open for stdin/out/err after we have already opened the master
1339                 // so we can read/write stdin/out/err.
1340                 int pty_fd = launch_info.GetPTY().ReleaseMasterFileDescriptor();
1341                 if (pty_fd != lldb_utility::PseudoTerminal::invalid_fd)
1342                 {
1343                     process_sp->SetSTDIOFileDescriptor(pty_fd);
1344                 }
1345             }
1346             else
1347             {
1348                 if (log)
1349                     log->Printf ("Platform::%s Attach() failed: %s", __FUNCTION__, error.AsCString ());
1350             }
1351         }
1352         else
1353         {
1354             if (log)
1355                 log->Printf ("Platform::%s LaunchProcess() returned launch_info with invalid process id", __FUNCTION__);
1356         }
1357     }
1358     else
1359     {
1360         if (log)
1361             log->Printf ("Platform::%s LaunchProcess() failed: %s", __FUNCTION__, error.AsCString ());
1362     }
1363 
1364     return process_sp;
1365 }
1366 
1367 
1368 lldb::PlatformSP
1369 Platform::GetPlatformForArchitecture (const ArchSpec &arch, ArchSpec *platform_arch_ptr)
1370 {
1371     lldb::PlatformSP platform_sp;
1372     Error error;
1373     if (arch.IsValid())
1374         platform_sp = Platform::Create (arch, platform_arch_ptr, error);
1375     return platform_sp;
1376 }
1377 
1378 
1379 //------------------------------------------------------------------
1380 /// Lets a platform answer if it is compatible with a given
1381 /// architecture and the target triple contained within.
1382 //------------------------------------------------------------------
1383 bool
1384 Platform::IsCompatibleArchitecture (const ArchSpec &arch, bool exact_arch_match, ArchSpec *compatible_arch_ptr)
1385 {
1386     // If the architecture is invalid, we must answer true...
1387     if (arch.IsValid())
1388     {
1389         ArchSpec platform_arch;
1390         // Try for an exact architecture match first.
1391         if (exact_arch_match)
1392         {
1393             for (uint32_t arch_idx=0; GetSupportedArchitectureAtIndex (arch_idx, platform_arch); ++arch_idx)
1394             {
1395                 if (arch.IsExactMatch(platform_arch))
1396                 {
1397                     if (compatible_arch_ptr)
1398                         *compatible_arch_ptr = platform_arch;
1399                     return true;
1400                 }
1401             }
1402         }
1403         else
1404         {
1405             for (uint32_t arch_idx=0; GetSupportedArchitectureAtIndex (arch_idx, platform_arch); ++arch_idx)
1406             {
1407                 if (arch.IsCompatibleMatch(platform_arch))
1408                 {
1409                     if (compatible_arch_ptr)
1410                         *compatible_arch_ptr = platform_arch;
1411                     return true;
1412                 }
1413             }
1414         }
1415     }
1416     if (compatible_arch_ptr)
1417         compatible_arch_ptr->Clear();
1418     return false;
1419 }
1420 
1421 Error
1422 Platform::PutFile (const FileSpec& source,
1423                    const FileSpec& destination,
1424                    uint32_t uid,
1425                    uint32_t gid)
1426 {
1427     Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_PLATFORM));
1428     if (log)
1429         log->Printf("[PutFile] Using block by block transfer....\n");
1430 
1431     uint32_t source_open_options = File::eOpenOptionRead | File::eOpenOptionCloseOnExec;
1432     if (source.GetFileType() == FileSpec::eFileTypeSymbolicLink)
1433         source_open_options |= File::eOpenoptionDontFollowSymlinks;
1434 
1435     File source_file(source, source_open_options, lldb::eFilePermissionsUserRW);
1436     Error error;
1437     uint32_t permissions = source_file.GetPermissions(error);
1438     if (permissions == 0)
1439         permissions = lldb::eFilePermissionsFileDefault;
1440 
1441     if (!source_file.IsValid())
1442         return Error("PutFile: unable to open source file");
1443     lldb::user_id_t dest_file = OpenFile (destination,
1444                                           File::eOpenOptionCanCreate |
1445                                           File::eOpenOptionWrite |
1446                                           File::eOpenOptionTruncate |
1447                                           File::eOpenOptionCloseOnExec,
1448                                           permissions,
1449                                           error);
1450     if (log)
1451         log->Printf ("dest_file = %" PRIu64 "\n", dest_file);
1452 
1453     if (error.Fail())
1454         return error;
1455     if (dest_file == UINT64_MAX)
1456         return Error("unable to open target file");
1457     lldb::DataBufferSP buffer_sp(new DataBufferHeap(1024, 0));
1458     uint64_t offset = 0;
1459     for (;;)
1460     {
1461         size_t bytes_read = buffer_sp->GetByteSize();
1462         error = source_file.Read(buffer_sp->GetBytes(), bytes_read);
1463         if (error.Fail() || bytes_read == 0)
1464             break;
1465 
1466         const uint64_t bytes_written = WriteFile(dest_file, offset,
1467             buffer_sp->GetBytes(), bytes_read, error);
1468         if (error.Fail())
1469             break;
1470 
1471         offset += bytes_written;
1472         if (bytes_written != bytes_read)
1473         {
1474             // We didn't write the correct number of bytes, so adjust
1475             // the file position in the source file we are reading from...
1476             source_file.SeekFromStart(offset);
1477         }
1478     }
1479     CloseFile(dest_file, error);
1480 
1481     if (uid == UINT32_MAX && gid == UINT32_MAX)
1482         return error;
1483 
1484     // TODO: ChownFile?
1485 
1486     return error;
1487 }
1488 
1489 Error
1490 Platform::GetFile(const FileSpec &source,
1491                   const FileSpec &destination)
1492 {
1493     Error error("unimplemented");
1494     return error;
1495 }
1496 
1497 Error
1498 Platform::CreateSymlink(const FileSpec &src, // The name of the link is in src
1499                         const FileSpec &dst) // The symlink points to dst
1500 {
1501     Error error("unimplemented");
1502     return error;
1503 }
1504 
1505 bool
1506 Platform::GetFileExists(const lldb_private::FileSpec &file_spec)
1507 {
1508     return false;
1509 }
1510 
1511 Error
1512 Platform::Unlink(const FileSpec &path)
1513 {
1514     Error error("unimplemented");
1515     return error;
1516 }
1517 
1518 uint64_t
1519 Platform::ConvertMmapFlagsToPlatform(const ArchSpec &arch, unsigned flags)
1520 {
1521     uint64_t flags_platform = 0;
1522     if (flags & eMmapFlagsPrivate)
1523         flags_platform |= MAP_PRIVATE;
1524     if (flags & eMmapFlagsAnon)
1525         flags_platform |= MAP_ANON;
1526     return flags_platform;
1527 }
1528 
1529 lldb_private::Error
1530 Platform::RunShellCommand(const char *command,           // Shouldn't be NULL
1531                           const FileSpec &working_dir,   // Pass empty FileSpec to use the current working directory
1532                           int *status_ptr,               // Pass NULL if you don't want the process exit status
1533                           int *signo_ptr,                // Pass NULL if you don't want the signal that caused the process to exit
1534                           std::string *command_output,   // Pass NULL if you don't want the command output
1535                           uint32_t timeout_sec)          // Timeout in seconds to wait for shell program to finish
1536 {
1537     if (IsHost())
1538         return Host::RunShellCommand (command, working_dir, status_ptr, signo_ptr, command_output, timeout_sec);
1539     else
1540         return Error("unimplemented");
1541 }
1542 
1543 
1544 bool
1545 Platform::CalculateMD5 (const FileSpec& file_spec,
1546                         uint64_t &low,
1547                         uint64_t &high)
1548 {
1549     if (IsHost())
1550         return FileSystem::CalculateMD5(file_spec, low, high);
1551     else
1552         return false;
1553 }
1554 
1555 void
1556 Platform::SetLocalCacheDirectory (const char* local)
1557 {
1558     m_local_cache_directory.assign(local);
1559 }
1560 
1561 const char*
1562 Platform::GetLocalCacheDirectory ()
1563 {
1564     return m_local_cache_directory.c_str();
1565 }
1566 
1567 static OptionDefinition
1568 g_rsync_option_table[] =
1569 {
1570     {   LLDB_OPT_SET_ALL, false, "rsync"                  , 'r', OptionParser::eNoArgument,       NULL, NULL, 0, eArgTypeNone         , "Enable rsync." },
1571     {   LLDB_OPT_SET_ALL, false, "rsync-opts"             , 'R', OptionParser::eRequiredArgument, NULL, NULL, 0, eArgTypeCommandName  , "Platform-specific options required for rsync to work." },
1572     {   LLDB_OPT_SET_ALL, false, "rsync-prefix"           , 'P', OptionParser::eRequiredArgument, NULL, NULL, 0, eArgTypeCommandName  , "Platform-specific rsync prefix put before the remote path." },
1573     {   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." },
1574 };
1575 
1576 static OptionDefinition
1577 g_ssh_option_table[] =
1578 {
1579     {   LLDB_OPT_SET_ALL, false, "ssh"                    , 's', OptionParser::eNoArgument,       NULL, NULL, 0, eArgTypeNone         , "Enable SSH." },
1580     {   LLDB_OPT_SET_ALL, false, "ssh-opts"               , 'S', OptionParser::eRequiredArgument, NULL, NULL, 0, eArgTypeCommandName  , "Platform-specific options required for SSH to work." },
1581 };
1582 
1583 static OptionDefinition
1584 g_caching_option_table[] =
1585 {
1586     {   LLDB_OPT_SET_ALL, false, "local-cache-dir"        , 'c', OptionParser::eRequiredArgument, NULL, NULL, 0, eArgTypePath         , "Path in which to store local copies of files." },
1587 };
1588 
1589 OptionGroupPlatformRSync::OptionGroupPlatformRSync ()
1590 {
1591 }
1592 
1593 OptionGroupPlatformRSync::~OptionGroupPlatformRSync ()
1594 {
1595 }
1596 
1597 const lldb_private::OptionDefinition*
1598 OptionGroupPlatformRSync::GetDefinitions ()
1599 {
1600     return g_rsync_option_table;
1601 }
1602 
1603 void
1604 OptionGroupPlatformRSync::OptionParsingStarting (CommandInterpreter &interpreter)
1605 {
1606     m_rsync = false;
1607     m_rsync_opts.clear();
1608     m_rsync_prefix.clear();
1609     m_ignores_remote_hostname = false;
1610 }
1611 
1612 lldb_private::Error
1613 OptionGroupPlatformRSync::SetOptionValue (CommandInterpreter &interpreter,
1614                 uint32_t option_idx,
1615                 const char *option_arg)
1616 {
1617     Error error;
1618     char short_option = (char) GetDefinitions()[option_idx].short_option;
1619     switch (short_option)
1620     {
1621         case 'r':
1622             m_rsync = true;
1623             break;
1624 
1625         case 'R':
1626             m_rsync_opts.assign(option_arg);
1627             break;
1628 
1629         case 'P':
1630             m_rsync_prefix.assign(option_arg);
1631             break;
1632 
1633         case 'i':
1634             m_ignores_remote_hostname = true;
1635             break;
1636 
1637         default:
1638             error.SetErrorStringWithFormat ("unrecognized option '%c'", short_option);
1639             break;
1640     }
1641 
1642     return error;
1643 }
1644 
1645 uint32_t
1646 OptionGroupPlatformRSync::GetNumDefinitions ()
1647 {
1648     return llvm::array_lengthof(g_rsync_option_table);
1649 }
1650 
1651 lldb::BreakpointSP
1652 Platform::SetThreadCreationBreakpoint (lldb_private::Target &target)
1653 {
1654     return lldb::BreakpointSP();
1655 }
1656 
1657 OptionGroupPlatformSSH::OptionGroupPlatformSSH ()
1658 {
1659 }
1660 
1661 OptionGroupPlatformSSH::~OptionGroupPlatformSSH ()
1662 {
1663 }
1664 
1665 const lldb_private::OptionDefinition*
1666 OptionGroupPlatformSSH::GetDefinitions ()
1667 {
1668     return g_ssh_option_table;
1669 }
1670 
1671 void
1672 OptionGroupPlatformSSH::OptionParsingStarting (CommandInterpreter &interpreter)
1673 {
1674     m_ssh = false;
1675     m_ssh_opts.clear();
1676 }
1677 
1678 lldb_private::Error
1679 OptionGroupPlatformSSH::SetOptionValue (CommandInterpreter &interpreter,
1680                                           uint32_t option_idx,
1681                                           const char *option_arg)
1682 {
1683     Error error;
1684     char short_option = (char) GetDefinitions()[option_idx].short_option;
1685     switch (short_option)
1686     {
1687         case 's':
1688             m_ssh = true;
1689             break;
1690 
1691         case 'S':
1692             m_ssh_opts.assign(option_arg);
1693             break;
1694 
1695         default:
1696             error.SetErrorStringWithFormat ("unrecognized option '%c'", short_option);
1697             break;
1698     }
1699 
1700     return error;
1701 }
1702 
1703 uint32_t
1704 OptionGroupPlatformSSH::GetNumDefinitions ()
1705 {
1706     return llvm::array_lengthof(g_ssh_option_table);
1707 }
1708 
1709 OptionGroupPlatformCaching::OptionGroupPlatformCaching ()
1710 {
1711 }
1712 
1713 OptionGroupPlatformCaching::~OptionGroupPlatformCaching ()
1714 {
1715 }
1716 
1717 const lldb_private::OptionDefinition*
1718 OptionGroupPlatformCaching::GetDefinitions ()
1719 {
1720     return g_caching_option_table;
1721 }
1722 
1723 void
1724 OptionGroupPlatformCaching::OptionParsingStarting (CommandInterpreter &interpreter)
1725 {
1726     m_cache_dir.clear();
1727 }
1728 
1729 lldb_private::Error
1730 OptionGroupPlatformCaching::SetOptionValue (CommandInterpreter &interpreter,
1731                                         uint32_t option_idx,
1732                                         const char *option_arg)
1733 {
1734     Error error;
1735     char short_option = (char) GetDefinitions()[option_idx].short_option;
1736     switch (short_option)
1737     {
1738         case 'c':
1739             m_cache_dir.assign(option_arg);
1740             break;
1741 
1742         default:
1743             error.SetErrorStringWithFormat ("unrecognized option '%c'", short_option);
1744             break;
1745     }
1746 
1747     return error;
1748 }
1749 
1750 uint32_t
1751 OptionGroupPlatformCaching::GetNumDefinitions ()
1752 {
1753     return llvm::array_lengthof(g_caching_option_table);
1754 }
1755 
1756 size_t
1757 Platform::GetEnvironment (StringList &environment)
1758 {
1759     environment.Clear();
1760     return false;
1761 }
1762 
1763 const std::vector<ConstString> &
1764 Platform::GetTrapHandlerSymbolNames ()
1765 {
1766     if (!m_calculated_trap_handlers)
1767     {
1768         Mutex::Locker locker (m_mutex);
1769         if (!m_calculated_trap_handlers)
1770         {
1771             CalculateTrapHandlerSymbolNames();
1772             m_calculated_trap_handlers = true;
1773         }
1774     }
1775     return m_trap_handlers;
1776 }
1777 
1778 Error
1779 Platform::GetCachedExecutable (ModuleSpec &module_spec,
1780                                lldb::ModuleSP &module_sp,
1781                                const FileSpecList *module_search_paths_ptr,
1782                                Platform &remote_platform)
1783 {
1784     const auto platform_spec = module_spec.GetFileSpec ();
1785     const auto error = LoadCachedExecutable (module_spec,
1786                                              module_sp,
1787                                              module_search_paths_ptr,
1788                                              remote_platform);
1789     if (error.Success ())
1790     {
1791         module_spec.GetFileSpec () = module_sp->GetFileSpec ();
1792         module_spec.GetPlatformFileSpec () = platform_spec;
1793     }
1794 
1795     return error;
1796 }
1797 
1798 Error
1799 Platform::LoadCachedExecutable (const ModuleSpec &module_spec,
1800                                 lldb::ModuleSP &module_sp,
1801                                 const FileSpecList *module_search_paths_ptr,
1802                                 Platform &remote_platform)
1803 {
1804     return GetRemoteSharedModule (module_spec,
1805                                   nullptr,
1806                                   module_sp,
1807                                   [&](const ModuleSpec &spec)
1808                                   {
1809                                       return remote_platform.ResolveExecutable (
1810                                           spec, module_sp, module_search_paths_ptr);
1811                                   },
1812                                   nullptr);
1813 }
1814 
1815 Error
1816 Platform::GetRemoteSharedModule (const ModuleSpec &module_spec,
1817                                  Process* process,
1818                                  lldb::ModuleSP &module_sp,
1819                                  const ModuleResolver &module_resolver,
1820                                  bool *did_create_ptr)
1821 {
1822     // Get module information from a target.
1823     ModuleSpec resolved_module_spec;
1824     bool got_module_spec = false;
1825     if (process)
1826     {
1827         // Try to get module information from the process
1828         if (process->GetModuleSpec (module_spec.GetFileSpec (), module_spec.GetArchitecture (), resolved_module_spec))
1829             got_module_spec = true;
1830     }
1831 
1832     if (!got_module_spec)
1833     {
1834         // Get module information from a target.
1835         if (!GetModuleSpec (module_spec.GetFileSpec (), module_spec.GetArchitecture (), resolved_module_spec))
1836             return module_resolver (module_spec);
1837     }
1838 
1839     // Trying to find a module by UUID on local file system.
1840     const auto error = module_resolver (resolved_module_spec);
1841     if (error.Fail ())
1842      {
1843           if (GetCachedSharedModule (resolved_module_spec, module_sp, did_create_ptr))
1844               return Error ();
1845      }
1846 
1847     return error;
1848 }
1849 
1850 bool
1851 Platform::GetCachedSharedModule (const ModuleSpec &module_spec,
1852                                  lldb::ModuleSP &module_sp,
1853                                  bool *did_create_ptr)
1854 {
1855     if (IsHost() ||
1856         !GetGlobalPlatformProperties ()->GetUseModuleCache () ||
1857         !GetGlobalPlatformProperties ()->GetModuleCacheDirectory ())
1858         return false;
1859 
1860     Log *log = GetLogIfAnyCategoriesSet (LIBLLDB_LOG_PLATFORM);
1861 
1862     // Check local cache for a module.
1863     auto error = m_module_cache->GetAndPut (
1864         GetModuleCacheRoot (),
1865         GetCacheHostname (),
1866         module_spec,
1867         [this](const ModuleSpec &module_spec, const FileSpec &tmp_download_file_spec)
1868         {
1869             return DownloadModuleSlice (module_spec.GetFileSpec (),
1870                                         module_spec.GetObjectOffset (),
1871                                         module_spec.GetObjectSize (),
1872                                         tmp_download_file_spec);
1873 
1874         },
1875         [this](const ModuleSP& module_sp, const FileSpec& tmp_download_file_spec)
1876         {
1877             return DownloadSymbolFile (module_sp, tmp_download_file_spec);
1878         },
1879         module_sp,
1880         did_create_ptr);
1881     if (error.Success ())
1882         return true;
1883 
1884     if (log)
1885         log->Printf("Platform::%s - module %s not found in local cache: %s",
1886                     __FUNCTION__, module_spec.GetUUID ().GetAsString ().c_str (), error.AsCString ());
1887     return false;
1888 }
1889 
1890 Error
1891 Platform::DownloadModuleSlice (const FileSpec& src_file_spec,
1892                                const uint64_t src_offset,
1893                                const uint64_t src_size,
1894                                const FileSpec& dst_file_spec)
1895 {
1896     Error error;
1897 
1898     std::ofstream dst (dst_file_spec.GetPath(), std::ios::out | std::ios::binary);
1899     if (!dst.is_open())
1900     {
1901         error.SetErrorStringWithFormat ("unable to open destination file: %s", dst_file_spec.GetPath ().c_str ());
1902         return error;
1903     }
1904 
1905     auto src_fd = OpenFile (src_file_spec,
1906                             File::eOpenOptionRead,
1907                             lldb::eFilePermissionsFileDefault,
1908                             error);
1909 
1910    if (error.Fail ())
1911    {
1912        error.SetErrorStringWithFormat ("unable to open source file: %s", error.AsCString ());
1913        return error;
1914    }
1915 
1916     std::vector<char> buffer (1024);
1917     auto offset = src_offset;
1918     uint64_t total_bytes_read = 0;
1919     while (total_bytes_read < src_size)
1920     {
1921         const auto to_read = std::min (static_cast<uint64_t>(buffer.size ()), src_size - total_bytes_read);
1922         const uint64_t n_read = ReadFile (src_fd, offset, &buffer[0], to_read, error);
1923         if (error.Fail ())
1924             break;
1925         if (n_read == 0)
1926         {
1927             error.SetErrorString ("read 0 bytes");
1928             break;
1929         }
1930         offset += n_read;
1931         total_bytes_read += n_read;
1932         dst.write (&buffer[0], n_read);
1933     }
1934 
1935     Error close_error;
1936     CloseFile (src_fd, close_error);  // Ignoring close error.
1937 
1938     return error;
1939 }
1940 
1941 Error
1942 Platform::DownloadSymbolFile (const lldb::ModuleSP& module_sp, const FileSpec& dst_file_spec)
1943 {
1944     return Error ("Symbol file downloading not supported by the default platform.");
1945 }
1946 
1947 FileSpec
1948 Platform::GetModuleCacheRoot ()
1949 {
1950     auto dir_spec = GetGlobalPlatformProperties ()->GetModuleCacheDirectory ();
1951     dir_spec.AppendPathComponent (GetName ().AsCString ());
1952     return dir_spec;
1953 }
1954 
1955 const char *
1956 Platform::GetCacheHostname ()
1957 {
1958     return GetHostname ();
1959 }
1960 
1961 const UnixSignalsSP &
1962 Platform::GetRemoteUnixSignals()
1963 {
1964     static const auto s_default_unix_signals_sp = std::make_shared<UnixSignals>();
1965     return s_default_unix_signals_sp;
1966 }
1967 
1968 const UnixSignalsSP &
1969 Platform::GetUnixSignals()
1970 {
1971     if (IsHost())
1972         return Host::GetUnixSignals();
1973     return GetRemoteUnixSignals();
1974 }
1975