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