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
9#include "lldb/API/SBPlatform.h"
10#include "lldb/API/SBDebugger.h"
11#include "lldb/API/SBEnvironment.h"
12#include "lldb/API/SBError.h"
13#include "lldb/API/SBFileSpec.h"
14#include "lldb/API/SBLaunchInfo.h"
15#include "lldb/API/SBModuleSpec.h"
16#include "lldb/API/SBProcessInfoList.h"
17#include "lldb/API/SBTarget.h"
18#include "lldb/API/SBUnixSignals.h"
19#include "lldb/Host/File.h"
20#include "lldb/Target/Platform.h"
21#include "lldb/Target/Target.h"
22#include "lldb/Utility/ArchSpec.h"
23#include "lldb/Utility/Args.h"
24#include "lldb/Utility/Instrumentation.h"
25#include "lldb/Utility/Status.h"
26
27#include "llvm/Support/FileSystem.h"
28
29#include <functional>
30
31using namespace lldb;
32using namespace lldb_private;
33
34// PlatformConnectOptions
35struct PlatformConnectOptions {
36 PlatformConnectOptions(const char *url = nullptr) {
37 if (url && url[0])
38 m_url = url;
39 }
40
41 ~PlatformConnectOptions() = default;
42
43 std::string m_url;
44 std::string m_rsync_options;
45 std::string m_rsync_remote_path_prefix;
46 bool m_rsync_enabled = false;
47 bool m_rsync_omit_hostname_from_remote_path = false;
48 ConstString m_local_cache_directory;
49};
50
51// PlatformShellCommand
52struct PlatformShellCommand {
53 PlatformShellCommand(llvm::StringRef shell_interpreter,
54 llvm::StringRef shell_command) {
55 if (!shell_interpreter.empty())
56 m_shell = shell_interpreter.str();
57
58 if (!m_shell.empty() && !shell_command.empty())
59 m_command = shell_command.str();
60 }
61
62 PlatformShellCommand(llvm::StringRef shell_command = llvm::StringRef()) {
63 if (!shell_command.empty())
64 m_command = shell_command.str();
65 }
66
67 ~PlatformShellCommand() = default;
68
69 std::string m_shell;
70 std::string m_command;
71 std::string m_working_dir;
72 std::string m_output;
73 int m_status = 0;
74 int m_signo = 0;
75 Timeout<std::ratio<1>> m_timeout = std::nullopt;
76};
77// SBPlatformConnectOptions
78SBPlatformConnectOptions::SBPlatformConnectOptions(const char *url)
79 : m_opaque_ptr(new PlatformConnectOptions(url)) {
80 LLDB_INSTRUMENT_VA(this, url);
81}
82
83SBPlatformConnectOptions::SBPlatformConnectOptions(
84 const SBPlatformConnectOptions &rhs)
85 : m_opaque_ptr(new PlatformConnectOptions()) {
86 LLDB_INSTRUMENT_VA(this, rhs);
87
88 *m_opaque_ptr = *rhs.m_opaque_ptr;
89}
90
91SBPlatformConnectOptions::~SBPlatformConnectOptions() { delete m_opaque_ptr; }
92
93SBPlatformConnectOptions &
94SBPlatformConnectOptions::operator=(const SBPlatformConnectOptions &rhs) {
95 LLDB_INSTRUMENT_VA(this, rhs);
96
97 *m_opaque_ptr = *rhs.m_opaque_ptr;
98 return *this;
99}
100
101const char *SBPlatformConnectOptions::GetURL() {
102 LLDB_INSTRUMENT_VA(this);
103
104 if (m_opaque_ptr->m_url.empty())
105 return nullptr;
106 return ConstString(m_opaque_ptr->m_url.c_str()).GetCString();
107}
108
109void SBPlatformConnectOptions::SetURL(const char *url) {
110 LLDB_INSTRUMENT_VA(this, url);
111
112 if (url && url[0])
113 m_opaque_ptr->m_url = url;
114 else
115 m_opaque_ptr->m_url.clear();
116}
117
118bool SBPlatformConnectOptions::GetRsyncEnabled() {
119 LLDB_INSTRUMENT_VA(this);
120
121 return m_opaque_ptr->m_rsync_enabled;
122}
123
124void SBPlatformConnectOptions::EnableRsync(
125 const char *options, const char *remote_path_prefix,
126 bool omit_hostname_from_remote_path) {
127 LLDB_INSTRUMENT_VA(this, options, remote_path_prefix,
128 omit_hostname_from_remote_path);
129
130 m_opaque_ptr->m_rsync_enabled = true;
131 m_opaque_ptr->m_rsync_omit_hostname_from_remote_path =
132 omit_hostname_from_remote_path;
133 if (remote_path_prefix && remote_path_prefix[0])
134 m_opaque_ptr->m_rsync_remote_path_prefix = remote_path_prefix;
135 else
136 m_opaque_ptr->m_rsync_remote_path_prefix.clear();
137
138 if (options && options[0])
139 m_opaque_ptr->m_rsync_options = options;
140 else
141 m_opaque_ptr->m_rsync_options.clear();
142}
143
144void SBPlatformConnectOptions::DisableRsync() {
145 LLDB_INSTRUMENT_VA(this);
146
147 m_opaque_ptr->m_rsync_enabled = false;
148}
149
150const char *SBPlatformConnectOptions::GetLocalCacheDirectory() {
151 LLDB_INSTRUMENT_VA(this);
152
153 return m_opaque_ptr->m_local_cache_directory.GetCString();
154}
155
156void SBPlatformConnectOptions::SetLocalCacheDirectory(const char *path) {
157 LLDB_INSTRUMENT_VA(this, path);
158
159 if (path && path[0])
160 m_opaque_ptr->m_local_cache_directory.SetCString(path);
161 else
162 m_opaque_ptr->m_local_cache_directory = ConstString();
163}
164
165// SBPlatformShellCommand
166SBPlatformShellCommand::SBPlatformShellCommand(const char *shell_interpreter,
167 const char *shell_command)
168 : m_opaque_ptr(new PlatformShellCommand(shell_interpreter, shell_command)) {
169 LLDB_INSTRUMENT_VA(this, shell_interpreter, shell_command);
170}
171
172SBPlatformShellCommand::SBPlatformShellCommand(const char *shell_command)
173 : m_opaque_ptr(new PlatformShellCommand(shell_command)) {
174 LLDB_INSTRUMENT_VA(this, shell_command);
175}
176
177SBPlatformShellCommand::SBPlatformShellCommand(
178 const SBPlatformShellCommand &rhs)
179 : m_opaque_ptr(new PlatformShellCommand()) {
180 LLDB_INSTRUMENT_VA(this, rhs);
181
182 *m_opaque_ptr = *rhs.m_opaque_ptr;
183}
184
185SBPlatformShellCommand &
186SBPlatformShellCommand::operator=(const SBPlatformShellCommand &rhs) {
187
188 LLDB_INSTRUMENT_VA(this, rhs);
189
190 *m_opaque_ptr = *rhs.m_opaque_ptr;
191 return *this;
192}
193
194SBPlatformShellCommand::~SBPlatformShellCommand() { delete m_opaque_ptr; }
195
196void SBPlatformShellCommand::Clear() {
197 LLDB_INSTRUMENT_VA(this);
198
199 m_opaque_ptr->m_output = std::string();
200 m_opaque_ptr->m_status = 0;
201 m_opaque_ptr->m_signo = 0;
202}
203
204const char *SBPlatformShellCommand::GetShell() {
205 LLDB_INSTRUMENT_VA(this);
206
207 if (m_opaque_ptr->m_shell.empty())
208 return nullptr;
209 return ConstString(m_opaque_ptr->m_shell.c_str()).GetCString();
210}
211
212void SBPlatformShellCommand::SetShell(const char *shell_interpreter) {
213 LLDB_INSTRUMENT_VA(this, shell_interpreter);
214
215 if (shell_interpreter && shell_interpreter[0])
216 m_opaque_ptr->m_shell = shell_interpreter;
217 else
218 m_opaque_ptr->m_shell.clear();
219}
220
221const char *SBPlatformShellCommand::GetCommand() {
222 LLDB_INSTRUMENT_VA(this);
223
224 if (m_opaque_ptr->m_command.empty())
225 return nullptr;
226 return ConstString(m_opaque_ptr->m_command.c_str()).GetCString();
227}
228
229void SBPlatformShellCommand::SetCommand(const char *shell_command) {
230 LLDB_INSTRUMENT_VA(this, shell_command);
231
232 if (shell_command && shell_command[0])
233 m_opaque_ptr->m_command = shell_command;
234 else
235 m_opaque_ptr->m_command.clear();
236}
237
238const char *SBPlatformShellCommand::GetWorkingDirectory() {
239 LLDB_INSTRUMENT_VA(this);
240
241 if (m_opaque_ptr->m_working_dir.empty())
242 return nullptr;
243 return ConstString(m_opaque_ptr->m_working_dir.c_str()).GetCString();
244}
245
246void SBPlatformShellCommand::SetWorkingDirectory(const char *path) {
247 LLDB_INSTRUMENT_VA(this, path);
248
249 if (path && path[0])
250 m_opaque_ptr->m_working_dir = path;
251 else
252 m_opaque_ptr->m_working_dir.clear();
253}
254
255uint32_t SBPlatformShellCommand::GetTimeoutSeconds() {
256 LLDB_INSTRUMENT_VA(this);
257
258 if (m_opaque_ptr->m_timeout)
259 return m_opaque_ptr->m_timeout->count();
260 return UINT32_MAX;
261}
262
263void SBPlatformShellCommand::SetTimeoutSeconds(uint32_t sec) {
264 LLDB_INSTRUMENT_VA(this, sec);
265
266 if (sec == UINT32_MAX)
267 m_opaque_ptr->m_timeout = std::nullopt;
268 else
269 m_opaque_ptr->m_timeout = std::chrono::seconds(sec);
270}
271
272int SBPlatformShellCommand::GetSignal() {
273 LLDB_INSTRUMENT_VA(this);
274
275 return m_opaque_ptr->m_signo;
276}
277
278int SBPlatformShellCommand::GetStatus() {
279 LLDB_INSTRUMENT_VA(this);
280
281 return m_opaque_ptr->m_status;
282}
283
284const char *SBPlatformShellCommand::GetOutput() {
285 LLDB_INSTRUMENT_VA(this);
286
287 if (m_opaque_ptr->m_output.empty())
288 return nullptr;
289 return ConstString(m_opaque_ptr->m_output.c_str()).GetCString();
290}
291
292// SBPlatform
293SBPlatform::SBPlatform() { LLDB_INSTRUMENT_VA(this); }
294
295SBPlatform::SBPlatform(const char *platform_name) {
296 LLDB_INSTRUMENT_VA(this, platform_name);
297
298 m_opaque_sp = Platform::Create(name: platform_name);
299}
300
301SBPlatform::SBPlatform(const SBPlatform &rhs) {
302 LLDB_INSTRUMENT_VA(this, rhs);
303
304 m_opaque_sp = rhs.m_opaque_sp;
305}
306
307SBPlatform &SBPlatform::operator=(const SBPlatform &rhs) {
308 LLDB_INSTRUMENT_VA(this, rhs);
309
310 m_opaque_sp = rhs.m_opaque_sp;
311 return *this;
312}
313
314SBPlatform::~SBPlatform() = default;
315
316SBPlatform SBPlatform::GetHostPlatform() {
317 LLDB_INSTRUMENT();
318
319 SBPlatform host_platform;
320 host_platform.m_opaque_sp = Platform::GetHostPlatform();
321 return host_platform;
322}
323
324bool SBPlatform::IsValid() const {
325 LLDB_INSTRUMENT_VA(this);
326 return this->operator bool();
327}
328SBPlatform::operator bool() const {
329 LLDB_INSTRUMENT_VA(this);
330
331 return m_opaque_sp.get() != nullptr;
332}
333
334void SBPlatform::Clear() {
335 LLDB_INSTRUMENT_VA(this);
336
337 m_opaque_sp.reset();
338}
339
340const char *SBPlatform::GetName() {
341 LLDB_INSTRUMENT_VA(this);
342
343 PlatformSP platform_sp(GetSP());
344 if (platform_sp)
345 return ConstString(platform_sp->GetName()).AsCString();
346 return nullptr;
347}
348
349lldb::PlatformSP SBPlatform::GetSP() const { return m_opaque_sp; }
350
351void SBPlatform::SetSP(const lldb::PlatformSP &platform_sp) {
352 m_opaque_sp = platform_sp;
353}
354
355const char *SBPlatform::GetWorkingDirectory() {
356 LLDB_INSTRUMENT_VA(this);
357
358 PlatformSP platform_sp(GetSP());
359 if (platform_sp)
360 return platform_sp->GetWorkingDirectory().GetPathAsConstString().AsCString();
361 return nullptr;
362}
363
364bool SBPlatform::SetWorkingDirectory(const char *path) {
365 LLDB_INSTRUMENT_VA(this, path);
366
367 PlatformSP platform_sp(GetSP());
368 if (platform_sp) {
369 if (path)
370 platform_sp->SetWorkingDirectory(FileSpec(path));
371 else
372 platform_sp->SetWorkingDirectory(FileSpec());
373 return true;
374 }
375 return false;
376}
377
378SBError SBPlatform::ConnectRemote(SBPlatformConnectOptions &connect_options) {
379 LLDB_INSTRUMENT_VA(this, connect_options);
380
381 SBError sb_error;
382 PlatformSP platform_sp(GetSP());
383 if (platform_sp && connect_options.GetURL()) {
384 Args args;
385 args.AppendArgument(arg_str: connect_options.GetURL());
386 sb_error.ref() = platform_sp->ConnectRemote(args);
387 } else {
388 sb_error = Status::FromErrorString(str: "invalid platform");
389 }
390 return sb_error;
391}
392
393void SBPlatform::DisconnectRemote() {
394 LLDB_INSTRUMENT_VA(this);
395
396 PlatformSP platform_sp(GetSP());
397 if (platform_sp)
398 platform_sp->DisconnectRemote();
399}
400
401bool SBPlatform::IsConnected() {
402 LLDB_INSTRUMENT_VA(this);
403
404 PlatformSP platform_sp(GetSP());
405 if (platform_sp)
406 return platform_sp->IsConnected();
407 return false;
408}
409
410const char *SBPlatform::GetTriple() {
411 LLDB_INSTRUMENT_VA(this);
412
413 PlatformSP platform_sp(GetSP());
414 if (platform_sp) {
415 ArchSpec arch(platform_sp->GetSystemArchitecture());
416 if (arch.IsValid()) {
417 // Const-ify the string so we don't need to worry about the lifetime of
418 // the string
419 return ConstString(arch.GetTriple().getTriple().c_str()).GetCString();
420 }
421 }
422 return nullptr;
423}
424
425const char *SBPlatform::GetOSBuild() {
426 LLDB_INSTRUMENT_VA(this);
427
428 PlatformSP platform_sp(GetSP());
429 if (platform_sp) {
430 std::string s = platform_sp->GetOSBuildString().value_or(u: "");
431 if (!s.empty()) {
432 // Const-ify the string so we don't need to worry about the lifetime of
433 // the string
434 return ConstString(s).GetCString();
435 }
436 }
437 return nullptr;
438}
439
440const char *SBPlatform::GetOSDescription() {
441 LLDB_INSTRUMENT_VA(this);
442
443 PlatformSP platform_sp(GetSP());
444 if (platform_sp) {
445 std::string s = platform_sp->GetOSKernelDescription().value_or(u: "");
446 if (!s.empty()) {
447 // Const-ify the string so we don't need to worry about the lifetime of
448 // the string
449 return ConstString(s.c_str()).GetCString();
450 }
451 }
452 return nullptr;
453}
454
455const char *SBPlatform::GetHostname() {
456 LLDB_INSTRUMENT_VA(this);
457
458 PlatformSP platform_sp(GetSP());
459 if (platform_sp)
460 return ConstString(platform_sp->GetHostname()).GetCString();
461 return nullptr;
462}
463
464uint32_t SBPlatform::GetOSMajorVersion() {
465 LLDB_INSTRUMENT_VA(this);
466
467 llvm::VersionTuple version;
468 if (PlatformSP platform_sp = GetSP())
469 version = platform_sp->GetOSVersion();
470 return version.empty() ? UINT32_MAX : version.getMajor();
471}
472
473uint32_t SBPlatform::GetOSMinorVersion() {
474 LLDB_INSTRUMENT_VA(this);
475
476 llvm::VersionTuple version;
477 if (PlatformSP platform_sp = GetSP())
478 version = platform_sp->GetOSVersion();
479 return version.getMinor().value_or(UINT32_MAX);
480}
481
482uint32_t SBPlatform::GetOSUpdateVersion() {
483 LLDB_INSTRUMENT_VA(this);
484
485 llvm::VersionTuple version;
486 if (PlatformSP platform_sp = GetSP())
487 version = platform_sp->GetOSVersion();
488 return version.getSubminor().value_or(UINT32_MAX);
489}
490
491void SBPlatform::SetSDKRoot(const char *sysroot) {
492 LLDB_INSTRUMENT_VA(this, sysroot);
493 if (PlatformSP platform_sp = GetSP())
494 platform_sp->SetSDKRootDirectory(llvm::StringRef(sysroot).str());
495}
496
497SBError SBPlatform::Get(SBFileSpec &src, SBFileSpec &dst) {
498 LLDB_INSTRUMENT_VA(this, src, dst);
499
500 SBError sb_error;
501 PlatformSP platform_sp(GetSP());
502 if (platform_sp) {
503 sb_error.ref() = platform_sp->GetFile(source: src.ref(), destination: dst.ref());
504 } else {
505 sb_error = Status::FromErrorString(str: "invalid platform");
506 }
507 return sb_error;
508}
509
510SBError SBPlatform::Put(SBFileSpec &src, SBFileSpec &dst) {
511 LLDB_INSTRUMENT_VA(this, src, dst);
512 return ExecuteConnected(func: [&](const lldb::PlatformSP &platform_sp) {
513 if (src.Exists()) {
514 uint32_t permissions = FileSystem::Instance().GetPermissions(file_spec: src.ref());
515 if (permissions == 0) {
516 if (FileSystem::Instance().IsDirectory(file_spec: src.ref()))
517 permissions = eFilePermissionsDirectoryDefault;
518 else
519 permissions = eFilePermissionsFileDefault;
520 }
521
522 return platform_sp->PutFile(source: src.ref(), destination: dst.ref(), uid: permissions);
523 }
524
525 return Status::FromErrorStringWithFormat(
526 format: "'src' argument doesn't exist: '%s'", src.ref().GetPath().c_str());
527 });
528}
529
530SBError SBPlatform::Install(SBFileSpec &src, SBFileSpec &dst) {
531 LLDB_INSTRUMENT_VA(this, src, dst);
532 return ExecuteConnected(func: [&](const lldb::PlatformSP &platform_sp) {
533 if (src.Exists())
534 return platform_sp->Install(src: src.ref(), dst: dst.ref());
535
536 Status error;
537 error = Status::FromErrorStringWithFormat(
538 format: "'src' argument doesn't exist: '%s'", src.ref().GetPath().c_str());
539 return error;
540 });
541}
542
543SBError SBPlatform::Run(SBPlatformShellCommand &shell_command) {
544 LLDB_INSTRUMENT_VA(this, shell_command);
545 return ExecuteConnected(
546 func: [&](const lldb::PlatformSP &platform_sp) {
547 const char *command = shell_command.GetCommand();
548 if (!command)
549 return Status::FromErrorString(str: "invalid shell command (empty)");
550
551 if (shell_command.GetWorkingDirectory() == nullptr) {
552 std::string platform_working_dir =
553 platform_sp->GetWorkingDirectory().GetPath();
554 if (!platform_working_dir.empty())
555 shell_command.SetWorkingDirectory(platform_working_dir.c_str());
556 }
557 return platform_sp->RunShellCommand(
558 shell: shell_command.m_opaque_ptr->m_shell, command,
559 working_dir: FileSpec(shell_command.GetWorkingDirectory()),
560 status_ptr: &shell_command.m_opaque_ptr->m_status,
561 signo_ptr: &shell_command.m_opaque_ptr->m_signo,
562 command_output: &shell_command.m_opaque_ptr->m_output,
563 timeout: shell_command.m_opaque_ptr->m_timeout);
564 });
565}
566
567SBError SBPlatform::Launch(SBLaunchInfo &launch_info) {
568 LLDB_INSTRUMENT_VA(this, launch_info);
569 return ExecuteConnected(func: [&](const lldb::PlatformSP &platform_sp) {
570 ProcessLaunchInfo info = launch_info.ref();
571 Status error = platform_sp->LaunchProcess(launch_info&: info);
572 launch_info.set_ref(info);
573 return error;
574 });
575}
576
577SBProcess SBPlatform::Attach(SBAttachInfo &attach_info,
578 const SBDebugger &debugger, SBTarget &target,
579 SBError &error) {
580 LLDB_INSTRUMENT_VA(this, attach_info, debugger, target, error);
581
582 if (PlatformSP platform_sp = GetSP()) {
583 if (platform_sp->IsConnected()) {
584 ProcessAttachInfo &info = attach_info.ref();
585 Status status;
586 ProcessSP process_sp = platform_sp->Attach(attach_info&: info, debugger&: debugger.ref(),
587 target: target.GetSP().get(), error&: status);
588 error.SetError(std::move(status));
589 return SBProcess(process_sp);
590 }
591
592 error = Status::FromErrorString(str: "not connected");
593 return {};
594 }
595
596 error = Status::FromErrorString(str: "invalid platform");
597 return {};
598}
599
600SBProcessInfoList SBPlatform::GetAllProcesses(SBError &error) {
601 if (PlatformSP platform_sp = GetSP()) {
602 if (platform_sp->IsConnected()) {
603 ProcessInstanceInfoList list = platform_sp->GetAllProcesses();
604 return SBProcessInfoList(list);
605 }
606 error = Status::FromErrorString(str: "not connected");
607 return {};
608 }
609
610 error = Status::FromErrorString(str: "invalid platform");
611 return {};
612}
613
614SBError SBPlatform::Kill(const lldb::pid_t pid) {
615 LLDB_INSTRUMENT_VA(this, pid);
616 return ExecuteConnected(func: [&](const lldb::PlatformSP &platform_sp) {
617 return platform_sp->KillProcess(pid);
618 });
619}
620
621SBError SBPlatform::ExecuteConnected(
622 const std::function<Status(const lldb::PlatformSP &)> &func) {
623 SBError sb_error;
624 const auto platform_sp(GetSP());
625 if (platform_sp) {
626 if (platform_sp->IsConnected())
627 sb_error.ref() = func(platform_sp);
628 else
629 sb_error = Status::FromErrorString(str: "not connected");
630 } else
631 sb_error = Status::FromErrorString(str: "invalid platform");
632
633 return sb_error;
634}
635
636SBError SBPlatform::MakeDirectory(const char *path, uint32_t file_permissions) {
637 LLDB_INSTRUMENT_VA(this, path, file_permissions);
638
639 SBError sb_error;
640 PlatformSP platform_sp(GetSP());
641 if (platform_sp) {
642 sb_error.ref() =
643 platform_sp->MakeDirectory(file_spec: FileSpec(path), permissions: file_permissions);
644 } else {
645 sb_error = Status::FromErrorString(str: "invalid platform");
646 }
647 return sb_error;
648}
649
650uint32_t SBPlatform::GetFilePermissions(const char *path) {
651 LLDB_INSTRUMENT_VA(this, path);
652
653 PlatformSP platform_sp(GetSP());
654 if (platform_sp) {
655 uint32_t file_permissions = 0;
656 platform_sp->GetFilePermissions(file_spec: FileSpec(path), file_permissions);
657 return file_permissions;
658 }
659 return 0;
660}
661
662SBError SBPlatform::SetFilePermissions(const char *path,
663 uint32_t file_permissions) {
664 LLDB_INSTRUMENT_VA(this, path, file_permissions);
665
666 SBError sb_error;
667 PlatformSP platform_sp(GetSP());
668 if (platform_sp) {
669 sb_error.ref() =
670 platform_sp->SetFilePermissions(file_spec: FileSpec(path), file_permissions);
671 } else {
672 sb_error = Status::FromErrorString(str: "invalid platform");
673 }
674 return sb_error;
675}
676
677SBUnixSignals SBPlatform::GetUnixSignals() const {
678 LLDB_INSTRUMENT_VA(this);
679
680 if (auto platform_sp = GetSP())
681 return SBUnixSignals{platform_sp};
682
683 return SBUnixSignals();
684}
685
686SBEnvironment SBPlatform::GetEnvironment() {
687 LLDB_INSTRUMENT_VA(this);
688 PlatformSP platform_sp(GetSP());
689
690 if (platform_sp) {
691 return SBEnvironment(platform_sp->GetEnvironment());
692 }
693
694 return SBEnvironment();
695}
696
697SBError SBPlatform::SetLocateModuleCallback(
698 lldb::SBPlatformLocateModuleCallback callback, void *callback_baton) {
699 LLDB_INSTRUMENT_VA(this, callback, callback_baton);
700 PlatformSP platform_sp(GetSP());
701 if (!platform_sp)
702 return SBError("invalid platform");
703
704 if (!callback) {
705 // Clear the callback.
706 platform_sp->SetLocateModuleCallback(nullptr);
707 return SBError();
708 }
709
710 // Platform.h does not accept lldb::SBPlatformLocateModuleCallback directly
711 // because of the SBModuleSpec and SBFileSpec dependencies. Use a lambda to
712 // convert ModuleSpec/FileSpec <--> SBModuleSpec/SBFileSpec for the callback
713 // arguments.
714 platform_sp->SetLocateModuleCallback(
715 [callback, callback_baton](const ModuleSpec &module_spec,
716 FileSpec &module_file_spec,
717 FileSpec &symbol_file_spec) {
718 SBModuleSpec module_spec_sb(module_spec);
719 SBFileSpec module_file_spec_sb;
720 SBFileSpec symbol_file_spec_sb;
721
722 SBError error = callback(callback_baton, module_spec_sb,
723 module_file_spec_sb, symbol_file_spec_sb);
724
725 if (error.Success()) {
726 module_file_spec = module_file_spec_sb.ref();
727 symbol_file_spec = symbol_file_spec_sb.ref();
728 }
729
730 return error.ref().Clone();
731 });
732 return SBError();
733}
734

Provided by KDAB

Privacy Policy
Improve your Profiling and Debugging skills
Find out more

source code of lldb/source/API/SBPlatform.cpp