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