LLDB mainline
SBPlatform.cpp
Go to the documentation of this file.
1//===-- SBPlatform.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
11#include "lldb/API/SBError.h"
12#include "lldb/API/SBFileSpec.h"
14#include "lldb/API/SBPlatform.h"
16#include "lldb/Host/File.h"
18#include "lldb/Target/Target.h"
20#include "lldb/Utility/Args.h"
22#include "lldb/Utility/Status.h"
23
24#include "llvm/Support/FileSystem.h"
25
26#include <functional>
27
28using namespace lldb;
29using namespace lldb_private;
30
31// PlatformConnectOptions
33 PlatformConnectOptions(const char *url = nullptr) {
34 if (url && url[0])
35 m_url = url;
36 }
37
39
40 std::string m_url;
41 std::string m_rsync_options;
43 bool m_rsync_enabled = false;
46};
47
48// PlatformShellCommand
50 PlatformShellCommand(llvm::StringRef shell_interpreter,
51 llvm::StringRef shell_command) {
52 if (!shell_interpreter.empty())
53 m_shell = shell_interpreter.str();
54
55 if (!m_shell.empty() && !shell_command.empty())
56 m_command = shell_command.str();
57 }
58
59 PlatformShellCommand(llvm::StringRef shell_command = llvm::StringRef()) {
60 if (!shell_command.empty())
61 m_command = shell_command.str();
62 }
63
65
66 std::string m_shell;
67 std::string m_command;
68 std::string m_working_dir;
69 std::string m_output;
70 int m_status = 0;
71 int m_signo = 0;
73};
74// SBPlatformConnectOptions
76 : m_opaque_ptr(new PlatformConnectOptions(url)) {
77 LLDB_INSTRUMENT_VA(this, url);
78}
79
81 const SBPlatformConnectOptions &rhs)
82 : m_opaque_ptr(new PlatformConnectOptions()) {
83 LLDB_INSTRUMENT_VA(this, rhs);
84
86}
87
89
92 LLDB_INSTRUMENT_VA(this, rhs);
93
95 return *this;
96}
97
100
101 if (m_opaque_ptr->m_url.empty())
102 return nullptr;
103 return ConstString(m_opaque_ptr->m_url.c_str()).GetCString();
104}
105
106void SBPlatformConnectOptions::SetURL(const char *url) {
107 LLDB_INSTRUMENT_VA(this, url);
108
109 if (url && url[0])
110 m_opaque_ptr->m_url = url;
111 else
112 m_opaque_ptr->m_url.clear();
113}
114
116 LLDB_INSTRUMENT_VA(this);
117
119}
120
122 const char *options, const char *remote_path_prefix,
123 bool omit_hostname_from_remote_path) {
124 LLDB_INSTRUMENT_VA(this, options, remote_path_prefix,
125 omit_hostname_from_remote_path);
126
129 omit_hostname_from_remote_path;
130 if (remote_path_prefix && remote_path_prefix[0])
131 m_opaque_ptr->m_rsync_remote_path_prefix = remote_path_prefix;
132 else
134
135 if (options && options[0])
136 m_opaque_ptr->m_rsync_options = options;
137 else
139}
140
142 LLDB_INSTRUMENT_VA(this);
143
145}
146
148 LLDB_INSTRUMENT_VA(this);
149
151}
152
154 LLDB_INSTRUMENT_VA(this, path);
155
156 if (path && path[0])
158 else
160}
161
162// SBPlatformShellCommand
164 const char *shell_command)
165 : m_opaque_ptr(new PlatformShellCommand(shell_interpreter, shell_command)) {
166 LLDB_INSTRUMENT_VA(this, shell_interpreter, shell_command);
167}
168
170 : m_opaque_ptr(new PlatformShellCommand(shell_command)) {
171 LLDB_INSTRUMENT_VA(this, shell_command);
172}
173
175 const SBPlatformShellCommand &rhs)
176 : m_opaque_ptr(new PlatformShellCommand()) {
177 LLDB_INSTRUMENT_VA(this, rhs);
178
180}
181
184
185 LLDB_INSTRUMENT_VA(this, rhs);
186
188 return *this;
189}
190
192
194 LLDB_INSTRUMENT_VA(this);
195
196 m_opaque_ptr->m_output = std::string();
199}
200
202 LLDB_INSTRUMENT_VA(this);
203
204 if (m_opaque_ptr->m_shell.empty())
205 return nullptr;
206 return ConstString(m_opaque_ptr->m_shell.c_str()).GetCString();
207}
208
209void SBPlatformShellCommand::SetShell(const char *shell_interpreter) {
210 LLDB_INSTRUMENT_VA(this, shell_interpreter);
211
212 if (shell_interpreter && shell_interpreter[0])
213 m_opaque_ptr->m_shell = shell_interpreter;
214 else
215 m_opaque_ptr->m_shell.clear();
216}
217
219 LLDB_INSTRUMENT_VA(this);
220
221 if (m_opaque_ptr->m_command.empty())
222 return nullptr;
223 return ConstString(m_opaque_ptr->m_command.c_str()).GetCString();
224}
225
226void SBPlatformShellCommand::SetCommand(const char *shell_command) {
227 LLDB_INSTRUMENT_VA(this, shell_command);
228
229 if (shell_command && shell_command[0])
230 m_opaque_ptr->m_command = shell_command;
231 else
232 m_opaque_ptr->m_command.clear();
233}
234
236 LLDB_INSTRUMENT_VA(this);
237
238 if (m_opaque_ptr->m_working_dir.empty())
239 return nullptr;
241}
242
244 LLDB_INSTRUMENT_VA(this, path);
245
246 if (path && path[0])
248 else
250}
251
253 LLDB_INSTRUMENT_VA(this);
254
256 return m_opaque_ptr->m_timeout->count();
257 return UINT32_MAX;
258}
259
261 LLDB_INSTRUMENT_VA(this, sec);
262
263 if (sec == UINT32_MAX)
264 m_opaque_ptr->m_timeout = std::nullopt;
265 else
266 m_opaque_ptr->m_timeout = std::chrono::seconds(sec);
267}
268
270 LLDB_INSTRUMENT_VA(this);
271
272 return m_opaque_ptr->m_signo;
273}
274
276 LLDB_INSTRUMENT_VA(this);
277
278 return m_opaque_ptr->m_status;
279}
280
282 LLDB_INSTRUMENT_VA(this);
283
284 if (m_opaque_ptr->m_output.empty())
285 return nullptr;
286 return ConstString(m_opaque_ptr->m_output.c_str()).GetCString();
287}
288
289// SBPlatform
291
292SBPlatform::SBPlatform(const char *platform_name) {
293 LLDB_INSTRUMENT_VA(this, platform_name);
294
295 m_opaque_sp = Platform::Create(platform_name);
296}
297
299 LLDB_INSTRUMENT_VA(this, rhs);
300
302}
303
305 LLDB_INSTRUMENT_VA(this, rhs);
306
308 return *this;
309}
310
311SBPlatform::~SBPlatform() = default;
312
315
316 SBPlatform host_platform;
317 host_platform.m_opaque_sp = Platform::GetHostPlatform();
318 return host_platform;
319}
320
322 LLDB_INSTRUMENT_VA(this);
323 return this->operator bool();
324}
325SBPlatform::operator bool() const {
326 LLDB_INSTRUMENT_VA(this);
327
328 return m_opaque_sp.get() != nullptr;
329}
330
332 LLDB_INSTRUMENT_VA(this);
333
334 m_opaque_sp.reset();
335}
336
337const char *SBPlatform::GetName() {
338 LLDB_INSTRUMENT_VA(this);
339
340 PlatformSP platform_sp(GetSP());
341 if (platform_sp)
342 return ConstString(platform_sp->GetName()).AsCString();
343 return nullptr;
344}
345
346lldb::PlatformSP SBPlatform::GetSP() const { return m_opaque_sp; }
347
348void SBPlatform::SetSP(const lldb::PlatformSP &platform_sp) {
349 m_opaque_sp = platform_sp;
350}
351
353 LLDB_INSTRUMENT_VA(this);
354
355 PlatformSP platform_sp(GetSP());
356 if (platform_sp)
357 return platform_sp->GetWorkingDirectory().GetPathAsConstString().AsCString();
358 return nullptr;
359}
360
361bool SBPlatform::SetWorkingDirectory(const char *path) {
362 LLDB_INSTRUMENT_VA(this, path);
363
364 PlatformSP platform_sp(GetSP());
365 if (platform_sp) {
366 if (path)
367 platform_sp->SetWorkingDirectory(FileSpec(path));
368 else
369 platform_sp->SetWorkingDirectory(FileSpec());
370 return true;
371 }
372 return false;
373}
374
376 LLDB_INSTRUMENT_VA(this, connect_options);
377
378 SBError sb_error;
379 PlatformSP platform_sp(GetSP());
380 if (platform_sp && connect_options.GetURL()) {
381 Args args;
382 args.AppendArgument(connect_options.GetURL());
383 sb_error.ref() = platform_sp->ConnectRemote(args);
384 } else {
385 sb_error.SetErrorString("invalid platform");
386 }
387 return sb_error;
388}
389
391 LLDB_INSTRUMENT_VA(this);
392
393 PlatformSP platform_sp(GetSP());
394 if (platform_sp)
395 platform_sp->DisconnectRemote();
396}
397
399 LLDB_INSTRUMENT_VA(this);
400
401 PlatformSP platform_sp(GetSP());
402 if (platform_sp)
403 return platform_sp->IsConnected();
404 return false;
405}
406
408 LLDB_INSTRUMENT_VA(this);
409
410 PlatformSP platform_sp(GetSP());
411 if (platform_sp) {
412 ArchSpec arch(platform_sp->GetSystemArchitecture());
413 if (arch.IsValid()) {
414 // Const-ify the string so we don't need to worry about the lifetime of
415 // the string
416 return ConstString(arch.GetTriple().getTriple().c_str()).GetCString();
417 }
418 }
419 return nullptr;
420}
421
423 LLDB_INSTRUMENT_VA(this);
424
425 PlatformSP platform_sp(GetSP());
426 if (platform_sp) {
427 std::string s = platform_sp->GetOSBuildString().value_or("");
428 if (!s.empty()) {
429 // Const-ify the string so we don't need to worry about the lifetime of
430 // the string
431 return ConstString(s).GetCString();
432 }
433 }
434 return nullptr;
435}
436
438 LLDB_INSTRUMENT_VA(this);
439
440 PlatformSP platform_sp(GetSP());
441 if (platform_sp) {
442 std::string s = platform_sp->GetOSKernelDescription().value_or("");
443 if (!s.empty()) {
444 // Const-ify the string so we don't need to worry about the lifetime of
445 // the string
446 return ConstString(s.c_str()).GetCString();
447 }
448 }
449 return nullptr;
450}
451
453 LLDB_INSTRUMENT_VA(this);
454
455 PlatformSP platform_sp(GetSP());
456 if (platform_sp)
457 return ConstString(platform_sp->GetHostname()).GetCString();
458 return nullptr;
459}
460
462 LLDB_INSTRUMENT_VA(this);
463
464 llvm::VersionTuple version;
465 if (PlatformSP platform_sp = GetSP())
466 version = platform_sp->GetOSVersion();
467 return version.empty() ? UINT32_MAX : version.getMajor();
468}
469
471 LLDB_INSTRUMENT_VA(this);
472
473 llvm::VersionTuple version;
474 if (PlatformSP platform_sp = GetSP())
475 version = platform_sp->GetOSVersion();
476 return version.getMinor().value_or(UINT32_MAX);
477}
478
480 LLDB_INSTRUMENT_VA(this);
481
482 llvm::VersionTuple version;
483 if (PlatformSP platform_sp = GetSP())
484 version = platform_sp->GetOSVersion();
485 return version.getSubminor().value_or(UINT32_MAX);
486}
487
488void SBPlatform::SetSDKRoot(const char *sysroot) {
489 LLDB_INSTRUMENT_VA(this, sysroot);
490 if (PlatformSP platform_sp = GetSP())
491 platform_sp->SetSDKRootDirectory(ConstString(sysroot));
492}
493
495 LLDB_INSTRUMENT_VA(this, src, dst);
496
497 SBError sb_error;
498 PlatformSP platform_sp(GetSP());
499 if (platform_sp) {
500 sb_error.ref() = platform_sp->GetFile(src.ref(), dst.ref());
501 } else {
502 sb_error.SetErrorString("invalid platform");
503 }
504 return sb_error;
505}
506
508 LLDB_INSTRUMENT_VA(this, src, dst);
509 return ExecuteConnected([&](const lldb::PlatformSP &platform_sp) {
510 if (src.Exists()) {
511 uint32_t permissions = FileSystem::Instance().GetPermissions(src.ref());
512 if (permissions == 0) {
513 if (FileSystem::Instance().IsDirectory(src.ref()))
514 permissions = eFilePermissionsDirectoryDefault;
515 else
516 permissions = eFilePermissionsFileDefault;
517 }
518
519 return platform_sp->PutFile(src.ref(), dst.ref(), permissions);
520 }
521
523 error.SetErrorStringWithFormat("'src' argument doesn't exist: '%s'",
524 src.ref().GetPath().c_str());
525 return error;
526 });
527}
528
530 LLDB_INSTRUMENT_VA(this, src, dst);
531 return ExecuteConnected([&](const lldb::PlatformSP &platform_sp) {
532 if (src.Exists())
533 return platform_sp->Install(src.ref(), dst.ref());
534
536 error.SetErrorStringWithFormat("'src' argument doesn't exist: '%s'",
537 src.ref().GetPath().c_str());
538 return error;
539 });
540}
541
543 LLDB_INSTRUMENT_VA(this, shell_command);
544 return ExecuteConnected(
545 [&](const lldb::PlatformSP &platform_sp) {
546 const char *command = shell_command.GetCommand();
547 if (!command)
548 return Status("invalid shell command (empty)");
549
550 if (shell_command.GetWorkingDirectory() == nullptr) {
551 std::string platform_working_dir =
552 platform_sp->GetWorkingDirectory().GetPath();
553 if (!platform_working_dir.empty())
554 shell_command.SetWorkingDirectory(platform_working_dir.c_str());
555 }
556 return platform_sp->RunShellCommand(
557 shell_command.m_opaque_ptr->m_shell, command,
558 FileSpec(shell_command.GetWorkingDirectory()),
559 &shell_command.m_opaque_ptr->m_status,
560 &shell_command.m_opaque_ptr->m_signo,
561 &shell_command.m_opaque_ptr->m_output,
562 shell_command.m_opaque_ptr->m_timeout);
563 });
564}
565
567 LLDB_INSTRUMENT_VA(this, launch_info);
568 return ExecuteConnected([&](const lldb::PlatformSP &platform_sp) {
569 ProcessLaunchInfo info = launch_info.ref();
570 Status error = platform_sp->LaunchProcess(info);
571 launch_info.set_ref(info);
572 return error;
573 });
574}
575
577 LLDB_INSTRUMENT_VA(this, pid);
578 return ExecuteConnected([&](const lldb::PlatformSP &platform_sp) {
579 return platform_sp->KillProcess(pid);
580 });
581}
582
584 const std::function<Status(const lldb::PlatformSP &)> &func) {
585 SBError sb_error;
586 const auto platform_sp(GetSP());
587 if (platform_sp) {
588 if (platform_sp->IsConnected())
589 sb_error.ref() = func(platform_sp);
590 else
591 sb_error.SetErrorString("not connected");
592 } else
593 sb_error.SetErrorString("invalid platform");
594
595 return sb_error;
596}
597
598SBError SBPlatform::MakeDirectory(const char *path, uint32_t file_permissions) {
599 LLDB_INSTRUMENT_VA(this, path, file_permissions);
600
601 SBError sb_error;
602 PlatformSP platform_sp(GetSP());
603 if (platform_sp) {
604 sb_error.ref() =
605 platform_sp->MakeDirectory(FileSpec(path), file_permissions);
606 } else {
607 sb_error.SetErrorString("invalid platform");
608 }
609 return sb_error;
610}
611
613 LLDB_INSTRUMENT_VA(this, path);
614
615 PlatformSP platform_sp(GetSP());
616 if (platform_sp) {
617 uint32_t file_permissions = 0;
618 platform_sp->GetFilePermissions(FileSpec(path), file_permissions);
619 return file_permissions;
620 }
621 return 0;
622}
623
625 uint32_t file_permissions) {
626 LLDB_INSTRUMENT_VA(this, path, file_permissions);
627
628 SBError sb_error;
629 PlatformSP platform_sp(GetSP());
630 if (platform_sp) {
631 sb_error.ref() =
632 platform_sp->SetFilePermissions(FileSpec(path), file_permissions);
633 } else {
634 sb_error.SetErrorString("invalid platform");
635 }
636 return sb_error;
637}
638
640 LLDB_INSTRUMENT_VA(this);
641
642 if (auto platform_sp = GetSP())
643 return SBUnixSignals{platform_sp};
644
645 return SBUnixSignals();
646}
647
649 LLDB_INSTRUMENT_VA(this);
650 PlatformSP platform_sp(GetSP());
651
652 if (platform_sp) {
653 return SBEnvironment(platform_sp->GetEnvironment());
654 }
655
656 return SBEnvironment();
657}
static llvm::raw_ostream & error(Stream &strm)
#define LLDB_INSTRUMENT()
#define LLDB_INSTRUMENT_VA(...)
void SetErrorString(const char *err_str)
Definition: SBError.cpp:132
lldb_private::Status & ref()
Definition: SBError.cpp:167
const lldb_private::FileSpec & ref() const
Definition: SBFileSpec.cpp:162
bool Exists() const
Definition: SBFileSpec.cpp:86
void set_ref(const lldb_private::ProcessLaunchInfo &info)
const lldb_private::ProcessLaunchInfo & ref() const
PlatformConnectOptions * m_opaque_ptr
Definition: SBPlatform.h:49
const char * GetLocalCacheDirectory()
Definition: SBPlatform.cpp:147
SBPlatformConnectOptions(const char *url)
Definition: SBPlatform.cpp:75
void EnableRsync(const char *options, const char *remote_path_prefix, bool omit_remote_hostname)
Definition: SBPlatform.cpp:121
SBPlatformConnectOptions & operator=(const SBPlatformConnectOptions &rhs)
Definition: SBPlatform.cpp:91
void SetURL(const char *url)
Definition: SBPlatform.cpp:106
void SetLocalCacheDirectory(const char *path)
Definition: SBPlatform.cpp:153
SBPlatformShellCommand & operator=(const SBPlatformShellCommand &rhs)
Definition: SBPlatform.cpp:183
void SetCommand(const char *shell_command)
Definition: SBPlatform.cpp:226
void SetShell(const char *shell)
Definition: SBPlatform.cpp:209
PlatformShellCommand * m_opaque_ptr
Definition: SBPlatform.h:90
void SetTimeoutSeconds(uint32_t sec)
Definition: SBPlatform.cpp:260
void SetWorkingDirectory(const char *path)
Definition: SBPlatform.cpp:243
const char * GetWorkingDirectory()
Definition: SBPlatform.cpp:235
SBPlatformShellCommand(const char *shell, const char *shell_command)
Definition: SBPlatform.cpp:163
SBError ExecuteConnected(const std::function< lldb_private::Status(const lldb::PlatformSP &)> &func)
Definition: SBPlatform.cpp:583
const char * GetName()
Definition: SBPlatform.cpp:337
SBError Kill(const lldb::pid_t pid)
Definition: SBPlatform.cpp:576
lldb::PlatformSP GetSP() const
Definition: SBPlatform.cpp:346
SBError Launch(SBLaunchInfo &launch_info)
Definition: SBPlatform.cpp:566
uint32_t GetOSMinorVersion()
Definition: SBPlatform.cpp:470
uint32_t GetOSUpdateVersion()
Definition: SBPlatform.cpp:479
bool IsValid() const
Definition: SBPlatform.cpp:321
const char * GetTriple()
Definition: SBPlatform.cpp:407
uint32_t GetOSMajorVersion()
Definition: SBPlatform.cpp:461
SBError ConnectRemote(SBPlatformConnectOptions &connect_options)
Definition: SBPlatform.cpp:375
void SetSDKRoot(const char *sysroot)
Definition: SBPlatform.cpp:488
static SBPlatform GetHostPlatform()
Definition: SBPlatform.cpp:313
SBEnvironment GetEnvironment()
Return the environment variables of the remote platform connection process.
Definition: SBPlatform.cpp:648
SBError SetFilePermissions(const char *path, uint32_t file_permissions)
Definition: SBPlatform.cpp:624
SBError MakeDirectory(const char *path, uint32_t file_permissions=eFilePermissionsDirectoryDefault)
Definition: SBPlatform.cpp:598
SBUnixSignals GetUnixSignals() const
Definition: SBPlatform.cpp:639
SBError Run(SBPlatformShellCommand &shell_command)
Definition: SBPlatform.cpp:542
SBPlatform & operator=(const SBPlatform &rhs)
Definition: SBPlatform.cpp:304
const char * GetOSDescription()
Definition: SBPlatform.cpp:437
void SetSP(const lldb::PlatformSP &platform_sp)
Definition: SBPlatform.cpp:348
const char * GetHostname()
Definition: SBPlatform.cpp:452
void DisconnectRemote()
Definition: SBPlatform.cpp:390
lldb::PlatformSP m_opaque_sp
Definition: SBPlatform.h:184
SBError Put(SBFileSpec &src, SBFileSpec &dst)
Definition: SBPlatform.cpp:507
uint32_t GetFilePermissions(const char *path)
Definition: SBPlatform.cpp:612
const char * GetWorkingDirectory()
Definition: SBPlatform.cpp:352
SBError Get(SBFileSpec &src, SBFileSpec &dst)
Definition: SBPlatform.cpp:494
const char * GetOSBuild()
Definition: SBPlatform.cpp:422
SBError Install(SBFileSpec &src, SBFileSpec &dst)
Definition: SBPlatform.cpp:529
bool SetWorkingDirectory(const char *path)
Definition: SBPlatform.cpp:361
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
A command line argument class.
Definition: Args.h:33
void AppendArgument(llvm::StringRef arg_str, char quote_char='\0')
Appends a new argument to the end of the list argument list.
Definition: Args.cpp:322
A uniqued constant string class.
Definition: ConstString.h:40
void SetCString(const char *cstr)
Set the C string value.
const char * AsCString(const char *value_if_empty=nullptr) const
Get the string value as a C string.
Definition: ConstString.h:198
const char * GetCString() const
Get the string value as a C string.
Definition: ConstString.h:221
A file utility class.
Definition: FileSpec.h:56
size_t GetPath(char *path, size_t max_path_length, bool denormalize=true) const
Extract the full path to the file.
Definition: FileSpec.cpp:366
static lldb::PlatformSP Create(llvm::StringRef name)
Definition: Platform.cpp:252
static lldb::PlatformSP GetHostPlatform()
Get the native host platform plug-in.
Definition: Platform.cpp:135
An error handling class.
Definition: Status.h:44
#define UINT32_MAX
Definition: lldb-defines.h:19
A class that represents a running process on the host machine.
Definition: SBAttachInfo.h:14
Definition: SBAddress.h:15
uint64_t pid_t
Definition: lldb-types.h:81
PlatformConnectOptions(const char *url=nullptr)
Definition: SBPlatform.cpp:33
std::string m_rsync_remote_path_prefix
Definition: SBPlatform.cpp:42
~PlatformConnectOptions()=default
bool m_rsync_omit_hostname_from_remote_path
Definition: SBPlatform.cpp:44
std::string m_rsync_options
Definition: SBPlatform.cpp:41
ConstString m_local_cache_directory
Definition: SBPlatform.cpp:45
PlatformShellCommand(llvm::StringRef shell_command=llvm::StringRef())
Definition: SBPlatform.cpp:59
std::string m_command
Definition: SBPlatform.cpp:67
std::string m_working_dir
Definition: SBPlatform.cpp:68
Timeout< std::ratio< 1 > > m_timeout
Definition: SBPlatform.cpp:72
PlatformShellCommand(llvm::StringRef shell_interpreter, llvm::StringRef shell_command)
Definition: SBPlatform.cpp:50
std::string m_output
Definition: SBPlatform.cpp:69
~PlatformShellCommand()=default
std::string m_shell
Definition: SBPlatform.cpp:66