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