1 //===-- Platform.cpp ------------------------------------------------------===//
3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4 // See https://llvm.org/LICENSE.txt for license information.
5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
7 //===----------------------------------------------------------------------===//
16 #include "lldb/Breakpoint/BreakpointIDList.h"
17 #include "lldb/Breakpoint/BreakpointLocation.h"
18 #include "lldb/Core/Debugger.h"
19 #include "lldb/Core/Module.h"
20 #include "lldb/Core/ModuleSpec.h"
21 #include "lldb/Core/PluginManager.h"
22 #include "lldb/Host/FileCache.h"
23 #include "lldb/Host/FileSystem.h"
24 #include "lldb/Host/Host.h"
25 #include "lldb/Host/HostInfo.h"
26 #include "lldb/Host/OptionParser.h"
27 #include "lldb/Interpreter/OptionValueFileSpec.h"
28 #include "lldb/Interpreter/OptionValueProperties.h"
29 #include "lldb/Interpreter/Property.h"
30 #include "lldb/Symbol/ObjectFile.h"
31 #include "lldb/Target/ModuleCache.h"
32 #include "lldb/Target/Platform.h"
33 #include "lldb/Target/Process.h"
34 #include "lldb/Target/Target.h"
35 #include "lldb/Target/UnixSignals.h"
36 #include "lldb/Utility/DataBufferHeap.h"
37 #include "lldb/Utility/FileSpec.h"
38 #include "lldb/Utility/LLDBLog.h"
39 #include "lldb/Utility/Log.h"
40 #include "lldb/Utility/Status.h"
41 #include "lldb/Utility/StructuredData.h"
42 #include "llvm/ADT/STLExtras.h"
43 #include "llvm/Support/FileSystem.h"
44 #include "llvm/Support/Path.h"
46 // Define these constants from POSIX mman.h rather than include the file so
47 // that they will be correct even when compiled on Linux.
49 #define MAP_ANON 0x1000
52 using namespace lldb_private
;
54 // Use a singleton function for g_local_platform_sp to avoid init constructors
55 // since LLDB is often part of a shared library
56 static PlatformSP
&GetHostPlatformSP() {
57 static PlatformSP g_platform_sp
;
61 const char *Platform::GetHostPlatformName() { return "host"; }
65 #define LLDB_PROPERTIES_platform
66 #include "TargetProperties.inc"
69 #define LLDB_PROPERTIES_platform
70 #include "TargetPropertiesEnum.inc"
75 llvm::StringRef
PlatformProperties::GetSettingName() {
76 static constexpr llvm::StringLiteral
g_setting_name("platform");
77 return g_setting_name
;
80 PlatformProperties::PlatformProperties() {
81 m_collection_sp
= std::make_shared
<OptionValueProperties
>(GetSettingName());
82 m_collection_sp
->Initialize(g_platform_properties
);
84 auto module_cache_dir
= GetModuleCacheDirectory();
88 llvm::SmallString
<64> user_home_dir
;
89 if (!FileSystem::Instance().GetHomeDirectory(user_home_dir
))
92 module_cache_dir
= FileSpec(user_home_dir
.c_str());
93 module_cache_dir
.AppendPathComponent(".lldb");
94 module_cache_dir
.AppendPathComponent("module_cache");
95 SetDefaultModuleCacheDirectory(module_cache_dir
);
96 SetModuleCacheDirectory(module_cache_dir
);
99 bool PlatformProperties::GetUseModuleCache() const {
100 const auto idx
= ePropertyUseModuleCache
;
101 return GetPropertyAtIndexAs
<bool>(
102 idx
, g_platform_properties
[idx
].default_uint_value
!= 0);
105 bool PlatformProperties::SetUseModuleCache(bool use_module_cache
) {
106 return SetPropertyAtIndex(ePropertyUseModuleCache
, use_module_cache
);
109 FileSpec
PlatformProperties::GetModuleCacheDirectory() const {
110 return GetPropertyAtIndexAs
<FileSpec
>(ePropertyModuleCacheDirectory
, {});
113 bool PlatformProperties::SetModuleCacheDirectory(const FileSpec
&dir_spec
) {
114 return m_collection_sp
->SetPropertyAtIndex(ePropertyModuleCacheDirectory
,
118 void PlatformProperties::SetDefaultModuleCacheDirectory(
119 const FileSpec
&dir_spec
) {
120 auto f_spec_opt
= m_collection_sp
->GetPropertyAtIndexAsOptionValueFileSpec(
121 ePropertyModuleCacheDirectory
);
123 f_spec_opt
->SetDefaultValue(dir_spec
);
126 /// Get the native host platform plug-in.
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.
132 /// This platform will be used as the default platform when launching
133 /// or attaching to processes unless another platform is specified.
134 PlatformSP
Platform::GetHostPlatform() { return GetHostPlatformSP(); }
136 void Platform::Initialize() {}
138 void Platform::Terminate() {}
140 PlatformProperties
&Platform::GetGlobalPlatformProperties() {
141 static PlatformProperties g_settings
;
145 void Platform::SetHostPlatform(const lldb::PlatformSP
&platform_sp
) {
146 // The native platform should use its static void Platform::Initialize()
147 // function to register itself as the native platform.
148 GetHostPlatformSP() = platform_sp
;
151 Status
Platform::GetFileWithUUID(const FileSpec
&platform_file
,
152 const UUID
*uuid_ptr
, FileSpec
&local_file
) {
153 // Default to the local case
154 local_file
= platform_file
;
159 Platform::LocateExecutableScriptingResources(Target
*target
, Module
&module
,
160 Stream
&feedback_stream
) {
161 return FileSpecList();
164 Status
Platform::GetSharedModule(
165 const ModuleSpec
&module_spec
, Process
*process
, ModuleSP
&module_sp
,
166 const FileSpecList
*module_search_paths_ptr
,
167 llvm::SmallVectorImpl
<lldb::ModuleSP
> *old_modules
, bool *did_create_ptr
) {
169 return ModuleList::GetSharedModule(module_spec
, module_sp
,
170 module_search_paths_ptr
, old_modules
,
171 did_create_ptr
, false);
173 // Module resolver lambda.
174 auto resolver
= [&](const ModuleSpec
&spec
) {
175 Status
error(eErrorTypeGeneric
);
176 ModuleSpec resolved_spec
;
177 // Check if we have sysroot set.
178 if (!m_sdk_sysroot
.empty()) {
179 // Prepend sysroot to module spec.
180 resolved_spec
= spec
;
181 resolved_spec
.GetFileSpec().PrependPathComponent(m_sdk_sysroot
);
182 // Try to get shared module with resolved spec.
183 error
= ModuleList::GetSharedModule(resolved_spec
, module_sp
,
184 module_search_paths_ptr
, old_modules
,
185 did_create_ptr
, false);
187 // If we don't have sysroot or it didn't work then
188 // try original module spec.
189 if (!error
.Success()) {
190 resolved_spec
= spec
;
191 error
= ModuleList::GetSharedModule(resolved_spec
, module_sp
,
192 module_search_paths_ptr
, old_modules
,
193 did_create_ptr
, false);
195 if (error
.Success() && module_sp
)
196 module_sp
->SetPlatformFileSpec(resolved_spec
.GetFileSpec());
200 return GetRemoteSharedModule(module_spec
, process
, module_sp
, resolver
,
204 bool Platform::GetModuleSpec(const FileSpec
&module_file_spec
,
205 const ArchSpec
&arch
, ModuleSpec
&module_spec
) {
206 ModuleSpecList module_specs
;
207 if (ObjectFile::GetModuleSpecifications(module_file_spec
, 0, 0,
211 ModuleSpec matched_module_spec
;
212 return module_specs
.FindMatchingModuleSpec(ModuleSpec(module_file_spec
, arch
),
216 PlatformSP
Platform::Create(llvm::StringRef name
) {
217 lldb::PlatformSP platform_sp
;
218 if (name
== GetHostPlatformName())
219 return GetHostPlatform();
221 if (PlatformCreateInstance create_callback
=
222 PluginManager::GetPlatformCreateCallbackForPluginName(name
))
223 return create_callback(true, nullptr);
227 ArchSpec
Platform::GetAugmentedArchSpec(Platform
*platform
, llvm::StringRef triple
) {
229 return platform
->GetAugmentedArchSpec(triple
);
230 return HostInfo::GetAugmentedArchSpec(triple
);
233 /// Default Constructor
234 Platform::Platform(bool is_host
)
235 : m_is_host(is_host
), m_os_version_set_while_connected(false),
236 m_system_arch_set_while_connected(false), m_max_uid_name_len(0),
237 m_max_gid_name_len(0), m_supports_rsync(false), m_rsync_opts(),
238 m_rsync_prefix(), m_supports_ssh(false), m_ssh_opts(),
239 m_ignores_remote_hostname(false), m_trap_handlers(),
240 m_calculated_trap_handlers(false),
241 m_module_cache(std::make_unique
<ModuleCache
>()) {
242 Log
*log
= GetLog(LLDBLog::Object
);
243 LLDB_LOGF(log
, "%p Platform::Platform()", static_cast<void *>(this));
246 Platform::~Platform() = default;
248 void Platform::GetStatus(Stream
&strm
) {
249 strm
.Format(" Platform: {0}\n", GetPluginName());
251 ArchSpec
arch(GetSystemArchitecture());
252 if (arch
.IsValid()) {
253 if (!arch
.GetTriple().str().empty()) {
254 strm
.Printf(" Triple: ");
255 arch
.DumpTriple(strm
.AsRawOstream());
260 llvm::VersionTuple os_version
= GetOSVersion();
261 if (!os_version
.empty()) {
262 strm
.Format("OS Version: {0}", os_version
.getAsString());
264 if (std::optional
<std::string
> s
= GetOSBuildString())
265 strm
.Format(" ({0})", *s
);
271 strm
.Printf(" Hostname: %s\n", GetHostname());
273 const bool is_connected
= IsConnected();
275 strm
.Printf(" Hostname: %s\n", GetHostname());
276 strm
.Printf(" Connected: %s\n", is_connected
? "yes" : "no");
279 if (const std::string
&sdk_root
= GetSDKRootDirectory(); !sdk_root
.empty())
280 strm
.Format(" Sysroot: {0}\n", sdk_root
);
282 if (GetWorkingDirectory()) {
283 strm
.Printf("WorkingDir: %s\n", GetWorkingDirectory().GetPath().c_str());
288 std::string
specific_info(GetPlatformSpecificConnectionInformation());
290 if (!specific_info
.empty())
291 strm
.Printf("Platform-specific connection: %s\n", specific_info
.c_str());
293 if (std::optional
<std::string
> s
= GetOSKernelDescription())
294 strm
.Format(" Kernel: {0}\n", *s
);
297 llvm::VersionTuple
Platform::GetOSVersion(Process
*process
) {
298 std::lock_guard
<std::mutex
> guard(m_mutex
);
301 if (m_os_version
.empty()) {
302 // We have a local host platform
303 m_os_version
= HostInfo::GetOSVersion();
304 m_os_version_set_while_connected
= !m_os_version
.empty();
307 // We have a remote platform. We can only fetch the remote
308 // OS version if we are connected, and we don't want to do it
311 const bool is_connected
= IsConnected();
314 if (!m_os_version
.empty()) {
315 // We have valid OS version info, check to make sure it wasn't manually
316 // set prior to connecting. If it was manually set prior to connecting,
317 // then lets fetch the actual OS version info if we are now connected.
318 if (is_connected
&& !m_os_version_set_while_connected
)
321 // We don't have valid OS version info, fetch it if we are connected
322 fetch
= is_connected
;
326 m_os_version_set_while_connected
= GetRemoteOSVersion();
329 if (!m_os_version
.empty())
332 // Check with the process in case it can answer the question if a process
334 return process
->GetHostOSVersion();
336 return llvm::VersionTuple();
339 std::optional
<std::string
> Platform::GetOSBuildString() {
341 return HostInfo::GetOSBuildString();
342 return GetRemoteOSBuildString();
345 std::optional
<std::string
> Platform::GetOSKernelDescription() {
347 return HostInfo::GetOSKernelDescription();
348 return GetRemoteOSKernelDescription();
351 void Platform::AddClangModuleCompilationOptions(
352 Target
*target
, std::vector
<std::string
> &options
) {
353 std::vector
<std::string
> default_compilation_options
= {
354 "-x", "c++", "-Xclang", "-nostdsysteminc", "-Xclang", "-nostdsysteminc"};
356 options
.insert(options
.end(), default_compilation_options
.begin(),
357 default_compilation_options
.end());
360 FileSpec
Platform::GetWorkingDirectory() {
362 llvm::SmallString
<64> cwd
;
363 if (llvm::sys::fs::current_path(cwd
))
366 FileSpec
file_spec(cwd
);
367 FileSystem::Instance().Resolve(file_spec
);
372 m_working_dir
= GetRemoteWorkingDirectory();
373 return m_working_dir
;
377 struct RecurseCopyBaton
{
379 Platform
*platform_ptr
;
383 static FileSystem::EnumerateDirectoryResult
384 RecurseCopy_Callback(void *baton
, llvm::sys::fs::file_type ft
,
385 llvm::StringRef path
) {
386 RecurseCopyBaton
*rc_baton
= (RecurseCopyBaton
*)baton
;
388 namespace fs
= llvm::sys::fs
;
390 case fs::file_type::fifo_file
:
391 case fs::file_type::socket_file
:
392 // we have no way to copy pipes and sockets - ignore them and continue
393 return FileSystem::eEnumerateDirectoryResultNext
;
396 case fs::file_type::directory_file
: {
397 // make the new directory and get in there
398 FileSpec dst_dir
= rc_baton
->dst
;
399 if (!dst_dir
.GetFilename())
400 dst_dir
.SetFilename(src
.GetFilename());
401 Status error
= rc_baton
->platform_ptr
->MakeDirectory(
402 dst_dir
, lldb::eFilePermissionsDirectoryDefault
);
404 rc_baton
->error
= Status::FromErrorStringWithFormatv(
405 "unable to setup directory {0} on remote end", dst_dir
.GetPath());
406 return FileSystem::eEnumerateDirectoryResultQuit
; // got an error, bail out
410 std::string
src_dir_path(src
.GetPath());
412 // Make a filespec that only fills in the directory of a FileSpec so when
413 // we enumerate we can quickly fill in the filename for dst copies
414 FileSpec recurse_dst
;
415 recurse_dst
.SetDirectory(dst_dir
.GetPathAsConstString());
416 RecurseCopyBaton rc_baton2
= {recurse_dst
, rc_baton
->platform_ptr
,
418 FileSystem::Instance().EnumerateDirectory(src_dir_path
, true, true, true,
419 RecurseCopy_Callback
, &rc_baton2
);
420 if (rc_baton2
.error
.Fail()) {
421 rc_baton
->error
= Status::FromErrorString(rc_baton2
.error
.AsCString());
422 return FileSystem::eEnumerateDirectoryResultQuit
; // got an error, bail out
424 return FileSystem::eEnumerateDirectoryResultNext
;
427 case fs::file_type::symlink_file
: {
428 // copy the file and keep going
429 FileSpec dst_file
= rc_baton
->dst
;
430 if (!dst_file
.GetFilename())
431 dst_file
.SetFilename(src
.GetFilename());
433 FileSpec src_resolved
;
435 rc_baton
->error
= FileSystem::Instance().Readlink(src
, src_resolved
);
437 if (rc_baton
->error
.Fail())
438 return FileSystem::eEnumerateDirectoryResultQuit
; // got an error, bail out
441 rc_baton
->platform_ptr
->CreateSymlink(dst_file
, src_resolved
);
443 if (rc_baton
->error
.Fail())
444 return FileSystem::eEnumerateDirectoryResultQuit
; // got an error, bail out
446 return FileSystem::eEnumerateDirectoryResultNext
;
449 case fs::file_type::regular_file
: {
450 // copy the file and keep going
451 FileSpec dst_file
= rc_baton
->dst
;
452 if (!dst_file
.GetFilename())
453 dst_file
.SetFilename(src
.GetFilename());
454 Status err
= rc_baton
->platform_ptr
->PutFile(src
, dst_file
);
456 rc_baton
->error
= Status::FromErrorString(err
.AsCString());
457 return FileSystem::eEnumerateDirectoryResultQuit
; // got an error, bail out
459 return FileSystem::eEnumerateDirectoryResultNext
;
463 rc_baton
->error
= Status::FromErrorStringWithFormat(
464 "invalid file detected during copy: %s", src
.GetPath().c_str());
465 return FileSystem::eEnumerateDirectoryResultQuit
; // got an error, bail out
468 llvm_unreachable("Unhandled file_type!");
471 Status
Platform::Install(const FileSpec
&src
, const FileSpec
&dst
) {
474 Log
*log
= GetLog(LLDBLog::Platform
);
475 LLDB_LOGF(log
, "Platform::Install (src='%s', dst='%s')",
476 src
.GetPath().c_str(), dst
.GetPath().c_str());
477 FileSpec
fixed_dst(dst
);
479 if (!fixed_dst
.GetFilename())
480 fixed_dst
.SetFilename(src
.GetFilename());
482 FileSpec working_dir
= GetWorkingDirectory();
485 if (dst
.GetDirectory()) {
486 const char first_dst_dir_char
= dst
.GetDirectory().GetCString()[0];
487 if (first_dst_dir_char
== '/' || first_dst_dir_char
== '\\') {
488 fixed_dst
.SetDirectory(dst
.GetDirectory());
490 // If the fixed destination file doesn't have a directory yet, then we
491 // must have a relative path. We will resolve this relative path against
492 // the platform's working directory
493 if (!fixed_dst
.GetDirectory()) {
494 FileSpec relative_spec
;
497 relative_spec
= working_dir
;
498 relative_spec
.AppendPathComponent(dst
.GetPath());
499 fixed_dst
.SetDirectory(relative_spec
.GetDirectory());
501 error
= Status::FromErrorStringWithFormat(
502 "platform working directory must be valid for relative path '%s'",
503 dst
.GetPath().c_str());
509 fixed_dst
.SetDirectory(working_dir
.GetPathAsConstString());
511 error
= Status::FromErrorStringWithFormat(
512 "platform working directory must be valid for relative path '%s'",
513 dst
.GetPath().c_str());
519 fixed_dst
.SetDirectory(working_dir
.GetPathAsConstString());
522 Status::FromErrorString("platform working directory must be valid "
523 "when destination directory is empty");
528 LLDB_LOGF(log
, "Platform::Install (src='%s', dst='%s') fixed_dst='%s'",
529 src
.GetPath().c_str(), dst
.GetPath().c_str(),
530 fixed_dst
.GetPath().c_str());
532 if (GetSupportsRSync()) {
533 error
= PutFile(src
, dst
);
535 namespace fs
= llvm::sys::fs
;
536 switch (fs::get_file_type(src
.GetPath(), false)) {
537 case fs::file_type::directory_file
: {
538 llvm::sys::fs::remove(fixed_dst
.GetPath());
539 uint32_t permissions
= FileSystem::Instance().GetPermissions(src
);
540 if (permissions
== 0)
541 permissions
= eFilePermissionsDirectoryDefault
;
542 error
= MakeDirectory(fixed_dst
, permissions
);
543 if (error
.Success()) {
544 // Make a filespec that only fills in the directory of a FileSpec so
545 // when we enumerate we can quickly fill in the filename for dst copies
546 FileSpec recurse_dst
;
547 recurse_dst
.SetDirectory(fixed_dst
.GetPathAsConstString());
548 std::string
src_dir_path(src
.GetPath());
549 RecurseCopyBaton baton
= {recurse_dst
, this, Status()};
550 FileSystem::Instance().EnumerateDirectory(
551 src_dir_path
, true, true, true, RecurseCopy_Callback
, &baton
);
552 return std::move(baton
.error
);
556 case fs::file_type::regular_file
:
557 llvm::sys::fs::remove(fixed_dst
.GetPath());
558 error
= PutFile(src
, fixed_dst
);
561 case fs::file_type::symlink_file
: {
562 llvm::sys::fs::remove(fixed_dst
.GetPath());
563 FileSpec src_resolved
;
564 error
= FileSystem::Instance().Readlink(src
, src_resolved
);
566 error
= CreateSymlink(dst
, src_resolved
);
568 case fs::file_type::fifo_file
:
569 error
= Status::FromErrorString("platform install doesn't handle pipes");
571 case fs::file_type::socket_file
:
573 Status::FromErrorString("platform install doesn't handle sockets");
576 error
= Status::FromErrorString(
577 "platform install doesn't handle non file or directory items");
584 bool Platform::SetWorkingDirectory(const FileSpec
&file_spec
) {
586 Log
*log
= GetLog(LLDBLog::Platform
);
587 LLDB_LOG(log
, "{0}", file_spec
);
588 if (std::error_code ec
= llvm::sys::fs::set_current_path(file_spec
.GetPath())) {
589 LLDB_LOG(log
, "error: {0}", ec
.message());
594 m_working_dir
.Clear();
595 return SetRemoteWorkingDirectory(file_spec
);
599 Status
Platform::MakeDirectory(const FileSpec
&file_spec
,
600 uint32_t permissions
) {
602 return llvm::sys::fs::create_directory(file_spec
.GetPath(), permissions
);
605 return Status::FromErrorStringWithFormatv(
606 "remote platform {0} doesn't support {1}", GetPluginName(),
607 LLVM_PRETTY_FUNCTION
);
612 Status
Platform::GetFilePermissions(const FileSpec
&file_spec
,
613 uint32_t &file_permissions
) {
615 auto Value
= llvm::sys::fs::getPermissions(file_spec
.GetPath());
617 file_permissions
= Value
.get();
618 return Status(Value
.getError());
621 return Status::FromErrorStringWithFormatv(
622 "remote platform {0} doesn't support {1}", GetPluginName(),
623 LLVM_PRETTY_FUNCTION
);
628 Status
Platform::SetFilePermissions(const FileSpec
&file_spec
,
629 uint32_t file_permissions
) {
631 auto Perms
= static_cast<llvm::sys::fs::perms
>(file_permissions
);
632 return llvm::sys::fs::setPermissions(file_spec
.GetPath(), Perms
);
635 return Status::FromErrorStringWithFormatv(
636 "remote platform {0} doesn't support {1}", GetPluginName(),
637 LLVM_PRETTY_FUNCTION
);
642 user_id_t
Platform::OpenFile(const FileSpec
&file_spec
,
643 File::OpenOptions flags
, uint32_t mode
,
646 return FileCache::GetInstance().OpenFile(file_spec
, flags
, mode
, error
);
650 bool Platform::CloseFile(user_id_t fd
, Status
&error
) {
652 return FileCache::GetInstance().CloseFile(fd
, error
);
656 user_id_t
Platform::GetFileSize(const FileSpec
&file_spec
) {
661 if (llvm::sys::fs::file_size(file_spec
.GetPath(), Size
))
666 uint64_t Platform::ReadFile(lldb::user_id_t fd
, uint64_t offset
, void *dst
,
667 uint64_t dst_len
, Status
&error
) {
669 return FileCache::GetInstance().ReadFile(fd
, offset
, dst
, dst_len
, error
);
670 error
= Status::FromErrorStringWithFormatv(
671 "Platform::ReadFile() is not supported in the {0} platform",
676 uint64_t Platform::WriteFile(lldb::user_id_t fd
, uint64_t offset
,
677 const void *src
, uint64_t src_len
, Status
&error
) {
679 return FileCache::GetInstance().WriteFile(fd
, offset
, src
, src_len
, error
);
680 error
= Status::FromErrorStringWithFormatv(
681 "Platform::WriteFile() is not supported in the {0} platform",
686 UserIDResolver
&Platform::GetUserIDResolver() {
688 return HostInfo::GetUserIDResolver();
689 return UserIDResolver::GetNoopResolver();
692 const char *Platform::GetHostname() {
696 if (m_hostname
.empty())
698 return m_hostname
.c_str();
701 ConstString
Platform::GetFullNameForDylib(ConstString basename
) {
705 bool Platform::SetRemoteWorkingDirectory(const FileSpec
&working_dir
) {
706 Log
*log
= GetLog(LLDBLog::Platform
);
707 LLDB_LOGF(log
, "Platform::SetRemoteWorkingDirectory('%s')",
708 working_dir
.GetPath().c_str());
709 m_working_dir
= working_dir
;
713 bool Platform::SetOSVersion(llvm::VersionTuple version
) {
715 // We don't need anyone setting the OS version for the host platform, we
716 // should be able to figure it out by calling HostInfo::GetOSVersion(...).
719 // We have a remote platform, allow setting the target OS version if we
720 // aren't connected, since if we are connected, we should be able to
721 // request the remote OS version from the connected platform.
725 // We aren't connected and we might want to set the OS version ahead of
726 // time before we connect so we can peruse files and use a local SDK or
727 // PDK cache of support files to disassemble or do other things.
728 m_os_version
= version
;
736 Platform::ResolveExecutable(const ModuleSpec
&module_spec
,
737 lldb::ModuleSP
&exe_module_sp
,
738 const FileSpecList
*module_search_paths_ptr
) {
740 // We may connect to a process and use the provided executable (Don't use
742 ModuleSpec
resolved_module_spec(module_spec
);
744 // Resolve any executable within a bundle on MacOSX
745 Host::ResolveExecutableInBundle(resolved_module_spec
.GetFileSpec());
747 if (!FileSystem::Instance().Exists(resolved_module_spec
.GetFileSpec()) &&
748 !module_spec
.GetUUID().IsValid())
749 return Status::FromErrorStringWithFormatv(
750 "'{0}' does not exist", resolved_module_spec
.GetFileSpec());
752 if (resolved_module_spec
.GetArchitecture().IsValid() ||
753 resolved_module_spec
.GetUUID().IsValid()) {
755 ModuleList::GetSharedModule(resolved_module_spec
, exe_module_sp
,
756 module_search_paths_ptr
, nullptr, nullptr);
758 if (exe_module_sp
&& exe_module_sp
->GetObjectFile())
760 exe_module_sp
.reset();
762 // No valid architecture was specified or the exact arch wasn't found.
763 // Ask the platform for the architectures that we should be using (in the
764 // correct order) and see if we can find a match that way.
765 StreamString arch_names
;
766 llvm::ListSeparator LS
;
767 ArchSpec process_host_arch
;
769 for (const ArchSpec
&arch
: GetSupportedArchitectures(process_host_arch
)) {
770 resolved_module_spec
.GetArchitecture() = arch
;
772 ModuleList::GetSharedModule(resolved_module_spec
, exe_module_sp
,
773 module_search_paths_ptr
, nullptr, nullptr);
774 if (error
.Success()) {
775 if (exe_module_sp
&& exe_module_sp
->GetObjectFile())
777 error
= Status::FromErrorString("no exe object file");
780 arch_names
<< LS
<< arch
.GetArchitectureName();
783 if (exe_module_sp
&& error
.Success())
786 if (!FileSystem::Instance().Readable(resolved_module_spec
.GetFileSpec()))
787 return Status::FromErrorStringWithFormatv(
788 "'{0}' is not readable", resolved_module_spec
.GetFileSpec());
790 if (!ObjectFile::IsObjectFile(resolved_module_spec
.GetFileSpec()))
791 return Status::FromErrorStringWithFormatv(
792 "'{0}' is not a valid executable", resolved_module_spec
.GetFileSpec());
794 return Status::FromErrorStringWithFormatv(
795 "'{0}' doesn't contain any '{1}' platform architectures: {2}",
796 resolved_module_spec
.GetFileSpec(), GetPluginName(),
797 arch_names
.GetData());
800 Status
Platform::ResolveSymbolFile(Target
&target
, const ModuleSpec
&sym_spec
,
801 FileSpec
&sym_file
) {
803 if (FileSystem::Instance().Exists(sym_spec
.GetSymbolFileSpec()))
804 sym_file
= sym_spec
.GetSymbolFileSpec();
806 error
= Status::FromErrorString("unable to resolve symbol file");
810 bool Platform::ResolveRemotePath(const FileSpec
&platform_path
,
811 FileSpec
&resolved_platform_path
) {
812 resolved_platform_path
= platform_path
;
813 FileSystem::Instance().Resolve(resolved_platform_path
);
817 const ArchSpec
&Platform::GetSystemArchitecture() {
819 if (!m_system_arch
.IsValid()) {
820 // We have a local host platform
821 m_system_arch
= HostInfo::GetArchitecture();
822 m_system_arch_set_while_connected
= m_system_arch
.IsValid();
825 // We have a remote platform. We can only fetch the remote system
826 // architecture if we are connected, and we don't want to do it more than
829 const bool is_connected
= IsConnected();
832 if (m_system_arch
.IsValid()) {
833 // We have valid OS version info, check to make sure it wasn't manually
834 // set prior to connecting. If it was manually set prior to connecting,
835 // then lets fetch the actual OS version info if we are now connected.
836 if (is_connected
&& !m_system_arch_set_while_connected
)
839 // We don't have valid OS version info, fetch it if we are connected
840 fetch
= is_connected
;
844 m_system_arch
= GetRemoteSystemArchitecture();
845 m_system_arch_set_while_connected
= m_system_arch
.IsValid();
848 return m_system_arch
;
851 ArchSpec
Platform::GetAugmentedArchSpec(llvm::StringRef triple
) {
854 llvm::Triple
normalized_triple(llvm::Triple::normalize(triple
));
855 if (!ArchSpec::ContainsOnlyArch(normalized_triple
))
856 return ArchSpec(triple
);
858 if (auto kind
= HostInfo::ParseArchitectureKind(triple
))
859 return HostInfo::GetArchitecture(*kind
);
861 ArchSpec compatible_arch
;
862 ArchSpec
raw_arch(triple
);
863 if (!IsCompatibleArchitecture(raw_arch
, {}, ArchSpec::CompatibleMatch
,
867 if (!compatible_arch
.IsValid())
868 return ArchSpec(normalized_triple
);
870 const llvm::Triple
&compatible_triple
= compatible_arch
.GetTriple();
871 if (normalized_triple
.getVendorName().empty())
872 normalized_triple
.setVendor(compatible_triple
.getVendor());
873 if (normalized_triple
.getOSName().empty())
874 normalized_triple
.setOS(compatible_triple
.getOS());
875 if (normalized_triple
.getEnvironmentName().empty())
876 normalized_triple
.setEnvironment(compatible_triple
.getEnvironment());
877 return ArchSpec(normalized_triple
);
880 Status
Platform::ConnectRemote(Args
&args
) {
883 return Status::FromErrorStringWithFormatv(
884 "The currently selected platform ({0}) is "
885 "the host platform and is always connected.",
888 return Status::FromErrorStringWithFormatv(
889 "Platform::ConnectRemote() is not supported by {0}", GetPluginName());
893 Status
Platform::DisconnectRemote() {
896 return Status::FromErrorStringWithFormatv(
897 "The currently selected platform ({0}) is "
898 "the host platform and is always connected.",
901 return Status::FromErrorStringWithFormatv(
902 "Platform::DisconnectRemote() is not supported by {0}",
907 bool Platform::GetProcessInfo(lldb::pid_t pid
,
908 ProcessInstanceInfo
&process_info
) {
909 // Take care of the host case so that each subclass can just call this
910 // function to get the host functionality.
912 return Host::GetProcessInfo(pid
, process_info
);
916 uint32_t Platform::FindProcesses(const ProcessInstanceInfoMatch
&match_info
,
917 ProcessInstanceInfoList
&process_infos
) {
918 // Take care of the host case so that each subclass can just call this
919 // function to get the host functionality.
920 uint32_t match_count
= 0;
922 match_count
= Host::FindProcesses(match_info
, process_infos
);
926 ProcessInstanceInfoList
Platform::GetAllProcesses() {
927 ProcessInstanceInfoList processes
;
928 ProcessInstanceInfoMatch match
;
929 assert(match
.MatchAllProcesses());
930 FindProcesses(match
, processes
);
934 Status
Platform::LaunchProcess(ProcessLaunchInfo
&launch_info
) {
936 Log
*log
= GetLog(LLDBLog::Platform
);
937 LLDB_LOGF(log
, "Platform::%s()", __FUNCTION__
);
939 // Take care of the host case so that each subclass can just call this
940 // function to get the host functionality.
942 if (::getenv("LLDB_LAUNCH_FLAG_LAUNCH_IN_TTY"))
943 launch_info
.GetFlags().Set(eLaunchFlagLaunchInTTY
);
945 if (launch_info
.GetFlags().Test(eLaunchFlagLaunchInShell
)) {
946 const bool will_debug
= launch_info
.GetFlags().Test(eLaunchFlagDebug
);
947 const bool first_arg_is_full_shell_command
= false;
948 uint32_t num_resumes
= GetResumeCountForLaunchInfo(launch_info
);
950 const FileSpec
&shell
= launch_info
.GetShell();
951 std::string shell_str
= (shell
) ? shell
.GetPath() : "<null>";
953 "Platform::%s GetResumeCountForLaunchInfo() returned %" PRIu32
955 __FUNCTION__
, num_resumes
, shell_str
.c_str());
958 if (!launch_info
.ConvertArgumentsForLaunchingInShell(
959 error
, will_debug
, first_arg_is_full_shell_command
, num_resumes
))
961 } else if (launch_info
.GetFlags().Test(eLaunchFlagShellExpandArguments
)) {
962 error
= ShellExpandArguments(launch_info
);
964 error
= Status::FromErrorStringWithFormat(
965 "shell expansion failed (reason: %s). "
966 "consider launching with 'process "
968 error
.AsCString("unknown"));
973 LLDB_LOGF(log
, "Platform::%s final launch_info resume count: %" PRIu32
,
974 __FUNCTION__
, launch_info
.GetResumeCount());
976 error
= Host::LaunchProcess(launch_info
);
978 error
= Status::FromErrorString(
979 "base lldb_private::Platform class can't launch remote processes");
983 Status
Platform::ShellExpandArguments(ProcessLaunchInfo
&launch_info
) {
985 return Host::ShellExpandArguments(launch_info
);
986 return Status::FromErrorString(
987 "base lldb_private::Platform class can't expand arguments");
990 Status
Platform::KillProcess(const lldb::pid_t pid
) {
991 Log
*log
= GetLog(LLDBLog::Platform
);
992 LLDB_LOGF(log
, "Platform::%s, pid %" PRIu64
, __FUNCTION__
, pid
);
995 return Status::FromErrorString(
996 "base lldb_private::Platform class can't kill remote processes");
998 Host::Kill(pid
, SIGKILL
);
1002 lldb::ProcessSP
Platform::DebugProcess(ProcessLaunchInfo
&launch_info
,
1003 Debugger
&debugger
, Target
&target
,
1005 Log
*log
= GetLog(LLDBLog::Platform
);
1006 LLDB_LOG(log
, "target = {0}", &target
);
1008 ProcessSP process_sp
;
1009 // Make sure we stop at the entry point
1010 launch_info
.GetFlags().Set(eLaunchFlagDebug
);
1011 // We always launch the process we are going to debug in a separate process
1012 // group, since then we can handle ^C interrupts ourselves w/o having to
1013 // worry about the target getting them as well.
1014 launch_info
.SetLaunchInSeparateProcessGroup(true);
1016 // Allow any StructuredData process-bound plugins to adjust the launch info
1019 bool iteration_complete
= false;
1020 // Note iteration can't simply go until a nullptr callback is returned, as it
1021 // is valid for a plugin to not supply a filter.
1022 auto get_filter_func
= PluginManager::GetStructuredDataFilterCallbackAtIndex
;
1023 for (auto filter_callback
= get_filter_func(i
, iteration_complete
);
1024 !iteration_complete
;
1025 filter_callback
= get_filter_func(++i
, iteration_complete
)) {
1026 if (filter_callback
) {
1027 // Give this ProcessLaunchInfo filter a chance to adjust the launch info.
1028 error
= (*filter_callback
)(launch_info
, &target
);
1029 if (!error
.Success()) {
1031 "Platform::%s() StructuredDataPlugin launch "
1039 error
= LaunchProcess(launch_info
);
1040 if (error
.Success()) {
1042 "Platform::%s LaunchProcess() call succeeded (pid=%" PRIu64
")",
1043 __FUNCTION__
, launch_info
.GetProcessID());
1044 if (launch_info
.GetProcessID() != LLDB_INVALID_PROCESS_ID
) {
1045 ProcessAttachInfo
attach_info(launch_info
);
1046 process_sp
= Attach(attach_info
, debugger
, &target
, error
);
1048 LLDB_LOG(log
, "Attach() succeeded, Process plugin: {0}",
1049 process_sp
->GetPluginName());
1050 launch_info
.SetHijackListener(attach_info
.GetHijackListener());
1052 // Since we attached to the process, it will think it needs to detach
1053 // if the process object just goes away without an explicit call to
1054 // Process::Kill() or Process::Detach(), so let it know to kill the
1055 // process if this happens.
1056 process_sp
->SetShouldDetach(false);
1058 // If we didn't have any file actions, the pseudo terminal might have
1059 // been used where the secondary side was given as the file to open for
1060 // stdin/out/err after we have already opened the primary so we can
1061 // read/write stdin/out/err.
1062 int pty_fd
= launch_info
.GetPTY().ReleasePrimaryFileDescriptor();
1063 if (pty_fd
!= PseudoTerminal::invalid_fd
) {
1064 process_sp
->SetSTDIOFileDescriptor(pty_fd
);
1067 LLDB_LOGF(log
, "Platform::%s Attach() failed: %s", __FUNCTION__
,
1072 "Platform::%s LaunchProcess() returned launch_info with "
1073 "invalid process id",
1077 LLDB_LOGF(log
, "Platform::%s LaunchProcess() failed: %s", __FUNCTION__
,
1084 std::vector
<ArchSpec
>
1085 Platform::CreateArchList(llvm::ArrayRef
<llvm::Triple::ArchType
> archs
,
1086 llvm::Triple::OSType os
) {
1087 std::vector
<ArchSpec
> list
;
1088 for(auto arch
: archs
) {
1089 llvm::Triple triple
;
1090 triple
.setArch(arch
);
1092 list
.push_back(ArchSpec(triple
));
1097 /// Lets a platform answer if it is compatible with a given
1098 /// architecture and the target triple contained within.
1099 bool Platform::IsCompatibleArchitecture(const ArchSpec
&arch
,
1100 const ArchSpec
&process_host_arch
,
1101 ArchSpec::MatchType match
,
1102 ArchSpec
*compatible_arch_ptr
) {
1103 // If the architecture is invalid, we must answer true...
1104 if (arch
.IsValid()) {
1105 ArchSpec platform_arch
;
1106 for (const ArchSpec
&platform_arch
:
1107 GetSupportedArchitectures(process_host_arch
)) {
1108 if (arch
.IsMatch(platform_arch
, match
)) {
1109 if (compatible_arch_ptr
)
1110 *compatible_arch_ptr
= platform_arch
;
1115 if (compatible_arch_ptr
)
1116 compatible_arch_ptr
->Clear();
1120 Status
Platform::PutFile(const FileSpec
&source
, const FileSpec
&destination
,
1121 uint32_t uid
, uint32_t gid
) {
1122 Log
*log
= GetLog(LLDBLog::Platform
);
1123 LLDB_LOGF(log
, "[PutFile] Using block by block transfer....\n");
1125 auto source_open_options
=
1126 File::eOpenOptionReadOnly
| File::eOpenOptionCloseOnExec
;
1127 namespace fs
= llvm::sys::fs
;
1128 if (fs::is_symlink_file(source
.GetPath()))
1129 source_open_options
|= File::eOpenOptionDontFollowSymlinks
;
1131 auto source_file
= FileSystem::Instance().Open(source
, source_open_options
,
1132 lldb::eFilePermissionsUserRW
);
1134 return Status::FromError(source_file
.takeError());
1137 bool requires_upload
= true;
1138 llvm::ErrorOr
<llvm::MD5::MD5Result
> remote_md5
= CalculateMD5(destination
);
1139 if (std::error_code ec
= remote_md5
.getError()) {
1140 LLDB_LOG(log
, "[PutFile] couldn't get md5 sum of destination: {0}",
1143 llvm::ErrorOr
<llvm::MD5::MD5Result
> local_md5
=
1144 llvm::sys::fs::md5_contents(source
.GetPath());
1145 if (std::error_code ec
= local_md5
.getError()) {
1146 LLDB_LOG(log
, "[PutFile] couldn't get md5 sum of source: {0}",
1149 LLDB_LOGF(log
, "[PutFile] destination md5: %016" PRIx64
"%016" PRIx64
,
1150 remote_md5
->high(), remote_md5
->low());
1151 LLDB_LOGF(log
, "[PutFile] local md5: %016" PRIx64
"%016" PRIx64
,
1152 local_md5
->high(), local_md5
->low());
1153 requires_upload
= *remote_md5
!= *local_md5
;
1157 if (!requires_upload
) {
1158 LLDB_LOGF(log
, "[PutFile] skipping PutFile because md5sums match");
1162 uint32_t permissions
= source_file
.get()->GetPermissions(error
);
1163 if (permissions
== 0)
1164 permissions
= lldb::eFilePermissionsUserRWX
;
1166 lldb::user_id_t dest_file
= OpenFile(
1167 destination
, File::eOpenOptionCanCreate
| File::eOpenOptionWriteOnly
|
1168 File::eOpenOptionTruncate
| File::eOpenOptionCloseOnExec
,
1169 permissions
, error
);
1170 LLDB_LOGF(log
, "dest_file = %" PRIu64
"\n", dest_file
);
1174 if (dest_file
== UINT64_MAX
)
1175 return Status::FromErrorString("unable to open target file");
1176 lldb::WritableDataBufferSP
buffer_sp(new DataBufferHeap(1024 * 16, 0));
1177 uint64_t offset
= 0;
1179 size_t bytes_read
= buffer_sp
->GetByteSize();
1180 error
= source_file
.get()->Read(buffer_sp
->GetBytes(), bytes_read
);
1181 if (error
.Fail() || bytes_read
== 0)
1184 const uint64_t bytes_written
=
1185 WriteFile(dest_file
, offset
, buffer_sp
->GetBytes(), bytes_read
, error
);
1189 offset
+= bytes_written
;
1190 if (bytes_written
!= bytes_read
) {
1191 // We didn't write the correct number of bytes, so adjust the file
1192 // position in the source file we are reading from...
1193 source_file
.get()->SeekFromStart(offset
);
1196 CloseFile(dest_file
, error
);
1198 if (uid
== UINT32_MAX
&& gid
== UINT32_MAX
)
1206 Status
Platform::GetFile(const FileSpec
&source
, const FileSpec
&destination
) {
1207 return Status::FromErrorString("unimplemented");
1211 Platform::CreateSymlink(const FileSpec
&src
, // The name of the link is in src
1212 const FileSpec
&dst
) // The symlink points to dst
1215 return FileSystem::Instance().Symlink(src
, dst
);
1216 return Status::FromErrorString("unimplemented");
1219 bool Platform::GetFileExists(const lldb_private::FileSpec
&file_spec
) {
1221 return FileSystem::Instance().Exists(file_spec
);
1225 Status
Platform::Unlink(const FileSpec
&path
) {
1227 return llvm::sys::fs::remove(path
.GetPath());
1228 return Status::FromErrorString("unimplemented");
1231 MmapArgList
Platform::GetMmapArgumentList(const ArchSpec
&arch
, addr_t addr
,
1232 addr_t length
, unsigned prot
,
1233 unsigned flags
, addr_t fd
,
1235 uint64_t flags_platform
= 0;
1236 if (flags
& eMmapFlagsPrivate
)
1237 flags_platform
|= MAP_PRIVATE
;
1238 if (flags
& eMmapFlagsAnon
)
1239 flags_platform
|= MAP_ANON
;
1241 MmapArgList
args({addr
, length
, prot
, flags_platform
, fd
, offset
});
1245 lldb_private::Status
Platform::RunShellCommand(
1246 llvm::StringRef command
,
1248 working_dir
, // Pass empty FileSpec to use the current working directory
1249 int *status_ptr
, // Pass nullptr if you don't want the process exit status
1250 int *signo_ptr
, // Pass nullptr if you don't want the signal that caused the
1253 *command_output
, // Pass nullptr if you don't want the command output
1254 const Timeout
<std::micro
> &timeout
) {
1255 return RunShellCommand(llvm::StringRef(), command
, working_dir
, status_ptr
,
1256 signo_ptr
, command_output
, timeout
);
1259 lldb_private::Status
Platform::RunShellCommand(
1260 llvm::StringRef shell
, // Pass empty if you want to use the default
1261 // shell interpreter
1262 llvm::StringRef command
, // Shouldn't be empty
1264 working_dir
, // Pass empty FileSpec to use the current working directory
1265 int *status_ptr
, // Pass nullptr if you don't want the process exit status
1266 int *signo_ptr
, // Pass nullptr if you don't want the signal that caused the
1269 *command_output
, // Pass nullptr if you don't want the command output
1270 const Timeout
<std::micro
> &timeout
) {
1272 return Host::RunShellCommand(shell
, command
, working_dir
, status_ptr
,
1273 signo_ptr
, command_output
, timeout
);
1274 return Status::FromErrorString(
1275 "unable to run a remote command without a platform");
1278 llvm::ErrorOr
<llvm::MD5::MD5Result
>
1279 Platform::CalculateMD5(const FileSpec
&file_spec
) {
1281 return std::make_error_code(std::errc::not_supported
);
1282 return llvm::sys::fs::md5_contents(file_spec
.GetPath());
1285 void Platform::SetLocalCacheDirectory(const char *local
) {
1286 m_local_cache_directory
.assign(local
);
1289 const char *Platform::GetLocalCacheDirectory() {
1290 return m_local_cache_directory
.c_str();
1293 static constexpr OptionDefinition g_rsync_option_table
[] = {
1294 {LLDB_OPT_SET_ALL
, false, "rsync", 'r', OptionParser::eNoArgument
, nullptr,
1295 {}, 0, eArgTypeNone
, "Enable rsync."},
1296 {LLDB_OPT_SET_ALL
, false, "rsync-opts", 'R',
1297 OptionParser::eRequiredArgument
, nullptr, {}, 0, eArgTypeCommandName
,
1298 "Platform-specific options required for rsync to work."},
1299 {LLDB_OPT_SET_ALL
, false, "rsync-prefix", 'P',
1300 OptionParser::eRequiredArgument
, nullptr, {}, 0, eArgTypeCommandName
,
1301 "Platform-specific rsync prefix put before the remote path."},
1302 {LLDB_OPT_SET_ALL
, false, "ignore-remote-hostname", 'i',
1303 OptionParser::eNoArgument
, nullptr, {}, 0, eArgTypeNone
,
1304 "Do not automatically fill in the remote hostname when composing the "
1308 static constexpr OptionDefinition g_ssh_option_table
[] = {
1309 {LLDB_OPT_SET_ALL
, false, "ssh", 's', OptionParser::eNoArgument
, nullptr,
1310 {}, 0, eArgTypeNone
, "Enable SSH."},
1311 {LLDB_OPT_SET_ALL
, false, "ssh-opts", 'S', OptionParser::eRequiredArgument
,
1312 nullptr, {}, 0, eArgTypeCommandName
,
1313 "Platform-specific options required for SSH to work."},
1316 static constexpr OptionDefinition g_caching_option_table
[] = {
1317 {LLDB_OPT_SET_ALL
, false, "local-cache-dir", 'c',
1318 OptionParser::eRequiredArgument
, nullptr, {}, 0, eArgTypePath
,
1319 "Path in which to store local copies of files."},
1322 llvm::ArrayRef
<OptionDefinition
> OptionGroupPlatformRSync::GetDefinitions() {
1323 return llvm::ArrayRef(g_rsync_option_table
);
1326 void OptionGroupPlatformRSync::OptionParsingStarting(
1327 ExecutionContext
*execution_context
) {
1329 m_rsync_opts
.clear();
1330 m_rsync_prefix
.clear();
1331 m_ignores_remote_hostname
= false;
1334 lldb_private::Status
1335 OptionGroupPlatformRSync::SetOptionValue(uint32_t option_idx
,
1336 llvm::StringRef option_arg
,
1337 ExecutionContext
*execution_context
) {
1339 char short_option
= (char)GetDefinitions()[option_idx
].short_option
;
1340 switch (short_option
) {
1346 m_rsync_opts
.assign(std::string(option_arg
));
1350 m_rsync_prefix
.assign(std::string(option_arg
));
1354 m_ignores_remote_hostname
= true;
1358 error
= Status::FromErrorStringWithFormat("unrecognized option '%c'",
1367 Platform::SetThreadCreationBreakpoint(lldb_private::Target
&target
) {
1368 return lldb::BreakpointSP();
1371 llvm::ArrayRef
<OptionDefinition
> OptionGroupPlatformSSH::GetDefinitions() {
1372 return llvm::ArrayRef(g_ssh_option_table
);
1375 void OptionGroupPlatformSSH::OptionParsingStarting(
1376 ExecutionContext
*execution_context
) {
1381 lldb_private::Status
1382 OptionGroupPlatformSSH::SetOptionValue(uint32_t option_idx
,
1383 llvm::StringRef option_arg
,
1384 ExecutionContext
*execution_context
) {
1386 char short_option
= (char)GetDefinitions()[option_idx
].short_option
;
1387 switch (short_option
) {
1393 m_ssh_opts
.assign(std::string(option_arg
));
1397 error
= Status::FromErrorStringWithFormat("unrecognized option '%c'",
1405 llvm::ArrayRef
<OptionDefinition
> OptionGroupPlatformCaching::GetDefinitions() {
1406 return llvm::ArrayRef(g_caching_option_table
);
1409 void OptionGroupPlatformCaching::OptionParsingStarting(
1410 ExecutionContext
*execution_context
) {
1411 m_cache_dir
.clear();
1414 lldb_private::Status
OptionGroupPlatformCaching::SetOptionValue(
1415 uint32_t option_idx
, llvm::StringRef option_arg
,
1416 ExecutionContext
*execution_context
) {
1418 char short_option
= (char)GetDefinitions()[option_idx
].short_option
;
1419 switch (short_option
) {
1421 m_cache_dir
.assign(std::string(option_arg
));
1425 error
= Status::FromErrorStringWithFormat("unrecognized option '%c'",
1433 Environment
Platform::GetEnvironment() {
1435 return Host::GetEnvironment();
1436 return Environment();
1439 const std::vector
<ConstString
> &Platform::GetTrapHandlerSymbolNames() {
1440 if (!m_calculated_trap_handlers
) {
1441 std::lock_guard
<std::mutex
> guard(m_mutex
);
1442 if (!m_calculated_trap_handlers
) {
1443 CalculateTrapHandlerSymbolNames();
1444 m_calculated_trap_handlers
= true;
1447 return m_trap_handlers
;
1451 Platform::GetCachedExecutable(ModuleSpec
&module_spec
,
1452 lldb::ModuleSP
&module_sp
,
1453 const FileSpecList
*module_search_paths_ptr
) {
1454 FileSpec platform_spec
= module_spec
.GetFileSpec();
1455 Status error
= GetRemoteSharedModule(
1456 module_spec
, nullptr, module_sp
,
1457 [&](const ModuleSpec
&spec
) {
1458 return Platform::ResolveExecutable(spec
, module_sp
,
1459 module_search_paths_ptr
);
1462 if (error
.Success()) {
1463 module_spec
.GetFileSpec() = module_sp
->GetFileSpec();
1464 module_spec
.GetPlatformFileSpec() = platform_spec
;
1470 Status
Platform::GetRemoteSharedModule(const ModuleSpec
&module_spec
,
1472 lldb::ModuleSP
&module_sp
,
1473 const ModuleResolver
&module_resolver
,
1474 bool *did_create_ptr
) {
1475 // Get module information from a target.
1476 ModuleSpec resolved_module_spec
;
1477 ArchSpec process_host_arch
;
1478 bool got_module_spec
= false;
1480 process_host_arch
= process
->GetSystemArchitecture();
1481 // Try to get module information from the process
1482 if (process
->GetModuleSpec(module_spec
.GetFileSpec(),
1483 module_spec
.GetArchitecture(),
1484 resolved_module_spec
)) {
1485 if (!module_spec
.GetUUID().IsValid() ||
1486 module_spec
.GetUUID() == resolved_module_spec
.GetUUID()) {
1487 got_module_spec
= true;
1492 if (!module_spec
.GetArchitecture().IsValid()) {
1494 // No valid architecture was specified, ask the platform for the
1495 // architectures that we should be using (in the correct order) and see if
1496 // we can find a match that way
1497 ModuleSpec
arch_module_spec(module_spec
);
1498 for (const ArchSpec
&arch
: GetSupportedArchitectures(process_host_arch
)) {
1499 arch_module_spec
.GetArchitecture() = arch
;
1500 error
= ModuleList::GetSharedModule(arch_module_spec
, module_sp
, nullptr,
1502 // Did we find an executable using one of the
1503 if (error
.Success() && module_sp
)
1507 resolved_module_spec
= arch_module_spec
;
1508 got_module_spec
= true;
1512 if (!got_module_spec
) {
1513 // Get module information from a target.
1514 if (GetModuleSpec(module_spec
.GetFileSpec(), module_spec
.GetArchitecture(),
1515 resolved_module_spec
)) {
1516 if (!module_spec
.GetUUID().IsValid() ||
1517 module_spec
.GetUUID() == resolved_module_spec
.GetUUID()) {
1518 got_module_spec
= true;
1523 if (!got_module_spec
) {
1524 // Fall back to the given module resolver, which may have its own
1526 return module_resolver(module_spec
);
1529 // If we are looking for a specific UUID, make sure resolved_module_spec has
1530 // the same one before we search.
1531 if (module_spec
.GetUUID().IsValid()) {
1532 resolved_module_spec
.GetUUID() = module_spec
.GetUUID();
1535 // Call locate module callback if set. This allows users to implement their
1536 // own module cache system. For example, to leverage build system artifacts,
1537 // to bypass pulling files from remote platform, or to search symbol files
1538 // from symbol servers.
1539 FileSpec symbol_file_spec
;
1540 CallLocateModuleCallbackIfSet(resolved_module_spec
, module_sp
,
1541 symbol_file_spec
, did_create_ptr
);
1543 // The module is loaded.
1544 if (symbol_file_spec
) {
1545 // 1. module_sp:loaded, symbol_file_spec:set
1546 // The callback found a module file and a symbol file for this
1547 // resolved_module_spec. Set the symbol file to the module.
1548 module_sp
->SetSymbolFileFileSpec(symbol_file_spec
);
1550 // 2. module_sp:loaded, symbol_file_spec:empty
1551 // The callback only found a module file for this
1552 // resolved_module_spec.
1557 // The module is not loaded by CallLocateModuleCallbackIfSet.
1558 // 3. module_sp:empty, symbol_file_spec:set
1559 // The callback only found a symbol file for the module. We continue to
1560 // find a module file for this resolved_module_spec. and we will call
1561 // module_sp->SetSymbolFileFileSpec with the symbol_file_spec later.
1562 // 4. module_sp:empty, symbol_file_spec:empty
1563 // The callback is not set. Or the callback did not find any module
1564 // files nor any symbol files. Or the callback failed, or something
1565 // went wrong. We continue to find a module file for this
1566 // resolved_module_spec.
1568 // Trying to find a module by UUID on local file system.
1569 Status error
= module_resolver(resolved_module_spec
);
1570 if (error
.Success()) {
1571 if (module_sp
&& symbol_file_spec
) {
1572 // Set the symbol file to the module if the locate modudle callback was
1573 // called and returned only a symbol file.
1574 module_sp
->SetSymbolFileFileSpec(symbol_file_spec
);
1579 // Fallback to call GetCachedSharedModule on failure.
1580 if (GetCachedSharedModule(resolved_module_spec
, module_sp
, did_create_ptr
)) {
1581 if (module_sp
&& symbol_file_spec
) {
1582 // Set the symbol file to the module if the locate modudle callback was
1583 // called and returned only a symbol file.
1584 module_sp
->SetSymbolFileFileSpec(symbol_file_spec
);
1589 return Status::FromErrorStringWithFormat(
1590 "Failed to call GetCachedSharedModule");
1593 void Platform::CallLocateModuleCallbackIfSet(const ModuleSpec
&module_spec
,
1594 lldb::ModuleSP
&module_sp
,
1595 FileSpec
&symbol_file_spec
,
1596 bool *did_create_ptr
) {
1597 if (!m_locate_module_callback
) {
1598 // Locate module callback is not set.
1602 FileSpec module_file_spec
;
1604 m_locate_module_callback(module_spec
, module_file_spec
, symbol_file_spec
);
1606 // Locate module callback is set and called. Check the error.
1607 Log
*log
= GetLog(LLDBLog::Platform
);
1609 LLDB_LOGF(log
, "%s: locate module callback failed: %s",
1610 LLVM_PRETTY_FUNCTION
, error
.AsCString());
1614 // The locate module callback was succeeded.
1615 // Check the module_file_spec and symbol_file_spec values.
1616 // 1. module:empty symbol:empty -> Failure
1617 // - The callback did not return any files.
1618 // 2. module:exists symbol:exists -> Success
1619 // - The callback returned a module file and a symbol file.
1620 // 3. module:exists symbol:empty -> Success
1621 // - The callback returned only a module file.
1622 // 4. module:empty symbol:exists -> Success
1623 // - The callback returned only a symbol file.
1624 // For example, a breakpad symbol text file.
1625 if (!module_file_spec
&& !symbol_file_spec
) {
1626 // This is '1. module:empty symbol:empty -> Failure'
1627 // The callback did not return any files.
1629 "%s: locate module callback did not set both "
1630 "module_file_spec and symbol_file_spec",
1631 LLVM_PRETTY_FUNCTION
);
1635 // If the callback returned a module file, it should exist.
1636 if (module_file_spec
&& !FileSystem::Instance().Exists(module_file_spec
)) {
1638 "%s: locate module callback set a non-existent file to "
1639 "module_file_spec: %s",
1640 LLVM_PRETTY_FUNCTION
, module_file_spec
.GetPath().c_str());
1641 // Clear symbol_file_spec for the error.
1642 symbol_file_spec
.Clear();
1646 // If the callback returned a symbol file, it should exist.
1647 if (symbol_file_spec
&& !FileSystem::Instance().Exists(symbol_file_spec
)) {
1649 "%s: locate module callback set a non-existent file to "
1650 "symbol_file_spec: %s",
1651 LLVM_PRETTY_FUNCTION
, symbol_file_spec
.GetPath().c_str());
1652 // Clear symbol_file_spec for the error.
1653 symbol_file_spec
.Clear();
1657 if (!module_file_spec
&& symbol_file_spec
) {
1658 // This is '4. module:empty symbol:exists -> Success'
1659 // The locate module callback returned only a symbol file. For example,
1660 // a breakpad symbol text file. GetRemoteSharedModule will use this returned
1661 // symbol_file_spec.
1662 LLDB_LOGF(log
, "%s: locate module callback succeeded: symbol=%s",
1663 LLVM_PRETTY_FUNCTION
, symbol_file_spec
.GetPath().c_str());
1667 // This is one of the following.
1668 // - 2. module:exists symbol:exists -> Success
1669 // - The callback returned a module file and a symbol file.
1670 // - 3. module:exists symbol:empty -> Success
1671 // - The callback returned Only a module file.
1672 // Load the module file.
1673 auto cached_module_spec(module_spec
);
1674 cached_module_spec
.GetUUID().Clear(); // Clear UUID since it may contain md5
1675 // content hash instead of real UUID.
1676 cached_module_spec
.GetFileSpec() = module_file_spec
;
1677 cached_module_spec
.GetPlatformFileSpec() = module_spec
.GetFileSpec();
1678 cached_module_spec
.SetObjectOffset(0);
1680 error
= ModuleList::GetSharedModule(cached_module_spec
, module_sp
, nullptr,
1681 nullptr, did_create_ptr
, false);
1682 if (error
.Success() && module_sp
) {
1683 // Succeeded to load the module file.
1684 LLDB_LOGF(log
, "%s: locate module callback succeeded: module=%s symbol=%s",
1685 LLVM_PRETTY_FUNCTION
, module_file_spec
.GetPath().c_str(),
1686 symbol_file_spec
.GetPath().c_str());
1689 "%s: locate module callback succeeded but failed to load: "
1690 "module=%s symbol=%s",
1691 LLVM_PRETTY_FUNCTION
, module_file_spec
.GetPath().c_str(),
1692 symbol_file_spec
.GetPath().c_str());
1693 // Clear module_sp and symbol_file_spec for the error.
1695 symbol_file_spec
.Clear();
1699 bool Platform::GetCachedSharedModule(const ModuleSpec
&module_spec
,
1700 lldb::ModuleSP
&module_sp
,
1701 bool *did_create_ptr
) {
1702 if (IsHost() || !GetGlobalPlatformProperties().GetUseModuleCache() ||
1703 !GetGlobalPlatformProperties().GetModuleCacheDirectory())
1706 Log
*log
= GetLog(LLDBLog::Platform
);
1708 // Check local cache for a module.
1709 auto error
= m_module_cache
->GetAndPut(
1710 GetModuleCacheRoot(), GetCacheHostname(), module_spec
,
1711 [this](const ModuleSpec
&module_spec
,
1712 const FileSpec
&tmp_download_file_spec
) {
1713 return DownloadModuleSlice(
1714 module_spec
.GetFileSpec(), module_spec
.GetObjectOffset(),
1715 module_spec
.GetObjectSize(), tmp_download_file_spec
);
1718 [this](const ModuleSP
&module_sp
,
1719 const FileSpec
&tmp_download_file_spec
) {
1720 return DownloadSymbolFile(module_sp
, tmp_download_file_spec
);
1722 module_sp
, did_create_ptr
);
1723 if (error
.Success())
1726 LLDB_LOGF(log
, "Platform::%s - module %s not found in local cache: %s",
1727 __FUNCTION__
, module_spec
.GetUUID().GetAsString().c_str(),
1732 Status
Platform::DownloadModuleSlice(const FileSpec
&src_file_spec
,
1733 const uint64_t src_offset
,
1734 const uint64_t src_size
,
1735 const FileSpec
&dst_file_spec
) {
1739 llvm::raw_fd_ostream
dst(dst_file_spec
.GetPath(), EC
, llvm::sys::fs::OF_None
);
1741 error
= Status::FromErrorStringWithFormat(
1742 "unable to open destination file: %s", dst_file_spec
.GetPath().c_str());
1746 auto src_fd
= OpenFile(src_file_spec
, File::eOpenOptionReadOnly
,
1747 lldb::eFilePermissionsFileDefault
, error
);
1750 error
= Status::FromErrorStringWithFormat("unable to open source file: %s",
1755 std::vector
<char> buffer(512 * 1024);
1756 auto offset
= src_offset
;
1757 uint64_t total_bytes_read
= 0;
1758 while (total_bytes_read
< src_size
) {
1759 const auto to_read
= std::min(static_cast<uint64_t>(buffer
.size()),
1760 src_size
- total_bytes_read
);
1761 const uint64_t n_read
=
1762 ReadFile(src_fd
, offset
, &buffer
[0], to_read
, error
);
1766 error
= Status::FromErrorString("read 0 bytes");
1770 total_bytes_read
+= n_read
;
1771 dst
.write(&buffer
[0], n_read
);
1775 CloseFile(src_fd
, close_error
); // Ignoring close error.
1780 Status
Platform::DownloadSymbolFile(const lldb::ModuleSP
&module_sp
,
1781 const FileSpec
&dst_file_spec
) {
1782 return Status::FromErrorString(
1783 "Symbol file downloading not supported by the default platform.");
1786 FileSpec
Platform::GetModuleCacheRoot() {
1787 auto dir_spec
= GetGlobalPlatformProperties().GetModuleCacheDirectory();
1788 dir_spec
.AppendPathComponent(GetPluginName());
1792 const char *Platform::GetCacheHostname() { return GetHostname(); }
1794 const UnixSignalsSP
&Platform::GetRemoteUnixSignals() {
1795 static const auto s_default_unix_signals_sp
= std::make_shared
<UnixSignals
>();
1796 return s_default_unix_signals_sp
;
1799 UnixSignalsSP
Platform::GetUnixSignals() {
1801 return UnixSignals::CreateForHost();
1802 return GetRemoteUnixSignals();
1805 uint32_t Platform::LoadImage(lldb_private::Process
*process
,
1806 const lldb_private::FileSpec
&local_file
,
1807 const lldb_private::FileSpec
&remote_file
,
1808 lldb_private::Status
&error
) {
1809 if (local_file
&& remote_file
) {
1810 // Both local and remote file was specified. Install the local file to the
1812 if (IsRemote() || local_file
!= remote_file
) {
1813 error
= Install(local_file
, remote_file
);
1815 return LLDB_INVALID_IMAGE_TOKEN
;
1817 return DoLoadImage(process
, remote_file
, nullptr, error
);
1821 // Only local file was specified. Install it to the current working
1823 FileSpec target_file
= GetWorkingDirectory();
1824 target_file
.AppendPathComponent(local_file
.GetFilename().AsCString());
1825 if (IsRemote() || local_file
!= target_file
) {
1826 error
= Install(local_file
, target_file
);
1828 return LLDB_INVALID_IMAGE_TOKEN
;
1830 return DoLoadImage(process
, target_file
, nullptr, error
);
1834 // Only remote file was specified so we don't have to do any copying
1835 return DoLoadImage(process
, remote_file
, nullptr, error
);
1839 Status::FromErrorString("Neither local nor remote file was specified");
1840 return LLDB_INVALID_IMAGE_TOKEN
;
1843 uint32_t Platform::DoLoadImage(lldb_private::Process
*process
,
1844 const lldb_private::FileSpec
&remote_file
,
1845 const std::vector
<std::string
> *paths
,
1846 lldb_private::Status
&error
,
1847 lldb_private::FileSpec
*loaded_image
) {
1848 error
= Status::FromErrorString(
1849 "LoadImage is not supported on the current platform");
1850 return LLDB_INVALID_IMAGE_TOKEN
;
1853 uint32_t Platform::LoadImageUsingPaths(lldb_private::Process
*process
,
1854 const lldb_private::FileSpec
&remote_filename
,
1855 const std::vector
<std::string
> &paths
,
1856 lldb_private::Status
&error
,
1857 lldb_private::FileSpec
*loaded_path
)
1859 FileSpec file_to_use
;
1860 if (remote_filename
.IsAbsolute())
1861 file_to_use
= FileSpec(remote_filename
.GetFilename().GetStringRef(),
1863 remote_filename
.GetPathStyle());
1865 file_to_use
= remote_filename
;
1867 return DoLoadImage(process
, file_to_use
, &paths
, error
, loaded_path
);
1870 Status
Platform::UnloadImage(lldb_private::Process
*process
,
1871 uint32_t image_token
) {
1872 return Status::FromErrorString(
1873 "UnloadImage is not supported on the current platform");
1876 lldb::ProcessSP
Platform::ConnectProcess(llvm::StringRef connect_url
,
1877 llvm::StringRef plugin_name
,
1878 Debugger
&debugger
, Target
*target
,
1880 return DoConnectProcess(connect_url
, plugin_name
, debugger
, nullptr, target
,
1884 lldb::ProcessSP
Platform::ConnectProcessSynchronous(
1885 llvm::StringRef connect_url
, llvm::StringRef plugin_name
,
1886 Debugger
&debugger
, Stream
&stream
, Target
*target
, Status
&error
) {
1887 return DoConnectProcess(connect_url
, plugin_name
, debugger
, &stream
, target
,
1891 lldb::ProcessSP
Platform::DoConnectProcess(llvm::StringRef connect_url
,
1892 llvm::StringRef plugin_name
,
1893 Debugger
&debugger
, Stream
*stream
,
1894 Target
*target
, Status
&error
) {
1898 ArchSpec arch
= Target::GetDefaultArchitecture();
1900 const char *triple
=
1901 arch
.IsValid() ? arch
.GetTriple().getTriple().c_str() : "";
1903 TargetSP new_target_sp
;
1904 error
= debugger
.GetTargetList().CreateTarget(
1905 debugger
, "", triple
, eLoadDependentsNo
, nullptr, new_target_sp
);
1907 target
= new_target_sp
.get();
1908 if (!target
|| error
.Fail()) {
1913 lldb::ProcessSP process_sp
=
1914 target
->CreateProcess(debugger
.GetListener(), plugin_name
, nullptr, true);
1919 // If this private method is called with a stream we are synchronous.
1920 const bool synchronous
= stream
!= nullptr;
1922 ListenerSP
listener_sp(
1923 Listener::MakeListener("lldb.Process.ConnectProcess.hijack"));
1925 process_sp
->HijackProcessEvents(listener_sp
);
1927 error
= process_sp
->ConnectRemote(connect_url
);
1930 process_sp
->RestoreProcessEvents();
1936 process_sp
->WaitForProcessToStop(std::nullopt
, &event_sp
, true, listener_sp
,
1938 process_sp
->RestoreProcessEvents();
1939 bool pop_process_io_handler
= false;
1940 // This is a user-level stop, so we allow recognizers to select frames.
1941 Process::HandleProcessStateChangedEvent(
1942 event_sp
, stream
, SelectMostRelevantFrame
, pop_process_io_handler
);
1948 size_t Platform::ConnectToWaitingProcesses(lldb_private::Debugger
&debugger
,
1949 lldb_private::Status
&error
) {
1954 size_t Platform::GetSoftwareBreakpointTrapOpcode(Target
&target
,
1955 BreakpointSite
*bp_site
) {
1956 ArchSpec arch
= target
.GetArchitecture();
1957 assert(arch
.IsValid());
1958 const uint8_t *trap_opcode
= nullptr;
1959 size_t trap_opcode_size
= 0;
1961 switch (arch
.GetMachine()) {
1962 case llvm::Triple::aarch64_32
:
1963 case llvm::Triple::aarch64
: {
1964 static const uint8_t g_aarch64_opcode
[] = {0x00, 0x00, 0x20, 0xd4};
1965 trap_opcode
= g_aarch64_opcode
;
1966 trap_opcode_size
= sizeof(g_aarch64_opcode
);
1969 case llvm::Triple::arc
: {
1970 static const uint8_t g_hex_opcode
[] = { 0xff, 0x7f };
1971 trap_opcode
= g_hex_opcode
;
1972 trap_opcode_size
= sizeof(g_hex_opcode
);
1975 // TODO: support big-endian arm and thumb trap codes.
1976 case llvm::Triple::arm
: {
1977 // The ARM reference recommends the use of 0xe7fddefe and 0xdefe but the
1978 // linux kernel does otherwise.
1979 static const uint8_t g_arm_breakpoint_opcode
[] = {0xf0, 0x01, 0xf0, 0xe7};
1980 static const uint8_t g_thumb_breakpoint_opcode
[] = {0x01, 0xde};
1982 lldb::BreakpointLocationSP
bp_loc_sp(bp_site
->GetConstituentAtIndex(0));
1983 AddressClass addr_class
= AddressClass::eUnknown
;
1986 addr_class
= bp_loc_sp
->GetAddress().GetAddressClass();
1987 if (addr_class
== AddressClass::eUnknown
&&
1988 (bp_loc_sp
->GetAddress().GetFileAddress() & 1))
1989 addr_class
= AddressClass::eCodeAlternateISA
;
1992 if (addr_class
== AddressClass::eCodeAlternateISA
) {
1993 trap_opcode
= g_thumb_breakpoint_opcode
;
1994 trap_opcode_size
= sizeof(g_thumb_breakpoint_opcode
);
1996 trap_opcode
= g_arm_breakpoint_opcode
;
1997 trap_opcode_size
= sizeof(g_arm_breakpoint_opcode
);
2001 case llvm::Triple::avr
: {
2002 static const uint8_t g_hex_opcode
[] = {0x98, 0x95};
2003 trap_opcode
= g_hex_opcode
;
2004 trap_opcode_size
= sizeof(g_hex_opcode
);
2007 case llvm::Triple::mips
:
2008 case llvm::Triple::mips64
: {
2009 static const uint8_t g_hex_opcode
[] = {0x00, 0x00, 0x00, 0x0d};
2010 trap_opcode
= g_hex_opcode
;
2011 trap_opcode_size
= sizeof(g_hex_opcode
);
2014 case llvm::Triple::mipsel
:
2015 case llvm::Triple::mips64el
: {
2016 static const uint8_t g_hex_opcode
[] = {0x0d, 0x00, 0x00, 0x00};
2017 trap_opcode
= g_hex_opcode
;
2018 trap_opcode_size
= sizeof(g_hex_opcode
);
2021 case llvm::Triple::msp430
: {
2022 static const uint8_t g_msp430_opcode
[] = {0x43, 0x43};
2023 trap_opcode
= g_msp430_opcode
;
2024 trap_opcode_size
= sizeof(g_msp430_opcode
);
2027 case llvm::Triple::systemz
: {
2028 static const uint8_t g_hex_opcode
[] = {0x00, 0x01};
2029 trap_opcode
= g_hex_opcode
;
2030 trap_opcode_size
= sizeof(g_hex_opcode
);
2033 case llvm::Triple::hexagon
: {
2034 static const uint8_t g_hex_opcode
[] = {0x0c, 0xdb, 0x00, 0x54};
2035 trap_opcode
= g_hex_opcode
;
2036 trap_opcode_size
= sizeof(g_hex_opcode
);
2039 case llvm::Triple::ppc
:
2040 case llvm::Triple::ppc64
: {
2041 static const uint8_t g_ppc_opcode
[] = {0x7f, 0xe0, 0x00, 0x08};
2042 trap_opcode
= g_ppc_opcode
;
2043 trap_opcode_size
= sizeof(g_ppc_opcode
);
2046 case llvm::Triple::ppc64le
: {
2047 static const uint8_t g_ppc64le_opcode
[] = {0x08, 0x00, 0xe0, 0x7f}; // trap
2048 trap_opcode
= g_ppc64le_opcode
;
2049 trap_opcode_size
= sizeof(g_ppc64le_opcode
);
2052 case llvm::Triple::x86
:
2053 case llvm::Triple::x86_64
: {
2054 static const uint8_t g_i386_opcode
[] = {0xCC};
2055 trap_opcode
= g_i386_opcode
;
2056 trap_opcode_size
= sizeof(g_i386_opcode
);
2059 case llvm::Triple::riscv32
:
2060 case llvm::Triple::riscv64
: {
2061 static const uint8_t g_riscv_opcode
[] = {0x73, 0x00, 0x10, 0x00}; // ebreak
2062 static const uint8_t g_riscv_opcode_c
[] = {0x02, 0x90}; // c.ebreak
2063 if (arch
.GetFlags() & ArchSpec::eRISCV_rvc
) {
2064 trap_opcode
= g_riscv_opcode_c
;
2065 trap_opcode_size
= sizeof(g_riscv_opcode_c
);
2067 trap_opcode
= g_riscv_opcode
;
2068 trap_opcode_size
= sizeof(g_riscv_opcode
);
2072 case llvm::Triple::loongarch32
:
2073 case llvm::Triple::loongarch64
: {
2074 static const uint8_t g_loongarch_opcode
[] = {0x05, 0x00, 0x2a,
2076 trap_opcode
= g_loongarch_opcode
;
2077 trap_opcode_size
= sizeof(g_loongarch_opcode
);
2085 if (bp_site
->SetTrapOpcode(trap_opcode
, trap_opcode_size
))
2086 return trap_opcode_size
;
2091 CompilerType
Platform::GetSiginfoType(const llvm::Triple
& triple
) {
2092 return CompilerType();
2095 Args
Platform::GetExtraStartupCommands() {
2099 void Platform::SetLocateModuleCallback(LocateModuleCallback callback
) {
2100 m_locate_module_callback
= callback
;
2103 Platform::LocateModuleCallback
Platform::GetLocateModuleCallback() const {
2104 return m_locate_module_callback
;
2107 PlatformSP
PlatformList::GetOrCreate(llvm::StringRef name
) {
2108 std::lock_guard
<std::recursive_mutex
> guard(m_mutex
);
2109 for (const PlatformSP
&platform_sp
: m_platforms
) {
2110 if (platform_sp
->GetName() == name
)
2113 return Create(name
);
2116 PlatformSP
PlatformList::GetOrCreate(const ArchSpec
&arch
,
2117 const ArchSpec
&process_host_arch
,
2118 ArchSpec
*platform_arch_ptr
,
2120 std::lock_guard
<std::recursive_mutex
> guard(m_mutex
);
2121 // First try exact arch matches across all platforms already created
2122 for (const auto &platform_sp
: m_platforms
) {
2123 if (platform_sp
->IsCompatibleArchitecture(
2124 arch
, process_host_arch
, ArchSpec::ExactMatch
, platform_arch_ptr
))
2128 // Next try compatible arch matches across all platforms already created
2129 for (const auto &platform_sp
: m_platforms
) {
2130 if (platform_sp
->IsCompatibleArchitecture(arch
, process_host_arch
,
2131 ArchSpec::CompatibleMatch
,
2136 PlatformCreateInstance create_callback
;
2137 // First try exact arch matches across all platform plug-ins
2140 (create_callback
= PluginManager::GetPlatformCreateCallbackAtIndex(idx
));
2142 PlatformSP platform_sp
= create_callback(false, &arch
);
2144 platform_sp
->IsCompatibleArchitecture(
2145 arch
, process_host_arch
, ArchSpec::ExactMatch
, platform_arch_ptr
)) {
2146 m_platforms
.push_back(platform_sp
);
2150 // Next try compatible arch matches across all platform plug-ins
2152 (create_callback
= PluginManager::GetPlatformCreateCallbackAtIndex(idx
));
2154 PlatformSP platform_sp
= create_callback(false, &arch
);
2155 if (platform_sp
&& platform_sp
->IsCompatibleArchitecture(
2156 arch
, process_host_arch
, ArchSpec::CompatibleMatch
,
2157 platform_arch_ptr
)) {
2158 m_platforms
.push_back(platform_sp
);
2162 if (platform_arch_ptr
)
2163 platform_arch_ptr
->Clear();
2167 PlatformSP
PlatformList::GetOrCreate(const ArchSpec
&arch
,
2168 const ArchSpec
&process_host_arch
,
2169 ArchSpec
*platform_arch_ptr
) {
2172 return GetOrCreate(arch
, process_host_arch
, platform_arch_ptr
, error
);
2176 PlatformSP
PlatformList::GetOrCreate(llvm::ArrayRef
<ArchSpec
> archs
,
2177 const ArchSpec
&process_host_arch
,
2178 std::vector
<PlatformSP
> &candidates
) {
2180 candidates
.reserve(archs
.size());
2185 PlatformSP host_platform_sp
= Platform::GetHostPlatform();
2187 // Prefer the selected platform if it matches at least one architecture.
2188 if (m_selected_platform_sp
) {
2189 for (const ArchSpec
&arch
: archs
) {
2190 if (m_selected_platform_sp
->IsCompatibleArchitecture(
2191 arch
, process_host_arch
, ArchSpec::CompatibleMatch
, nullptr))
2192 return m_selected_platform_sp
;
2196 // Prefer the host platform if it matches at least one architecture.
2197 if (host_platform_sp
) {
2198 for (const ArchSpec
&arch
: archs
) {
2199 if (host_platform_sp
->IsCompatibleArchitecture(
2200 arch
, process_host_arch
, ArchSpec::CompatibleMatch
, nullptr))
2201 return host_platform_sp
;
2205 // Collect a list of candidate platforms for the architectures.
2206 for (const ArchSpec
&arch
: archs
) {
2207 if (PlatformSP platform
= GetOrCreate(arch
, process_host_arch
, nullptr))
2208 candidates
.push_back(platform
);
2211 // The selected or host platform didn't match any of the architectures. If
2212 // the same platform supports all architectures then that's the obvious next
2214 if (candidates
.size() == archs
.size()) {
2215 if (llvm::all_of(candidates
, [&](const PlatformSP
&p
) -> bool {
2216 return p
->GetName() == candidates
.front()->GetName();
2218 return candidates
.front();
2222 // At this point we either have no platforms that match the given
2223 // architectures or multiple platforms with no good way to disambiguate
2228 PlatformSP
PlatformList::Create(llvm::StringRef name
) {
2229 std::lock_guard
<std::recursive_mutex
> guard(m_mutex
);
2230 PlatformSP platform_sp
= Platform::Create(name
);
2231 m_platforms
.push_back(platform_sp
);
2235 bool PlatformList::LoadPlatformBinaryAndSetup(Process
*process
,
2236 lldb::addr_t addr
, bool notify
) {
2237 std::lock_guard
<std::recursive_mutex
> guard(m_mutex
);
2239 PlatformCreateInstance create_callback
;
2241 (create_callback
= PluginManager::GetPlatformCreateCallbackAtIndex(idx
));
2244 PlatformSP platform_sp
= create_callback(true, &arch
);
2246 if (platform_sp
->LoadPlatformBinaryAndSetup(process
, addr
, notify
))