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