LLDB mainline
RemoteAwarePlatform.cpp
Go to the documentation of this file.
1//===-- RemoteAwarePlatform.cpp -------------------------------------------===//
2//
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
6//
7//===----------------------------------------------------------------------===//
8
10#include "lldb/Core/Module.h"
14#include "lldb/Host/Host.h"
15#include "lldb/Host/HostInfo.h"
17#include <optional>
18
19using namespace lldb_private;
20using namespace lldb;
21
22bool RemoteAwarePlatform::GetModuleSpec(const FileSpec &module_file_spec,
23 const ArchSpec &arch,
24 ModuleSpec &module_spec) {
26 return m_remote_platform_sp->GetModuleSpec(module_file_spec, arch,
27 module_spec);
28
29 return false;
30}
31
33 const ModuleSpec &module_spec, ModuleSP &exe_module_sp,
34 const FileSpecList *module_search_paths_ptr) {
36 // Nothing special to do here, just use the actual file and architecture
37
38 char exe_path[PATH_MAX];
39 ModuleSpec resolved_module_spec(module_spec);
40
41 if (IsHost()) {
42 // If we have "ls" as the exe_file, resolve the executable location based
43 // on the current path variables
44 if (!FileSystem::Instance().Exists(resolved_module_spec.GetFileSpec())) {
45 resolved_module_spec.GetFileSpec().GetPath(exe_path, sizeof(exe_path));
46 resolved_module_spec.GetFileSpec().SetFile(exe_path,
47 FileSpec::Style::native);
48 FileSystem::Instance().Resolve(resolved_module_spec.GetFileSpec());
49 }
50
51 if (!FileSystem::Instance().Exists(resolved_module_spec.GetFileSpec()))
53 resolved_module_spec.GetFileSpec());
54
55 // Resolve any executable within a bundle on MacOSX
56 Host::ResolveExecutableInBundle(resolved_module_spec.GetFileSpec());
57
58 if (FileSystem::Instance().Exists(resolved_module_spec.GetFileSpec()))
59 error.Clear();
60 else {
61 const uint32_t permissions = FileSystem::Instance().GetPermissions(
62 resolved_module_spec.GetFileSpec());
63 if (permissions && (permissions & eFilePermissionsEveryoneR) == 0)
64 error.SetErrorStringWithFormat(
65 "executable '%s' is not readable",
66 resolved_module_spec.GetFileSpec().GetPath().c_str());
67 else
68 error.SetErrorStringWithFormat(
69 "unable to find executable for '%s'",
70 resolved_module_spec.GetFileSpec().GetPath().c_str());
71 }
72 } else {
74 return GetCachedExecutable(resolved_module_spec, exe_module_sp,
75 module_search_paths_ptr);
76 }
77
78 // We may connect to a process and use the provided executable (Don't use
79 // local $PATH).
80
81 // Resolve any executable within a bundle on MacOSX
82 Host::ResolveExecutableInBundle(resolved_module_spec.GetFileSpec());
83
84 if (FileSystem::Instance().Exists(resolved_module_spec.GetFileSpec()))
85 error.Clear();
86 else
87 error.SetErrorStringWithFormat("the platform is not currently "
88 "connected, and '%s' doesn't exist in "
89 "the system root.",
90 exe_path);
91 }
92
93 if (error.Success()) {
94 if (resolved_module_spec.GetArchitecture().IsValid()) {
95 error = ModuleList::GetSharedModule(resolved_module_spec, exe_module_sp,
96 module_search_paths_ptr, nullptr, nullptr);
97 if (error.Fail()) {
98 // If we failed, it may be because the vendor and os aren't known. If
99 // that is the case, try setting them to the host architecture and give
100 // it another try.
101 llvm::Triple &module_triple =
102 resolved_module_spec.GetArchitecture().GetTriple();
103 bool is_vendor_specified =
104 (module_triple.getVendor() != llvm::Triple::UnknownVendor);
105 bool is_os_specified =
106 (module_triple.getOS() != llvm::Triple::UnknownOS);
107 if (!is_vendor_specified || !is_os_specified) {
108 const llvm::Triple &host_triple =
109 HostInfo::GetArchitecture(HostInfo::eArchKindDefault).GetTriple();
110
111 if (!is_vendor_specified)
112 module_triple.setVendorName(host_triple.getVendorName());
113 if (!is_os_specified)
114 module_triple.setOSName(host_triple.getOSName());
115
116 error = ModuleList::GetSharedModule(resolved_module_spec,
117 exe_module_sp, module_search_paths_ptr, nullptr, nullptr);
118 }
119 }
120
121 // TODO find out why exe_module_sp might be NULL
122 if (error.Fail() || !exe_module_sp || !exe_module_sp->GetObjectFile()) {
123 exe_module_sp.reset();
124 error.SetErrorStringWithFormat(
125 "'%s' doesn't contain the architecture %s",
126 resolved_module_spec.GetFileSpec().GetPath().c_str(),
127 resolved_module_spec.GetArchitecture().GetArchitectureName());
128 }
129 } else {
130 // No valid architecture was specified, ask the platform for the
131 // architectures that we should be using (in the correct order) and see
132 // if we can find a match that way
133 StreamString arch_names;
134 llvm::ListSeparator LS;
135 ArchSpec process_host_arch;
136 for (const ArchSpec &arch :
137 GetSupportedArchitectures(process_host_arch)) {
138 resolved_module_spec.GetArchitecture() = arch;
139 error = ModuleList::GetSharedModule(resolved_module_spec, exe_module_sp,
140 module_search_paths_ptr, nullptr, nullptr);
141 // Did we find an executable using one of the
142 if (error.Success()) {
143 if (exe_module_sp && exe_module_sp->GetObjectFile())
144 break;
145 else
146 error.SetErrorToGenericError();
147 }
148
149 arch_names << LS << arch.GetArchitectureName();
150 }
151
152 if (error.Fail() || !exe_module_sp) {
153 if (FileSystem::Instance().Readable(
154 resolved_module_spec.GetFileSpec())) {
155 error.SetErrorStringWithFormatv(
156 "'{0}' doesn't contain any '{1}' platform architectures: {2}",
157 resolved_module_spec.GetFileSpec(), GetPluginName(),
158 arch_names.GetData());
159 } else {
160 error.SetErrorStringWithFormat(
161 "'%s' is not readable",
162 resolved_module_spec.GetFileSpec().GetPath().c_str());
163 }
164 }
165 }
166 }
167
168 return error;
169}
170
172 llvm::StringRef command, const FileSpec &working_dir, int *status_ptr,
173 int *signo_ptr, std::string *command_output,
174 const Timeout<std::micro> &timeout) {
175 return RunShellCommand(llvm::StringRef(), command, working_dir, status_ptr,
176 signo_ptr, command_output, timeout);
177}
178
180 llvm::StringRef shell, llvm::StringRef command, const FileSpec &working_dir,
181 int *status_ptr, int *signo_ptr, std::string *command_output,
182 const Timeout<std::micro> &timeout) {
184 return m_remote_platform_sp->RunShellCommand(shell, command, working_dir,
185 status_ptr, signo_ptr,
186 command_output, timeout);
187 return Platform::RunShellCommand(shell, command, working_dir, status_ptr,
188 signo_ptr, command_output, timeout);
189}
190
192 uint32_t file_permissions) {
194 return m_remote_platform_sp->MakeDirectory(file_spec, file_permissions);
195 return Platform::MakeDirectory(file_spec, file_permissions);
196}
197
199 uint32_t &file_permissions) {
201 return m_remote_platform_sp->GetFilePermissions(file_spec,
202 file_permissions);
203 return Platform::GetFilePermissions(file_spec, file_permissions);
204}
205
207 uint32_t file_permissions) {
209 return m_remote_platform_sp->SetFilePermissions(file_spec,
210 file_permissions);
211 return Platform::SetFilePermissions(file_spec, file_permissions);
212}
213
215 File::OpenOptions flags,
216 uint32_t mode, Status &error) {
218 return m_remote_platform_sp->OpenFile(file_spec, flags, mode, error);
219 return Platform::OpenFile(file_spec, flags, mode, error);
220}
221
224 return m_remote_platform_sp->CloseFile(fd, error);
225 return Platform::CloseFile(fd, error);
226}
227
229 void *dst, uint64_t dst_len,
230 Status &error) {
232 return m_remote_platform_sp->ReadFile(fd, offset, dst, dst_len, error);
233 return Platform::ReadFile(fd, offset, dst, dst_len, error);
234}
235
237 const void *src, uint64_t src_len,
238 Status &error) {
240 return m_remote_platform_sp->WriteFile(fd, offset, src, src_len, error);
241 return Platform::WriteFile(fd, offset, src, src_len, error);
242}
243
246 return m_remote_platform_sp->GetFileSize(file_spec);
247 return Platform::GetFileSize(file_spec);
248}
249
251 const FileSpec &dst) {
253 return m_remote_platform_sp->CreateSymlink(src, dst);
254 return Platform::CreateSymlink(src, dst);
255}
256
259 return m_remote_platform_sp->GetFileExists(file_spec);
260 return Platform::GetFileExists(file_spec);
261}
262
265 return m_remote_platform_sp->Unlink(file_spec);
266 return Platform::Unlink(file_spec);
267}
268
269llvm::ErrorOr<llvm::MD5::MD5Result>
272 return m_remote_platform_sp->CalculateMD5(file_spec);
273 return Platform::CalculateMD5(file_spec);
274}
275
278 return m_remote_platform_sp->GetRemoteWorkingDirectory();
280}
281
283 const FileSpec &working_dir) {
285 return m_remote_platform_sp->SetRemoteWorkingDirectory(working_dir);
286 return Platform::SetRemoteWorkingDirectory(working_dir);
287}
288
290 const UUID *uuid_ptr,
291 FileSpec &local_file) {
293 return m_remote_platform_sp->GetFileWithUUID(platform_file, uuid_ptr,
294 local_file);
295
296 // Default to the local case
297 local_file = platform_file;
298 return Status();
299}
300
303 m_os_version = m_remote_platform_sp->GetOSVersion();
304 return !m_os_version.empty();
305 }
306 return false;
307}
308
311 return m_remote_platform_sp->GetRemoteOSBuildString();
312 return std::nullopt;
313}
314
317 return m_remote_platform_sp->GetRemoteOSKernelDescription();
318 return std::nullopt;
319}
320
323 return m_remote_platform_sp->GetRemoteSystemArchitecture();
324 return ArchSpec();
325}
326
329 return m_remote_platform_sp->GetHostname();
330 return Platform::GetHostname();
331}
332
335 return m_remote_platform_sp->GetUserIDResolver();
337}
338
341 return m_remote_platform_sp->GetEnvironment();
343}
344
347 return m_remote_platform_sp->IsConnected();
348 return Platform::IsConnected();
349}
350
352 ProcessInstanceInfo &process_info) {
354 return m_remote_platform_sp->GetProcessInfo(pid, process_info);
355 return Platform::GetProcessInfo(pid, process_info);
356}
357
358uint32_t
360 ProcessInstanceInfoList &process_infos) {
362 return m_remote_platform_sp->FindProcesses(match_info, process_infos);
363 return Platform::FindProcesses(match_info, process_infos);
364}
365
367 llvm::StringRef plugin_name,
368 Debugger &debugger,
369 Target *target,
370 Status &error) {
372 return m_remote_platform_sp->ConnectProcess(connect_url, plugin_name,
373 debugger, target, error);
374 return Platform::ConnectProcess(connect_url, plugin_name, debugger, target,
375 error);
376}
377
380 return m_remote_platform_sp->LaunchProcess(launch_info);
381 return Platform::LaunchProcess(launch_info);
382}
383
386 return m_remote_platform_sp->KillProcess(pid);
387 return Platform::KillProcess(pid);
388}
389
391 Status &error) {
393 return m_remote_platform_sp->ConnectToWaitingProcesses(debugger, error);
395}
static llvm::raw_ostream & error(Stream &strm)
An architecture specification class.
Definition: ArchSpec.h:31
bool IsValid() const
Tests if this ArchSpec is valid.
Definition: ArchSpec.h:348
llvm::Triple & GetTriple()
Architecture triple accessor.
Definition: ArchSpec.h:450
const char * GetArchitectureName() const
Returns a static string representing the current architecture.
Definition: ArchSpec.cpp:552
A class to manage flag bits.
Definition: Debugger.h:79
A file collection class.
Definition: FileSpecList.h:85
A file utility class.
Definition: FileSpec.h:56
void SetFile(llvm::StringRef path, Style style)
Change the file specified with a new path.
Definition: FileSpec.cpp:174
size_t GetPath(char *path, size_t max_path_length, bool denormalize=true) const
Extract the full path to the file.
Definition: FileSpec.cpp:367
void Resolve(llvm::SmallVectorImpl< char > &path)
Resolve path to make it canonical.
bool ResolveExecutableLocation(FileSpec &file_spec)
Call into the Host to see if it can help find the file.
uint32_t GetPermissions(const FileSpec &file_spec) const
Return the current permissions of the given file.
static FileSystem & Instance()
static bool ResolveExecutableInBundle(FileSpec &file)
When executable files may live within a directory, where the directory represents an executable bundl...
static Status GetSharedModule(const ModuleSpec &module_spec, lldb::ModuleSP &module_sp, const FileSpecList *module_search_paths_ptr, llvm::SmallVectorImpl< lldb::ModuleSP > *old_modules, bool *did_create_ptr, bool always_create=false)
Definition: ModuleList.cpp:789
FileSpec & GetFileSpec()
Definition: ModuleSpec.h:53
ArchSpec & GetArchitecture()
Definition: ModuleSpec.h:89
virtual FileSpec GetRemoteWorkingDirectory()
Definition: Platform.h:250
virtual bool GetFileExists(const lldb_private::FileSpec &file_spec)
Definition: Platform.cpp:1284
virtual bool CloseFile(lldb::user_id_t fd, Status &error)
Definition: Platform.cpp:680
virtual bool IsConnected() const
Definition: Platform.h:462
virtual lldb::user_id_t OpenFile(const FileSpec &file_spec, File::OpenOptions flags, uint32_t mode, Status &error)
Definition: Platform.cpp:672
virtual const char * GetHostname()
Definition: Platform.cpp:722
virtual uint32_t FindProcesses(const ProcessInstanceInfoMatch &match_info, ProcessInstanceInfoList &proc_infos)
Attach to an existing process by process name.
Definition: Platform.cpp:982
llvm::VersionTuple m_os_version
Definition: Platform.h:960
virtual Status GetFilePermissions(const FileSpec &file_spec, uint32_t &file_permissions)
Definition: Platform.cpp:644
virtual Status MakeDirectory(const FileSpec &file_spec, uint32_t permissions)
Definition: Platform.cpp:632
virtual UserIDResolver & GetUserIDResolver()
Definition: Platform.cpp:716
virtual lldb::user_id_t GetFileSize(const FileSpec &file_spec)
Definition: Platform.cpp:686
Status GetCachedExecutable(ModuleSpec &module_spec, lldb::ModuleSP &module_sp, const FileSpecList *module_search_paths_ptr)
Definition: Platform.cpp:1512
virtual Status Unlink(const FileSpec &file_spec)
Definition: Platform.cpp:1290
virtual bool SetRemoteWorkingDirectory(const FileSpec &working_dir)
Definition: Platform.cpp:735
virtual lldb::ProcessSP ConnectProcess(llvm::StringRef connect_url, llvm::StringRef plugin_name, Debugger &debugger, Target *target, Status &error)
Definition: Platform.cpp:1933
virtual Status LaunchProcess(ProcessLaunchInfo &launch_info)
Launch a new process on a platform, not necessarily for debugging, it could be just for running the p...
Definition: Platform.cpp:1000
virtual Status KillProcess(const lldb::pid_t pid)
Kill process on a platform.
Definition: Platform.cpp:1054
virtual Status CreateSymlink(const FileSpec &src, const FileSpec &dst)
Definition: Platform.cpp:1276
virtual size_t ConnectToWaitingProcesses(lldb_private::Debugger &debugger, lldb_private::Status &error)
Connect to all processes waiting for a debugger to attach.
Definition: Platform.cpp:2005
virtual uint64_t WriteFile(lldb::user_id_t fd, uint64_t offset, const void *src, uint64_t src_len, Status &error)
Definition: Platform.cpp:706
bool IsRemote() const
Definition: Platform.h:460
virtual Status SetFilePermissions(const FileSpec &file_spec, uint32_t file_permissions)
Definition: Platform.cpp:659
virtual bool GetProcessInfo(lldb::pid_t pid, ProcessInstanceInfo &proc_info)
Definition: Platform.cpp:973
bool IsHost() const
Definition: Platform.h:456
virtual lldb_private::Status RunShellCommand(llvm::StringRef command, const FileSpec &working_dir, int *status_ptr, int *signo_ptr, std::string *command_output, const Timeout< std::micro > &timeout)
Definition: Platform.cpp:1310
virtual Environment GetEnvironment()
Definition: Platform.cpp:1494
virtual std::vector< ArchSpec > GetSupportedArchitectures(const ArchSpec &process_host_arch)=0
Get the platform's supported architectures in the order in which they should be searched.
virtual llvm::ErrorOr< llvm::MD5::MD5Result > CalculateMD5(const FileSpec &file_spec)
Definition: Platform.cpp:1343
virtual uint64_t ReadFile(lldb::user_id_t fd, uint64_t offset, void *dst, uint64_t dst_len, Status &error)
Definition: Platform.cpp:696
virtual llvm::StringRef GetPluginName()=0
size_t ConnectToWaitingProcesses(Debugger &debugger, Status &error) override
Connect to all processes waiting for a debugger to attach.
Status ResolveExecutable(const ModuleSpec &module_spec, lldb::ModuleSP &module_sp, const FileSpecList *module_search_paths_ptr) override
Find a platform plugin for a given process.
uint64_t WriteFile(lldb::user_id_t fd, uint64_t offset, const void *src, uint64_t src_len, Status &error) override
uint64_t ReadFile(lldb::user_id_t fd, uint64_t offset, void *dst, uint64_t dst_len, Status &error) override
bool CloseFile(lldb::user_id_t fd, Status &error) override
Status GetFileWithUUID(const FileSpec &platform_file, const UUID *uuid, FileSpec &local_file) override
Locate a file for a platform.
std::optional< std::string > GetRemoteOSBuildString() override
bool GetModuleSpec(const FileSpec &module_file_spec, const ArchSpec &arch, ModuleSpec &module_spec) override
llvm::ErrorOr< llvm::MD5::MD5Result > CalculateMD5(const FileSpec &file_spec) override
Status KillProcess(const lldb::pid_t pid) override
Kill process on a platform.
bool GetProcessInfo(lldb::pid_t pid, ProcessInstanceInfo &proc_info) override
bool GetFileExists(const FileSpec &file_spec) override
std::optional< std::string > GetRemoteOSKernelDescription() override
Status SetFilePermissions(const FileSpec &file_spec, uint32_t file_permissions) override
lldb::ProcessSP ConnectProcess(llvm::StringRef connect_url, llvm::StringRef plugin_name, Debugger &debugger, Target *target, Status &error) override
Status MakeDirectory(const FileSpec &file_spec, uint32_t mode) override
lldb_private::Environment GetEnvironment() override
lldb::user_id_t OpenFile(const FileSpec &file_spec, File::OpenOptions flags, uint32_t mode, Status &error) override
Status RunShellCommand(llvm::StringRef command, const FileSpec &working_dir, int *status_ptr, int *signo_ptr, std::string *command_output, const Timeout< std::micro > &timeout) override
Status LaunchProcess(ProcessLaunchInfo &launch_info) override
Launch a new process on a platform, not necessarily for debugging, it could be just for running the p...
Status GetFilePermissions(const FileSpec &file_spec, uint32_t &file_permissions) override
lldb::user_id_t GetFileSize(const FileSpec &file_spec) override
bool SetRemoteWorkingDirectory(const FileSpec &working_dir) override
Status Unlink(const FileSpec &file_spec) override
Status CreateSymlink(const FileSpec &src, const FileSpec &dst) override
UserIDResolver & GetUserIDResolver() override
uint32_t FindProcesses(const ProcessInstanceInfoMatch &match_info, ProcessInstanceInfoList &process_infos) override
Attach to an existing process by process name.
An error handling class.
Definition: Status.h:44
const char * GetData() const
Definition: StreamString.h:43
An abstract interface for things that know how to map numeric user/group IDs into names.
A class that represents a running process on the host machine.
Definition: SBAttachInfo.h:14
std::vector< ProcessInstanceInfo > ProcessInstanceInfoList
Definition: Host.h:32
Definition: SBAddress.h:15
std::shared_ptr< lldb_private::Process > ProcessSP
Definition: lldb-forward.h:381
uint64_t pid_t
Definition: lldb-types.h:81
uint64_t user_id_t
Definition: lldb-types.h:80
std::shared_ptr< lldb_private::Module > ModuleSP
Definition: lldb-forward.h:365
#define PATH_MAX