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