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