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
31 using namespace lldb;
32 using namespace lldb_private;
33
34 // PlatformConnectOptions
35 struct PlatformConnectOptions {
PlatformConnectOptionsPlatformConnectOptions36 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
52 struct PlatformShellCommand {
PlatformShellCommandPlatformShellCommand53 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
PlatformShellCommandPlatformShellCommand62 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
SBPlatformConnectOptions(const char * url)78 SBPlatformConnectOptions::SBPlatformConnectOptions(const char *url)
79 : m_opaque_ptr(new PlatformConnectOptions(url)) {
80 LLDB_INSTRUMENT_VA(this, url);
81 }
82
SBPlatformConnectOptions(const SBPlatformConnectOptions & rhs)83 SBPlatformConnectOptions::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
~SBPlatformConnectOptions()91 SBPlatformConnectOptions::~SBPlatformConnectOptions() { delete m_opaque_ptr; }
92
93 SBPlatformConnectOptions &
operator =(const SBPlatformConnectOptions & rhs)94 SBPlatformConnectOptions::operator=(const SBPlatformConnectOptions &rhs) {
95 LLDB_INSTRUMENT_VA(this, rhs);
96
97 *m_opaque_ptr = *rhs.m_opaque_ptr;
98 return *this;
99 }
100
GetURL()101 const 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
SetURL(const char * url)109 void 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
GetRsyncEnabled()118 bool SBPlatformConnectOptions::GetRsyncEnabled() {
119 LLDB_INSTRUMENT_VA(this);
120
121 return m_opaque_ptr->m_rsync_enabled;
122 }
123
EnableRsync(const char * options,const char * remote_path_prefix,bool omit_hostname_from_remote_path)124 void 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
DisableRsync()144 void SBPlatformConnectOptions::DisableRsync() {
145 LLDB_INSTRUMENT_VA(this);
146
147 m_opaque_ptr->m_rsync_enabled = false;
148 }
149
GetLocalCacheDirectory()150 const char *SBPlatformConnectOptions::GetLocalCacheDirectory() {
151 LLDB_INSTRUMENT_VA(this);
152
153 return m_opaque_ptr->m_local_cache_directory.GetCString();
154 }
155
SetLocalCacheDirectory(const char * path)156 void 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
SBPlatformShellCommand(const char * shell_interpreter,const char * shell_command)166 SBPlatformShellCommand::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
SBPlatformShellCommand(const char * shell_command)172 SBPlatformShellCommand::SBPlatformShellCommand(const char *shell_command)
173 : m_opaque_ptr(new PlatformShellCommand(shell_command)) {
174 LLDB_INSTRUMENT_VA(this, shell_command);
175 }
176
SBPlatformShellCommand(const SBPlatformShellCommand & rhs)177 SBPlatformShellCommand::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
185 SBPlatformShellCommand &
operator =(const SBPlatformShellCommand & rhs)186 SBPlatformShellCommand::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
~SBPlatformShellCommand()194 SBPlatformShellCommand::~SBPlatformShellCommand() { delete m_opaque_ptr; }
195
Clear()196 void 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
GetShell()204 const 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
SetShell(const char * shell_interpreter)212 void 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
GetCommand()221 const 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
SetCommand(const char * shell_command)229 void 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
GetWorkingDirectory()238 const 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
SetWorkingDirectory(const char * path)246 void 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
GetTimeoutSeconds()255 uint32_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
SetTimeoutSeconds(uint32_t sec)263 void 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
GetSignal()272 int SBPlatformShellCommand::GetSignal() {
273 LLDB_INSTRUMENT_VA(this);
274
275 return m_opaque_ptr->m_signo;
276 }
277
GetStatus()278 int SBPlatformShellCommand::GetStatus() {
279 LLDB_INSTRUMENT_VA(this);
280
281 return m_opaque_ptr->m_status;
282 }
283
GetOutput()284 const 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
SBPlatform()293 SBPlatform::SBPlatform() { LLDB_INSTRUMENT_VA(this); }
294
SBPlatform(const char * platform_name)295 SBPlatform::SBPlatform(const char *platform_name) {
296 LLDB_INSTRUMENT_VA(this, platform_name);
297
298 m_opaque_sp = Platform::Create(platform_name);
299 }
300
SBPlatform(const SBPlatform & rhs)301 SBPlatform::SBPlatform(const SBPlatform &rhs) {
302 LLDB_INSTRUMENT_VA(this, rhs);
303
304 m_opaque_sp = rhs.m_opaque_sp;
305 }
306
operator =(const SBPlatform & rhs)307 SBPlatform &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
314 SBPlatform::~SBPlatform() = default;
315
GetHostPlatform()316 SBPlatform SBPlatform::GetHostPlatform() {
317 LLDB_INSTRUMENT();
318
319 SBPlatform host_platform;
320 host_platform.m_opaque_sp = Platform::GetHostPlatform();
321 return host_platform;
322 }
323
IsValid() const324 bool SBPlatform::IsValid() const {
325 LLDB_INSTRUMENT_VA(this);
326 return this->operator bool();
327 }
operator bool() const328 SBPlatform::operator bool() const {
329 LLDB_INSTRUMENT_VA(this);
330
331 return m_opaque_sp.get() != nullptr;
332 }
333
Clear()334 void SBPlatform::Clear() {
335 LLDB_INSTRUMENT_VA(this);
336
337 m_opaque_sp.reset();
338 }
339
GetName()340 const 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
GetSP() const349 lldb::PlatformSP SBPlatform::GetSP() const { return m_opaque_sp; }
350
SetSP(const lldb::PlatformSP & platform_sp)351 void SBPlatform::SetSP(const lldb::PlatformSP &platform_sp) {
352 m_opaque_sp = platform_sp;
353 }
354
GetWorkingDirectory()355 const 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
SetWorkingDirectory(const char * path)364 bool 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
ConnectRemote(SBPlatformConnectOptions & connect_options)378 SBError 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(connect_options.GetURL());
386 sb_error.ref() = platform_sp->ConnectRemote(args);
387 } else {
388 sb_error = Status::FromErrorString("invalid platform");
389 }
390 return sb_error;
391 }
392
DisconnectRemote()393 void SBPlatform::DisconnectRemote() {
394 LLDB_INSTRUMENT_VA(this);
395
396 PlatformSP platform_sp(GetSP());
397 if (platform_sp)
398 platform_sp->DisconnectRemote();
399 }
400
IsConnected()401 bool 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
GetTriple()410 const 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
GetOSBuild()425 const 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("");
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
GetOSDescription()440 const 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("");
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
GetHostname()455 const 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
GetOSMajorVersion()464 uint32_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
GetOSMinorVersion()473 uint32_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
GetOSUpdateVersion()482 uint32_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
SetSDKRoot(const char * sysroot)491 void 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
Get(SBFileSpec & src,SBFileSpec & dst)497 SBError 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(src.ref(), dst.ref());
504 } else {
505 sb_error = Status::FromErrorString("invalid platform");
506 }
507 return sb_error;
508 }
509
Put(SBFileSpec & src,SBFileSpec & dst)510 SBError SBPlatform::Put(SBFileSpec &src, SBFileSpec &dst) {
511 LLDB_INSTRUMENT_VA(this, src, dst);
512 return ExecuteConnected([&](const lldb::PlatformSP &platform_sp) {
513 if (src.Exists()) {
514 uint32_t permissions = FileSystem::Instance().GetPermissions(src.ref());
515 if (permissions == 0) {
516 if (FileSystem::Instance().IsDirectory(src.ref()))
517 permissions = eFilePermissionsDirectoryDefault;
518 else
519 permissions = eFilePermissionsFileDefault;
520 }
521
522 return platform_sp->PutFile(src.ref(), dst.ref(), permissions);
523 }
524
525 return Status::FromErrorStringWithFormat(
526 "'src' argument doesn't exist: '%s'", src.ref().GetPath().c_str());
527 });
528 }
529
Install(SBFileSpec & src,SBFileSpec & dst)530 SBError SBPlatform::Install(SBFileSpec &src, SBFileSpec &dst) {
531 LLDB_INSTRUMENT_VA(this, src, dst);
532 return ExecuteConnected([&](const lldb::PlatformSP &platform_sp) {
533 if (src.Exists())
534 return platform_sp->Install(src.ref(), dst.ref());
535
536 Status error;
537 error = Status::FromErrorStringWithFormat(
538 "'src' argument doesn't exist: '%s'", src.ref().GetPath().c_str());
539 return error;
540 });
541 }
542
Run(SBPlatformShellCommand & shell_command)543 SBError SBPlatform::Run(SBPlatformShellCommand &shell_command) {
544 LLDB_INSTRUMENT_VA(this, shell_command);
545 return ExecuteConnected(
546 [&](const lldb::PlatformSP &platform_sp) {
547 const char *command = shell_command.GetCommand();
548 if (!command)
549 return Status::FromErrorString("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_command.m_opaque_ptr->m_shell, command,
559 FileSpec(shell_command.GetWorkingDirectory()),
560 &shell_command.m_opaque_ptr->m_status,
561 &shell_command.m_opaque_ptr->m_signo,
562 &shell_command.m_opaque_ptr->m_output,
563 shell_command.m_opaque_ptr->m_timeout);
564 });
565 }
566
Launch(SBLaunchInfo & launch_info)567 SBError SBPlatform::Launch(SBLaunchInfo &launch_info) {
568 LLDB_INSTRUMENT_VA(this, launch_info);
569 return ExecuteConnected([&](const lldb::PlatformSP &platform_sp) {
570 ProcessLaunchInfo info = launch_info.ref();
571 Status error = platform_sp->LaunchProcess(info);
572 launch_info.set_ref(info);
573 return error;
574 });
575 }
576
Attach(SBAttachInfo & attach_info,const SBDebugger & debugger,SBTarget & target,SBError & error)577 SBProcess 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(info, debugger.ref(),
587 target.GetSP().get(), status);
588 error.SetError(std::move(status));
589 return SBProcess(process_sp);
590 }
591
592 error = Status::FromErrorString("not connected");
593 return {};
594 }
595
596 error = Status::FromErrorString("invalid platform");
597 return {};
598 }
599
GetAllProcesses(SBError & error)600 SBProcessInfoList 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("not connected");
607 return {};
608 }
609
610 error = Status::FromErrorString("invalid platform");
611 return {};
612 }
613
Kill(const lldb::pid_t pid)614 SBError SBPlatform::Kill(const lldb::pid_t pid) {
615 LLDB_INSTRUMENT_VA(this, pid);
616 return ExecuteConnected([&](const lldb::PlatformSP &platform_sp) {
617 return platform_sp->KillProcess(pid);
618 });
619 }
620
ExecuteConnected(const std::function<Status (const lldb::PlatformSP &)> & func)621 SBError 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("not connected");
630 } else
631 sb_error = Status::FromErrorString("invalid platform");
632
633 return sb_error;
634 }
635
MakeDirectory(const char * path,uint32_t file_permissions)636 SBError 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(FileSpec(path), file_permissions);
644 } else {
645 sb_error = Status::FromErrorString("invalid platform");
646 }
647 return sb_error;
648 }
649
GetFilePermissions(const char * path)650 uint32_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(FileSpec(path), file_permissions);
657 return file_permissions;
658 }
659 return 0;
660 }
661
SetFilePermissions(const char * path,uint32_t file_permissions)662 SBError 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(FileSpec(path), file_permissions);
671 } else {
672 sb_error = Status::FromErrorString("invalid platform");
673 }
674 return sb_error;
675 }
676
GetUnixSignals() const677 SBUnixSignals 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
GetEnvironment()686 SBEnvironment 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
SetLocateModuleCallback(lldb::SBPlatformLocateModuleCallback callback,void * callback_baton)697 SBError 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