1 //===-- RemoteAwarePlatform.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 //===----------------------------------------------------------------------===//
9 #include "lldb/Target/RemoteAwarePlatform.h"
10 #include "lldb/Core/Module.h"
11 #include "lldb/Core/ModuleList.h"
12 #include "lldb/Core/ModuleSpec.h"
13 #include "lldb/Host/FileSystem.h"
14 #include "lldb/Host/Host.h"
15 #include "lldb/Host/HostInfo.h"
16 #include "lldb/Utility/StreamString.h"
19 using namespace lldb_private
;
22 bool RemoteAwarePlatform::GetModuleSpec(const FileSpec
&module_file_spec
,
24 ModuleSpec
&module_spec
) {
25 if (m_remote_platform_sp
)
26 return m_remote_platform_sp
->GetModuleSpec(module_file_spec
, arch
,
32 Status
RemoteAwarePlatform::ResolveExecutable(
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
38 char exe_path
[PATH_MAX
];
39 ModuleSpec
resolved_module_spec(module_spec
);
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());
51 if (!FileSystem::Instance().Exists(resolved_module_spec
.GetFileSpec()))
52 FileSystem::Instance().ResolveExecutableLocation(
53 resolved_module_spec
.GetFileSpec());
55 // Resolve any executable within a bundle on MacOSX
56 Host::ResolveExecutableInBundle(resolved_module_spec
.GetFileSpec());
58 if (FileSystem::Instance().Exists(resolved_module_spec
.GetFileSpec()))
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());
68 error
.SetErrorStringWithFormat(
69 "unable to find executable for '%s'",
70 resolved_module_spec
.GetFileSpec().GetPath().c_str());
73 if (m_remote_platform_sp
) {
74 return GetCachedExecutable(resolved_module_spec
, exe_module_sp
,
75 module_search_paths_ptr
);
78 // We may connect to a process and use the provided executable (Don't use
81 // Resolve any executable within a bundle on MacOSX
82 Host::ResolveExecutableInBundle(resolved_module_spec
.GetFileSpec());
84 if (FileSystem::Instance().Exists(resolved_module_spec
.GetFileSpec()))
87 error
.SetErrorStringWithFormat("the platform is not currently "
88 "connected, and '%s' doesn't exist in "
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);
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
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();
111 if (!is_vendor_specified
)
112 module_triple
.setVendorName(host_triple
.getVendorName());
113 if (!is_os_specified
)
114 module_triple
.setOSName(host_triple
.getOSName());
116 error
= ModuleList::GetSharedModule(resolved_module_spec
,
117 exe_module_sp
, module_search_paths_ptr
, nullptr, nullptr);
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());
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())
146 error
.SetErrorToGenericError();
149 arch_names
<< LS
<< arch
.GetArchitectureName();
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());
160 error
.SetErrorStringWithFormat(
161 "'%s' is not readable",
162 resolved_module_spec
.GetFileSpec().GetPath().c_str());
171 Status
RemoteAwarePlatform::RunShellCommand(
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
);
179 Status
RemoteAwarePlatform::RunShellCommand(
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
) {
183 if (m_remote_platform_sp
)
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
);
191 Status
RemoteAwarePlatform::MakeDirectory(const FileSpec
&file_spec
,
192 uint32_t file_permissions
) {
193 if (m_remote_platform_sp
)
194 return m_remote_platform_sp
->MakeDirectory(file_spec
, file_permissions
);
195 return Platform::MakeDirectory(file_spec
, file_permissions
);
198 Status
RemoteAwarePlatform::GetFilePermissions(const FileSpec
&file_spec
,
199 uint32_t &file_permissions
) {
200 if (m_remote_platform_sp
)
201 return m_remote_platform_sp
->GetFilePermissions(file_spec
,
203 return Platform::GetFilePermissions(file_spec
, file_permissions
);
206 Status
RemoteAwarePlatform::SetFilePermissions(const FileSpec
&file_spec
,
207 uint32_t file_permissions
) {
208 if (m_remote_platform_sp
)
209 return m_remote_platform_sp
->SetFilePermissions(file_spec
,
211 return Platform::SetFilePermissions(file_spec
, file_permissions
);
214 lldb::user_id_t
RemoteAwarePlatform::OpenFile(const FileSpec
&file_spec
,
215 File::OpenOptions flags
,
216 uint32_t mode
, Status
&error
) {
217 if (m_remote_platform_sp
)
218 return m_remote_platform_sp
->OpenFile(file_spec
, flags
, mode
, error
);
219 return Platform::OpenFile(file_spec
, flags
, mode
, error
);
222 bool RemoteAwarePlatform::CloseFile(lldb::user_id_t fd
, Status
&error
) {
223 if (m_remote_platform_sp
)
224 return m_remote_platform_sp
->CloseFile(fd
, error
);
225 return Platform::CloseFile(fd
, error
);
228 uint64_t RemoteAwarePlatform::ReadFile(lldb::user_id_t fd
, uint64_t offset
,
229 void *dst
, uint64_t dst_len
,
231 if (m_remote_platform_sp
)
232 return m_remote_platform_sp
->ReadFile(fd
, offset
, dst
, dst_len
, error
);
233 return Platform::ReadFile(fd
, offset
, dst
, dst_len
, error
);
236 uint64_t RemoteAwarePlatform::WriteFile(lldb::user_id_t fd
, uint64_t offset
,
237 const void *src
, uint64_t src_len
,
239 if (m_remote_platform_sp
)
240 return m_remote_platform_sp
->WriteFile(fd
, offset
, src
, src_len
, error
);
241 return Platform::WriteFile(fd
, offset
, src
, src_len
, error
);
244 lldb::user_id_t
RemoteAwarePlatform::GetFileSize(const FileSpec
&file_spec
) {
245 if (m_remote_platform_sp
)
246 return m_remote_platform_sp
->GetFileSize(file_spec
);
247 return Platform::GetFileSize(file_spec
);
250 Status
RemoteAwarePlatform::CreateSymlink(const FileSpec
&src
,
251 const FileSpec
&dst
) {
252 if (m_remote_platform_sp
)
253 return m_remote_platform_sp
->CreateSymlink(src
, dst
);
254 return Platform::CreateSymlink(src
, dst
);
257 bool RemoteAwarePlatform::GetFileExists(const FileSpec
&file_spec
) {
258 if (m_remote_platform_sp
)
259 return m_remote_platform_sp
->GetFileExists(file_spec
);
260 return Platform::GetFileExists(file_spec
);
263 Status
RemoteAwarePlatform::Unlink(const FileSpec
&file_spec
) {
264 if (m_remote_platform_sp
)
265 return m_remote_platform_sp
->Unlink(file_spec
);
266 return Platform::Unlink(file_spec
);
269 bool RemoteAwarePlatform::CalculateMD5(const FileSpec
&file_spec
, uint64_t &low
,
271 if (m_remote_platform_sp
)
272 return m_remote_platform_sp
->CalculateMD5(file_spec
, low
, high
);
273 return Platform::CalculateMD5(file_spec
, low
, high
);
276 FileSpec
RemoteAwarePlatform::GetRemoteWorkingDirectory() {
277 if (IsRemote() && m_remote_platform_sp
)
278 return m_remote_platform_sp
->GetRemoteWorkingDirectory();
279 return Platform::GetRemoteWorkingDirectory();
282 bool RemoteAwarePlatform::SetRemoteWorkingDirectory(
283 const FileSpec
&working_dir
) {
284 if (IsRemote() && m_remote_platform_sp
)
285 return m_remote_platform_sp
->SetRemoteWorkingDirectory(working_dir
);
286 return Platform::SetRemoteWorkingDirectory(working_dir
);
289 Status
RemoteAwarePlatform::GetFileWithUUID(const FileSpec
&platform_file
,
290 const UUID
*uuid_ptr
,
291 FileSpec
&local_file
) {
292 if (IsRemote() && m_remote_platform_sp
)
293 return m_remote_platform_sp
->GetFileWithUUID(platform_file
, uuid_ptr
,
296 // Default to the local case
297 local_file
= platform_file
;
301 bool RemoteAwarePlatform::GetRemoteOSVersion() {
302 if (m_remote_platform_sp
) {
303 m_os_version
= m_remote_platform_sp
->GetOSVersion();
304 return !m_os_version
.empty();
309 std::optional
<std::string
> RemoteAwarePlatform::GetRemoteOSBuildString() {
310 if (m_remote_platform_sp
)
311 return m_remote_platform_sp
->GetRemoteOSBuildString();
315 std::optional
<std::string
> RemoteAwarePlatform::GetRemoteOSKernelDescription() {
316 if (m_remote_platform_sp
)
317 return m_remote_platform_sp
->GetRemoteOSKernelDescription();
321 ArchSpec
RemoteAwarePlatform::GetRemoteSystemArchitecture() {
322 if (m_remote_platform_sp
)
323 return m_remote_platform_sp
->GetRemoteSystemArchitecture();
327 const char *RemoteAwarePlatform::GetHostname() {
328 if (m_remote_platform_sp
)
329 return m_remote_platform_sp
->GetHostname();
330 return Platform::GetHostname();
333 UserIDResolver
&RemoteAwarePlatform::GetUserIDResolver() {
334 if (m_remote_platform_sp
)
335 return m_remote_platform_sp
->GetUserIDResolver();
336 return Platform::GetUserIDResolver();
339 Environment
RemoteAwarePlatform::GetEnvironment() {
340 if (m_remote_platform_sp
)
341 return m_remote_platform_sp
->GetEnvironment();
342 return Platform::GetEnvironment();
345 bool RemoteAwarePlatform::IsConnected() const {
346 if (m_remote_platform_sp
)
347 return m_remote_platform_sp
->IsConnected();
348 return Platform::IsConnected();
351 bool RemoteAwarePlatform::GetProcessInfo(lldb::pid_t pid
,
352 ProcessInstanceInfo
&process_info
) {
353 if (m_remote_platform_sp
)
354 return m_remote_platform_sp
->GetProcessInfo(pid
, process_info
);
355 return Platform::GetProcessInfo(pid
, process_info
);
359 RemoteAwarePlatform::FindProcesses(const ProcessInstanceInfoMatch
&match_info
,
360 ProcessInstanceInfoList
&process_infos
) {
361 if (m_remote_platform_sp
)
362 return m_remote_platform_sp
->FindProcesses(match_info
, process_infos
);
363 return Platform::FindProcesses(match_info
, process_infos
);
366 lldb::ProcessSP
RemoteAwarePlatform::ConnectProcess(llvm::StringRef connect_url
,
367 llvm::StringRef plugin_name
,
371 if (m_remote_platform_sp
)
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
,
378 Status
RemoteAwarePlatform::LaunchProcess(ProcessLaunchInfo
&launch_info
) {
379 if (m_remote_platform_sp
)
380 return m_remote_platform_sp
->LaunchProcess(launch_info
);
381 return Platform::LaunchProcess(launch_info
);
384 Status
RemoteAwarePlatform::KillProcess(const lldb::pid_t pid
) {
385 if (m_remote_platform_sp
)
386 return m_remote_platform_sp
->KillProcess(pid
);
387 return Platform::KillProcess(pid
);
390 size_t RemoteAwarePlatform::ConnectToWaitingProcesses(Debugger
&debugger
,
392 if (m_remote_platform_sp
)
393 return m_remote_platform_sp
->ConnectToWaitingProcesses(debugger
, error
);
394 return Platform::ConnectToWaitingProcesses(debugger
, error
);