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 = Status::FromErrorString("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 = Status::FromErrorString("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 return Status::FromErrorStringWithFormat( 527 "'src' argument doesn't exist: '%s'", src.ref().GetPath().c_str()); 528 }); 529 } 530 531 SBError SBPlatform::Install(SBFileSpec &src, SBFileSpec &dst) { 532 LLDB_INSTRUMENT_VA(this, src, dst); 533 return ExecuteConnected([&](const lldb::PlatformSP &platform_sp) { 534 if (src.Exists()) 535 return platform_sp->Install(src.ref(), dst.ref()); 536 537 Status error; 538 error = Status::FromErrorStringWithFormat( 539 "'src' argument doesn't exist: '%s'", src.ref().GetPath().c_str()); 540 return error; 541 }); 542 } 543 544 SBError SBPlatform::Run(SBPlatformShellCommand &shell_command) { 545 LLDB_INSTRUMENT_VA(this, shell_command); 546 return ExecuteConnected( 547 [&](const lldb::PlatformSP &platform_sp) { 548 const char *command = shell_command.GetCommand(); 549 if (!command) 550 return Status::FromErrorString("invalid shell command (empty)"); 551 552 if (shell_command.GetWorkingDirectory() == nullptr) { 553 std::string platform_working_dir = 554 platform_sp->GetWorkingDirectory().GetPath(); 555 if (!platform_working_dir.empty()) 556 shell_command.SetWorkingDirectory(platform_working_dir.c_str()); 557 } 558 return platform_sp->RunShellCommand( 559 shell_command.m_opaque_ptr->m_shell, command, 560 FileSpec(shell_command.GetWorkingDirectory()), 561 &shell_command.m_opaque_ptr->m_status, 562 &shell_command.m_opaque_ptr->m_signo, 563 &shell_command.m_opaque_ptr->m_output, 564 shell_command.m_opaque_ptr->m_timeout); 565 }); 566 } 567 568 SBError SBPlatform::Launch(SBLaunchInfo &launch_info) { 569 LLDB_INSTRUMENT_VA(this, launch_info); 570 return ExecuteConnected([&](const lldb::PlatformSP &platform_sp) { 571 ProcessLaunchInfo info = launch_info.ref(); 572 Status error = platform_sp->LaunchProcess(info); 573 launch_info.set_ref(info); 574 return error; 575 }); 576 } 577 578 SBProcess SBPlatform::Attach(SBAttachInfo &attach_info, 579 const SBDebugger &debugger, SBTarget &target, 580 SBError &error) { 581 LLDB_INSTRUMENT_VA(this, attach_info, debugger, target, error); 582 583 if (PlatformSP platform_sp = GetSP()) { 584 if (platform_sp->IsConnected()) { 585 ProcessAttachInfo &info = attach_info.ref(); 586 Status status; 587 ProcessSP process_sp = platform_sp->Attach(info, debugger.ref(), 588 target.GetSP().get(), status); 589 error.SetError(std::move(status)); 590 return SBProcess(process_sp); 591 } 592 593 error = Status::FromErrorString("not connected"); 594 return {}; 595 } 596 597 error = Status::FromErrorString("invalid platform"); 598 return {}; 599 } 600 601 SBProcessInfoList SBPlatform::GetAllProcesses(SBError &error) { 602 if (PlatformSP platform_sp = GetSP()) { 603 if (platform_sp->IsConnected()) { 604 ProcessInstanceInfoList list = platform_sp->GetAllProcesses(); 605 return SBProcessInfoList(list); 606 } 607 error = Status::FromErrorString("not connected"); 608 return {}; 609 } 610 611 error = Status::FromErrorString("invalid platform"); 612 return {}; 613 } 614 615 SBError SBPlatform::Kill(const lldb::pid_t pid) { 616 LLDB_INSTRUMENT_VA(this, pid); 617 return ExecuteConnected([&](const lldb::PlatformSP &platform_sp) { 618 return platform_sp->KillProcess(pid); 619 }); 620 } 621 622 SBError SBPlatform::ExecuteConnected( 623 const std::function<Status(const lldb::PlatformSP &)> &func) { 624 SBError sb_error; 625 const auto platform_sp(GetSP()); 626 if (platform_sp) { 627 if (platform_sp->IsConnected()) 628 sb_error.ref() = func(platform_sp); 629 else 630 sb_error = Status::FromErrorString("not connected"); 631 } else 632 sb_error = Status::FromErrorString("invalid platform"); 633 634 return sb_error; 635 } 636 637 SBError SBPlatform::MakeDirectory(const char *path, uint32_t file_permissions) { 638 LLDB_INSTRUMENT_VA(this, path, file_permissions); 639 640 SBError sb_error; 641 PlatformSP platform_sp(GetSP()); 642 if (platform_sp) { 643 sb_error.ref() = 644 platform_sp->MakeDirectory(FileSpec(path), file_permissions); 645 } else { 646 sb_error = Status::FromErrorString("invalid platform"); 647 } 648 return sb_error; 649 } 650 651 uint32_t SBPlatform::GetFilePermissions(const char *path) { 652 LLDB_INSTRUMENT_VA(this, path); 653 654 PlatformSP platform_sp(GetSP()); 655 if (platform_sp) { 656 uint32_t file_permissions = 0; 657 platform_sp->GetFilePermissions(FileSpec(path), file_permissions); 658 return file_permissions; 659 } 660 return 0; 661 } 662 663 SBError SBPlatform::SetFilePermissions(const char *path, 664 uint32_t file_permissions) { 665 LLDB_INSTRUMENT_VA(this, path, file_permissions); 666 667 SBError sb_error; 668 PlatformSP platform_sp(GetSP()); 669 if (platform_sp) { 670 sb_error.ref() = 671 platform_sp->SetFilePermissions(FileSpec(path), file_permissions); 672 } else { 673 sb_error = Status::FromErrorString("invalid platform"); 674 } 675 return sb_error; 676 } 677 678 SBUnixSignals SBPlatform::GetUnixSignals() const { 679 LLDB_INSTRUMENT_VA(this); 680 681 if (auto platform_sp = GetSP()) 682 return SBUnixSignals{platform_sp}; 683 684 return SBUnixSignals(); 685 } 686 687 SBEnvironment SBPlatform::GetEnvironment() { 688 LLDB_INSTRUMENT_VA(this); 689 PlatformSP platform_sp(GetSP()); 690 691 if (platform_sp) { 692 return SBEnvironment(platform_sp->GetEnvironment()); 693 } 694 695 return SBEnvironment(); 696 } 697 698 SBError SBPlatform::SetLocateModuleCallback( 699 lldb::SBPlatformLocateModuleCallback callback, void *callback_baton) { 700 LLDB_INSTRUMENT_VA(this, callback, callback_baton); 701 PlatformSP platform_sp(GetSP()); 702 if (!platform_sp) 703 return SBError("invalid platform"); 704 705 if (!callback) { 706 // Clear the callback. 707 platform_sp->SetLocateModuleCallback(nullptr); 708 return SBError(); 709 } 710 711 // Platform.h does not accept lldb::SBPlatformLocateModuleCallback directly 712 // because of the SBModuleSpec and SBFileSpec dependencies. Use a lambda to 713 // convert ModuleSpec/FileSpec <--> SBModuleSpec/SBFileSpec for the callback 714 // arguments. 715 platform_sp->SetLocateModuleCallback( 716 [callback, callback_baton](const ModuleSpec &module_spec, 717 FileSpec &module_file_spec, 718 FileSpec &symbol_file_spec) { 719 SBModuleSpec module_spec_sb(module_spec); 720 SBFileSpec module_file_spec_sb; 721 SBFileSpec symbol_file_spec_sb; 722 723 SBError error = callback(callback_baton, module_spec_sb, 724 module_file_spec_sb, symbol_file_spec_sb); 725 726 if (error.Success()) { 727 module_file_spec = module_file_spec_sb.ref(); 728 symbol_file_spec = symbol_file_spec_sb.ref(); 729 } 730 731 return error.ref().Clone(); 732 }); 733 return SBError(); 734 } 735