1 //===-- Platform.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 <algorithm> 10 #include <csignal> 11 #include <fstream> 12 #include <memory> 13 #include <vector> 14 15 #include "lldb/Breakpoint/BreakpointIDList.h" 16 #include "lldb/Breakpoint/BreakpointLocation.h" 17 #include "lldb/Core/Debugger.h" 18 #include "lldb/Core/Module.h" 19 #include "lldb/Core/ModuleSpec.h" 20 #include "lldb/Core/PluginManager.h" 21 #include "lldb/Core/StreamFile.h" 22 #include "lldb/Host/FileCache.h" 23 #include "lldb/Host/FileSystem.h" 24 #include "lldb/Host/Host.h" 25 #include "lldb/Host/HostInfo.h" 26 #include "lldb/Host/OptionParser.h" 27 #include "lldb/Interpreter/OptionValueFileSpec.h" 28 #include "lldb/Interpreter/OptionValueProperties.h" 29 #include "lldb/Interpreter/Property.h" 30 #include "lldb/Symbol/ObjectFile.h" 31 #include "lldb/Target/ModuleCache.h" 32 #include "lldb/Target/Platform.h" 33 #include "lldb/Target/Process.h" 34 #include "lldb/Target/Target.h" 35 #include "lldb/Target/UnixSignals.h" 36 #include "lldb/Utility/DataBufferHeap.h" 37 #include "lldb/Utility/FileSpec.h" 38 #include "lldb/Utility/LLDBLog.h" 39 #include "lldb/Utility/Log.h" 40 #include "lldb/Utility/Status.h" 41 #include "lldb/Utility/StructuredData.h" 42 #include "llvm/ADT/STLExtras.h" 43 #include "llvm/Support/FileSystem.h" 44 #include "llvm/Support/Path.h" 45 46 // Define these constants from POSIX mman.h rather than include the file so 47 // that they will be correct even when compiled on Linux. 48 #define MAP_PRIVATE 2 49 #define MAP_ANON 0x1000 50 51 using namespace lldb; 52 using namespace lldb_private; 53 54 static uint32_t g_initialize_count = 0; 55 56 // Use a singleton function for g_local_platform_sp to avoid init constructors 57 // since LLDB is often part of a shared library 58 static PlatformSP &GetHostPlatformSP() { 59 static PlatformSP g_platform_sp; 60 return g_platform_sp; 61 } 62 63 const char *Platform::GetHostPlatformName() { return "host"; } 64 65 namespace { 66 67 #define LLDB_PROPERTIES_platform 68 #include "TargetProperties.inc" 69 70 enum { 71 #define LLDB_PROPERTIES_platform 72 #include "TargetPropertiesEnum.inc" 73 }; 74 75 } // namespace 76 77 ConstString PlatformProperties::GetSettingName() { 78 static ConstString g_setting_name("platform"); 79 return g_setting_name; 80 } 81 82 PlatformProperties::PlatformProperties() { 83 m_collection_sp = std::make_shared<OptionValueProperties>(GetSettingName()); 84 m_collection_sp->Initialize(g_platform_properties); 85 86 auto module_cache_dir = GetModuleCacheDirectory(); 87 if (module_cache_dir) 88 return; 89 90 llvm::SmallString<64> user_home_dir; 91 if (!FileSystem::Instance().GetHomeDirectory(user_home_dir)) 92 return; 93 94 module_cache_dir = FileSpec(user_home_dir.c_str()); 95 module_cache_dir.AppendPathComponent(".lldb"); 96 module_cache_dir.AppendPathComponent("module_cache"); 97 SetDefaultModuleCacheDirectory(module_cache_dir); 98 SetModuleCacheDirectory(module_cache_dir); 99 } 100 101 bool PlatformProperties::GetUseModuleCache() const { 102 const auto idx = ePropertyUseModuleCache; 103 return m_collection_sp->GetPropertyAtIndexAsBoolean( 104 nullptr, idx, g_platform_properties[idx].default_uint_value != 0); 105 } 106 107 bool PlatformProperties::SetUseModuleCache(bool use_module_cache) { 108 return m_collection_sp->SetPropertyAtIndexAsBoolean( 109 nullptr, ePropertyUseModuleCache, use_module_cache); 110 } 111 112 FileSpec PlatformProperties::GetModuleCacheDirectory() const { 113 return m_collection_sp->GetPropertyAtIndexAsFileSpec( 114 nullptr, ePropertyModuleCacheDirectory); 115 } 116 117 bool PlatformProperties::SetModuleCacheDirectory(const FileSpec &dir_spec) { 118 return m_collection_sp->SetPropertyAtIndexAsFileSpec( 119 nullptr, ePropertyModuleCacheDirectory, dir_spec); 120 } 121 122 void PlatformProperties::SetDefaultModuleCacheDirectory( 123 const FileSpec &dir_spec) { 124 auto f_spec_opt = m_collection_sp->GetPropertyAtIndexAsOptionValueFileSpec( 125 nullptr, false, ePropertyModuleCacheDirectory); 126 assert(f_spec_opt); 127 f_spec_opt->SetDefaultValue(dir_spec); 128 } 129 130 /// Get the native host platform plug-in. 131 /// 132 /// There should only be one of these for each host that LLDB runs 133 /// upon that should be statically compiled in and registered using 134 /// preprocessor macros or other similar build mechanisms. 135 /// 136 /// This platform will be used as the default platform when launching 137 /// or attaching to processes unless another platform is specified. 138 PlatformSP Platform::GetHostPlatform() { return GetHostPlatformSP(); } 139 140 static std::vector<PlatformSP> &GetPlatformList() { 141 static std::vector<PlatformSP> g_platform_list; 142 return g_platform_list; 143 } 144 145 static std::recursive_mutex &GetPlatformListMutex() { 146 static std::recursive_mutex g_mutex; 147 return g_mutex; 148 } 149 150 void Platform::Initialize() { g_initialize_count++; } 151 152 void Platform::Terminate() { 153 if (g_initialize_count > 0) { 154 if (--g_initialize_count == 0) { 155 std::lock_guard<std::recursive_mutex> guard(GetPlatformListMutex()); 156 GetPlatformList().clear(); 157 } 158 } 159 } 160 161 void Platform::Clear() { GetPlatformList().clear(); } 162 163 PlatformProperties &Platform::GetGlobalPlatformProperties() { 164 static PlatformProperties g_settings; 165 return g_settings; 166 } 167 168 void Platform::SetHostPlatform(const lldb::PlatformSP &platform_sp) { 169 // The native platform should use its static void Platform::Initialize() 170 // function to register itself as the native platform. 171 GetHostPlatformSP() = platform_sp; 172 173 if (platform_sp) { 174 std::lock_guard<std::recursive_mutex> guard(GetPlatformListMutex()); 175 GetPlatformList().push_back(platform_sp); 176 } 177 } 178 179 Status Platform::GetFileWithUUID(const FileSpec &platform_file, 180 const UUID *uuid_ptr, FileSpec &local_file) { 181 // Default to the local case 182 local_file = platform_file; 183 return Status(); 184 } 185 186 FileSpecList 187 Platform::LocateExecutableScriptingResources(Target *target, Module &module, 188 Stream *feedback_stream) { 189 return FileSpecList(); 190 } 191 192 // PlatformSP 193 // Platform::FindPlugin (Process *process, ConstString plugin_name) 194 //{ 195 // PlatformCreateInstance create_callback = nullptr; 196 // if (plugin_name) 197 // { 198 // create_callback = 199 // PluginManager::GetPlatformCreateCallbackForPluginName (plugin_name); 200 // if (create_callback) 201 // { 202 // ArchSpec arch; 203 // if (process) 204 // { 205 // arch = process->GetTarget().GetArchitecture(); 206 // } 207 // PlatformSP platform_sp(create_callback(process, &arch)); 208 // if (platform_sp) 209 // return platform_sp; 210 // } 211 // } 212 // else 213 // { 214 // for (uint32_t idx = 0; (create_callback = 215 // PluginManager::GetPlatformCreateCallbackAtIndex(idx)) != nullptr; 216 // ++idx) 217 // { 218 // PlatformSP platform_sp(create_callback(process, nullptr)); 219 // if (platform_sp) 220 // return platform_sp; 221 // } 222 // } 223 // return PlatformSP(); 224 //} 225 226 Status Platform::GetSharedModule( 227 const ModuleSpec &module_spec, Process *process, ModuleSP &module_sp, 228 const FileSpecList *module_search_paths_ptr, 229 llvm::SmallVectorImpl<lldb::ModuleSP> *old_modules, bool *did_create_ptr) { 230 if (IsHost()) 231 return ModuleList::GetSharedModule(module_spec, module_sp, 232 module_search_paths_ptr, old_modules, 233 did_create_ptr, false); 234 235 // Module resolver lambda. 236 auto resolver = [&](const ModuleSpec &spec) { 237 Status error(eErrorTypeGeneric); 238 ModuleSpec resolved_spec; 239 // Check if we have sysroot set. 240 if (m_sdk_sysroot) { 241 // Prepend sysroot to module spec. 242 resolved_spec = spec; 243 resolved_spec.GetFileSpec().PrependPathComponent( 244 m_sdk_sysroot.GetStringRef()); 245 // Try to get shared module with resolved spec. 246 error = ModuleList::GetSharedModule(resolved_spec, module_sp, 247 module_search_paths_ptr, old_modules, 248 did_create_ptr, false); 249 } 250 // If we don't have sysroot or it didn't work then 251 // try original module spec. 252 if (!error.Success()) { 253 resolved_spec = spec; 254 error = ModuleList::GetSharedModule(resolved_spec, module_sp, 255 module_search_paths_ptr, old_modules, 256 did_create_ptr, false); 257 } 258 if (error.Success() && module_sp) 259 module_sp->SetPlatformFileSpec(resolved_spec.GetFileSpec()); 260 return error; 261 }; 262 263 return GetRemoteSharedModule(module_spec, process, module_sp, resolver, 264 did_create_ptr); 265 } 266 267 bool Platform::GetModuleSpec(const FileSpec &module_file_spec, 268 const ArchSpec &arch, ModuleSpec &module_spec) { 269 ModuleSpecList module_specs; 270 if (ObjectFile::GetModuleSpecifications(module_file_spec, 0, 0, 271 module_specs) == 0) 272 return false; 273 274 ModuleSpec matched_module_spec; 275 return module_specs.FindMatchingModuleSpec(ModuleSpec(module_file_spec, arch), 276 module_spec); 277 } 278 279 PlatformSP Platform::Find(ConstString name) { 280 if (name) { 281 static ConstString g_host_platform_name("host"); 282 if (name == g_host_platform_name) 283 return GetHostPlatform(); 284 285 std::lock_guard<std::recursive_mutex> guard(GetPlatformListMutex()); 286 for (const auto &platform_sp : GetPlatformList()) { 287 if (platform_sp->GetName() == name.GetStringRef()) 288 return platform_sp; 289 } 290 } 291 return PlatformSP(); 292 } 293 294 PlatformSP Platform::Create(ConstString name, Status &error) { 295 PlatformCreateInstance create_callback = nullptr; 296 lldb::PlatformSP platform_sp; 297 if (name) { 298 static ConstString g_host_platform_name("host"); 299 if (name == g_host_platform_name) 300 return GetHostPlatform(); 301 302 create_callback = PluginManager::GetPlatformCreateCallbackForPluginName( 303 name.GetStringRef()); 304 if (create_callback) 305 platform_sp = create_callback(true, nullptr); 306 else 307 error.SetErrorStringWithFormat( 308 "unable to find a plug-in for the platform named \"%s\"", 309 name.GetCString()); 310 } else 311 error.SetErrorString("invalid platform name"); 312 313 if (platform_sp) { 314 std::lock_guard<std::recursive_mutex> guard(GetPlatformListMutex()); 315 GetPlatformList().push_back(platform_sp); 316 } 317 318 return platform_sp; 319 } 320 321 PlatformSP Platform::Create(const ArchSpec &arch, 322 const ArchSpec &process_host_arch, 323 ArchSpec *platform_arch_ptr, Status &error) { 324 lldb::PlatformSP platform_sp; 325 if (arch.IsValid()) { 326 // Scope for locker 327 { 328 // First try exact arch matches across all platforms already created 329 std::lock_guard<std::recursive_mutex> guard(GetPlatformListMutex()); 330 for (const auto &platform_sp : GetPlatformList()) { 331 if (platform_sp->IsCompatibleArchitecture(arch, process_host_arch, true, 332 platform_arch_ptr)) 333 return platform_sp; 334 } 335 336 // Next try compatible arch matches across all platforms already created 337 for (const auto &platform_sp : GetPlatformList()) { 338 if (platform_sp->IsCompatibleArchitecture(arch, process_host_arch, 339 false, platform_arch_ptr)) 340 return platform_sp; 341 } 342 } 343 344 PlatformCreateInstance create_callback; 345 // First try exact arch matches across all platform plug-ins 346 uint32_t idx; 347 for (idx = 0; (create_callback = 348 PluginManager::GetPlatformCreateCallbackAtIndex(idx)); 349 ++idx) { 350 if (create_callback) { 351 platform_sp = create_callback(false, &arch); 352 if (platform_sp && 353 platform_sp->IsCompatibleArchitecture(arch, process_host_arch, true, 354 platform_arch_ptr)) { 355 std::lock_guard<std::recursive_mutex> guard(GetPlatformListMutex()); 356 GetPlatformList().push_back(platform_sp); 357 return platform_sp; 358 } 359 } 360 } 361 // Next try compatible arch matches across all platform plug-ins 362 for (idx = 0; (create_callback = 363 PluginManager::GetPlatformCreateCallbackAtIndex(idx)); 364 ++idx) { 365 if (create_callback) { 366 platform_sp = create_callback(false, &arch); 367 if (platform_sp && 368 platform_sp->IsCompatibleArchitecture(arch, process_host_arch, 369 false, platform_arch_ptr)) { 370 std::lock_guard<std::recursive_mutex> guard(GetPlatformListMutex()); 371 GetPlatformList().push_back(platform_sp); 372 return platform_sp; 373 } 374 } 375 } 376 } else 377 error.SetErrorString("invalid platform name"); 378 if (platform_arch_ptr) 379 platform_arch_ptr->Clear(); 380 platform_sp.reset(); 381 return platform_sp; 382 } 383 384 ArchSpec Platform::GetAugmentedArchSpec(Platform *platform, llvm::StringRef triple) { 385 if (platform) 386 return platform->GetAugmentedArchSpec(triple); 387 return HostInfo::GetAugmentedArchSpec(triple); 388 } 389 390 /// Default Constructor 391 Platform::Platform(bool is_host) 392 : m_is_host(is_host), m_os_version_set_while_connected(false), 393 m_system_arch_set_while_connected(false), m_max_uid_name_len(0), 394 m_max_gid_name_len(0), m_supports_rsync(false), m_rsync_opts(), 395 m_rsync_prefix(), m_supports_ssh(false), m_ssh_opts(), 396 m_ignores_remote_hostname(false), m_trap_handlers(), 397 m_calculated_trap_handlers(false), 398 m_module_cache(std::make_unique<ModuleCache>()) { 399 Log *log = GetLog(LLDBLog::Object); 400 LLDB_LOGF(log, "%p Platform::Platform()", static_cast<void *>(this)); 401 } 402 403 Platform::~Platform() = default; 404 405 void Platform::GetStatus(Stream &strm) { 406 strm.Format(" Platform: {0}\n", GetPluginName()); 407 408 ArchSpec arch(GetSystemArchitecture()); 409 if (arch.IsValid()) { 410 if (!arch.GetTriple().str().empty()) { 411 strm.Printf(" Triple: "); 412 arch.DumpTriple(strm.AsRawOstream()); 413 strm.EOL(); 414 } 415 } 416 417 llvm::VersionTuple os_version = GetOSVersion(); 418 if (!os_version.empty()) { 419 strm.Format("OS Version: {0}", os_version.getAsString()); 420 421 if (llvm::Optional<std::string> s = GetOSBuildString()) 422 strm.Format(" ({0})", *s); 423 424 strm.EOL(); 425 } 426 427 if (IsHost()) { 428 strm.Printf(" Hostname: %s\n", GetHostname()); 429 } else { 430 const bool is_connected = IsConnected(); 431 if (is_connected) 432 strm.Printf(" Hostname: %s\n", GetHostname()); 433 strm.Printf(" Connected: %s\n", is_connected ? "yes" : "no"); 434 } 435 436 if (GetSDKRootDirectory()) { 437 strm.Format(" Sysroot: {0}\n", GetSDKRootDirectory()); 438 } 439 if (GetWorkingDirectory()) { 440 strm.Printf("WorkingDir: %s\n", GetWorkingDirectory().GetCString()); 441 } 442 if (!IsConnected()) 443 return; 444 445 std::string specific_info(GetPlatformSpecificConnectionInformation()); 446 447 if (!specific_info.empty()) 448 strm.Printf("Platform-specific connection: %s\n", specific_info.c_str()); 449 450 if (llvm::Optional<std::string> s = GetOSKernelDescription()) 451 strm.Format(" Kernel: {0}\n", *s); 452 } 453 454 llvm::VersionTuple Platform::GetOSVersion(Process *process) { 455 std::lock_guard<std::mutex> guard(m_mutex); 456 457 if (IsHost()) { 458 if (m_os_version.empty()) { 459 // We have a local host platform 460 m_os_version = HostInfo::GetOSVersion(); 461 m_os_version_set_while_connected = !m_os_version.empty(); 462 } 463 } else { 464 // We have a remote platform. We can only fetch the remote 465 // OS version if we are connected, and we don't want to do it 466 // more than once. 467 468 const bool is_connected = IsConnected(); 469 470 bool fetch = false; 471 if (!m_os_version.empty()) { 472 // We have valid OS version info, check to make sure it wasn't manually 473 // set prior to connecting. If it was manually set prior to connecting, 474 // then lets fetch the actual OS version info if we are now connected. 475 if (is_connected && !m_os_version_set_while_connected) 476 fetch = true; 477 } else { 478 // We don't have valid OS version info, fetch it if we are connected 479 fetch = is_connected; 480 } 481 482 if (fetch) 483 m_os_version_set_while_connected = GetRemoteOSVersion(); 484 } 485 486 if (!m_os_version.empty()) 487 return m_os_version; 488 if (process) { 489 // Check with the process in case it can answer the question if a process 490 // was provided 491 return process->GetHostOSVersion(); 492 } 493 return llvm::VersionTuple(); 494 } 495 496 llvm::Optional<std::string> Platform::GetOSBuildString() { 497 if (IsHost()) 498 return HostInfo::GetOSBuildString(); 499 return GetRemoteOSBuildString(); 500 } 501 502 llvm::Optional<std::string> Platform::GetOSKernelDescription() { 503 if (IsHost()) 504 return HostInfo::GetOSKernelDescription(); 505 return GetRemoteOSKernelDescription(); 506 } 507 508 void Platform::AddClangModuleCompilationOptions( 509 Target *target, std::vector<std::string> &options) { 510 std::vector<std::string> default_compilation_options = { 511 "-x", "c++", "-Xclang", "-nostdsysteminc", "-Xclang", "-nostdsysteminc"}; 512 513 options.insert(options.end(), default_compilation_options.begin(), 514 default_compilation_options.end()); 515 } 516 517 FileSpec Platform::GetWorkingDirectory() { 518 if (IsHost()) { 519 llvm::SmallString<64> cwd; 520 if (llvm::sys::fs::current_path(cwd)) 521 return {}; 522 else { 523 FileSpec file_spec(cwd); 524 FileSystem::Instance().Resolve(file_spec); 525 return file_spec; 526 } 527 } else { 528 if (!m_working_dir) 529 m_working_dir = GetRemoteWorkingDirectory(); 530 return m_working_dir; 531 } 532 } 533 534 struct RecurseCopyBaton { 535 const FileSpec &dst; 536 Platform *platform_ptr; 537 Status error; 538 }; 539 540 static FileSystem::EnumerateDirectoryResult 541 RecurseCopy_Callback(void *baton, llvm::sys::fs::file_type ft, 542 llvm::StringRef path) { 543 RecurseCopyBaton *rc_baton = (RecurseCopyBaton *)baton; 544 FileSpec src(path); 545 namespace fs = llvm::sys::fs; 546 switch (ft) { 547 case fs::file_type::fifo_file: 548 case fs::file_type::socket_file: 549 // we have no way to copy pipes and sockets - ignore them and continue 550 return FileSystem::eEnumerateDirectoryResultNext; 551 break; 552 553 case fs::file_type::directory_file: { 554 // make the new directory and get in there 555 FileSpec dst_dir = rc_baton->dst; 556 if (!dst_dir.GetFilename()) 557 dst_dir.GetFilename() = src.GetLastPathComponent(); 558 Status error = rc_baton->platform_ptr->MakeDirectory( 559 dst_dir, lldb::eFilePermissionsDirectoryDefault); 560 if (error.Fail()) { 561 rc_baton->error.SetErrorStringWithFormat( 562 "unable to setup directory %s on remote end", dst_dir.GetCString()); 563 return FileSystem::eEnumerateDirectoryResultQuit; // got an error, bail out 564 } 565 566 // now recurse 567 std::string src_dir_path(src.GetPath()); 568 569 // Make a filespec that only fills in the directory of a FileSpec so when 570 // we enumerate we can quickly fill in the filename for dst copies 571 FileSpec recurse_dst; 572 recurse_dst.GetDirectory().SetCString(dst_dir.GetPath().c_str()); 573 RecurseCopyBaton rc_baton2 = {recurse_dst, rc_baton->platform_ptr, 574 Status()}; 575 FileSystem::Instance().EnumerateDirectory(src_dir_path, true, true, true, 576 RecurseCopy_Callback, &rc_baton2); 577 if (rc_baton2.error.Fail()) { 578 rc_baton->error.SetErrorString(rc_baton2.error.AsCString()); 579 return FileSystem::eEnumerateDirectoryResultQuit; // got an error, bail out 580 } 581 return FileSystem::eEnumerateDirectoryResultNext; 582 } break; 583 584 case fs::file_type::symlink_file: { 585 // copy the file and keep going 586 FileSpec dst_file = rc_baton->dst; 587 if (!dst_file.GetFilename()) 588 dst_file.GetFilename() = src.GetFilename(); 589 590 FileSpec src_resolved; 591 592 rc_baton->error = FileSystem::Instance().Readlink(src, src_resolved); 593 594 if (rc_baton->error.Fail()) 595 return FileSystem::eEnumerateDirectoryResultQuit; // got an error, bail out 596 597 rc_baton->error = 598 rc_baton->platform_ptr->CreateSymlink(dst_file, src_resolved); 599 600 if (rc_baton->error.Fail()) 601 return FileSystem::eEnumerateDirectoryResultQuit; // got an error, bail out 602 603 return FileSystem::eEnumerateDirectoryResultNext; 604 } break; 605 606 case fs::file_type::regular_file: { 607 // copy the file and keep going 608 FileSpec dst_file = rc_baton->dst; 609 if (!dst_file.GetFilename()) 610 dst_file.GetFilename() = src.GetFilename(); 611 Status err = rc_baton->platform_ptr->PutFile(src, dst_file); 612 if (err.Fail()) { 613 rc_baton->error.SetErrorString(err.AsCString()); 614 return FileSystem::eEnumerateDirectoryResultQuit; // got an error, bail out 615 } 616 return FileSystem::eEnumerateDirectoryResultNext; 617 } break; 618 619 default: 620 rc_baton->error.SetErrorStringWithFormat( 621 "invalid file detected during copy: %s", src.GetPath().c_str()); 622 return FileSystem::eEnumerateDirectoryResultQuit; // got an error, bail out 623 break; 624 } 625 llvm_unreachable("Unhandled file_type!"); 626 } 627 628 Status Platform::Install(const FileSpec &src, const FileSpec &dst) { 629 Status error; 630 631 Log *log = GetLog(LLDBLog::Platform); 632 LLDB_LOGF(log, "Platform::Install (src='%s', dst='%s')", 633 src.GetPath().c_str(), dst.GetPath().c_str()); 634 FileSpec fixed_dst(dst); 635 636 if (!fixed_dst.GetFilename()) 637 fixed_dst.GetFilename() = src.GetFilename(); 638 639 FileSpec working_dir = GetWorkingDirectory(); 640 641 if (dst) { 642 if (dst.GetDirectory()) { 643 const char first_dst_dir_char = dst.GetDirectory().GetCString()[0]; 644 if (first_dst_dir_char == '/' || first_dst_dir_char == '\\') { 645 fixed_dst.GetDirectory() = dst.GetDirectory(); 646 } 647 // If the fixed destination file doesn't have a directory yet, then we 648 // must have a relative path. We will resolve this relative path against 649 // the platform's working directory 650 if (!fixed_dst.GetDirectory()) { 651 FileSpec relative_spec; 652 std::string path; 653 if (working_dir) { 654 relative_spec = working_dir; 655 relative_spec.AppendPathComponent(dst.GetPath()); 656 fixed_dst.GetDirectory() = relative_spec.GetDirectory(); 657 } else { 658 error.SetErrorStringWithFormat( 659 "platform working directory must be valid for relative path '%s'", 660 dst.GetPath().c_str()); 661 return error; 662 } 663 } 664 } else { 665 if (working_dir) { 666 fixed_dst.GetDirectory().SetCString(working_dir.GetCString()); 667 } else { 668 error.SetErrorStringWithFormat( 669 "platform working directory must be valid for relative path '%s'", 670 dst.GetPath().c_str()); 671 return error; 672 } 673 } 674 } else { 675 if (working_dir) { 676 fixed_dst.GetDirectory().SetCString(working_dir.GetCString()); 677 } else { 678 error.SetErrorStringWithFormat("platform working directory must be valid " 679 "when destination directory is empty"); 680 return error; 681 } 682 } 683 684 LLDB_LOGF(log, "Platform::Install (src='%s', dst='%s') fixed_dst='%s'", 685 src.GetPath().c_str(), dst.GetPath().c_str(), 686 fixed_dst.GetPath().c_str()); 687 688 if (GetSupportsRSync()) { 689 error = PutFile(src, dst); 690 } else { 691 namespace fs = llvm::sys::fs; 692 switch (fs::get_file_type(src.GetPath(), false)) { 693 case fs::file_type::directory_file: { 694 llvm::sys::fs::remove(fixed_dst.GetPath()); 695 uint32_t permissions = FileSystem::Instance().GetPermissions(src); 696 if (permissions == 0) 697 permissions = eFilePermissionsDirectoryDefault; 698 error = MakeDirectory(fixed_dst, permissions); 699 if (error.Success()) { 700 // Make a filespec that only fills in the directory of a FileSpec so 701 // when we enumerate we can quickly fill in the filename for dst copies 702 FileSpec recurse_dst; 703 recurse_dst.GetDirectory().SetCString(fixed_dst.GetCString()); 704 std::string src_dir_path(src.GetPath()); 705 RecurseCopyBaton baton = {recurse_dst, this, Status()}; 706 FileSystem::Instance().EnumerateDirectory( 707 src_dir_path, true, true, true, RecurseCopy_Callback, &baton); 708 return baton.error; 709 } 710 } break; 711 712 case fs::file_type::regular_file: 713 llvm::sys::fs::remove(fixed_dst.GetPath()); 714 error = PutFile(src, fixed_dst); 715 break; 716 717 case fs::file_type::symlink_file: { 718 llvm::sys::fs::remove(fixed_dst.GetPath()); 719 FileSpec src_resolved; 720 error = FileSystem::Instance().Readlink(src, src_resolved); 721 if (error.Success()) 722 error = CreateSymlink(dst, src_resolved); 723 } break; 724 case fs::file_type::fifo_file: 725 error.SetErrorString("platform install doesn't handle pipes"); 726 break; 727 case fs::file_type::socket_file: 728 error.SetErrorString("platform install doesn't handle sockets"); 729 break; 730 default: 731 error.SetErrorString( 732 "platform install doesn't handle non file or directory items"); 733 break; 734 } 735 } 736 return error; 737 } 738 739 bool Platform::SetWorkingDirectory(const FileSpec &file_spec) { 740 if (IsHost()) { 741 Log *log = GetLog(LLDBLog::Platform); 742 LLDB_LOG(log, "{0}", file_spec); 743 if (std::error_code ec = llvm::sys::fs::set_current_path(file_spec.GetPath())) { 744 LLDB_LOG(log, "error: {0}", ec.message()); 745 return false; 746 } 747 return true; 748 } else { 749 m_working_dir.Clear(); 750 return SetRemoteWorkingDirectory(file_spec); 751 } 752 } 753 754 Status Platform::MakeDirectory(const FileSpec &file_spec, 755 uint32_t permissions) { 756 if (IsHost()) 757 return llvm::sys::fs::create_directory(file_spec.GetPath(), permissions); 758 else { 759 Status error; 760 error.SetErrorStringWithFormatv("remote platform {0} doesn't support {1}", 761 GetPluginName(), LLVM_PRETTY_FUNCTION); 762 return error; 763 } 764 } 765 766 Status Platform::GetFilePermissions(const FileSpec &file_spec, 767 uint32_t &file_permissions) { 768 if (IsHost()) { 769 auto Value = llvm::sys::fs::getPermissions(file_spec.GetPath()); 770 if (Value) 771 file_permissions = Value.get(); 772 return Status(Value.getError()); 773 } else { 774 Status error; 775 error.SetErrorStringWithFormatv("remote platform {0} doesn't support {1}", 776 GetPluginName(), LLVM_PRETTY_FUNCTION); 777 return error; 778 } 779 } 780 781 Status Platform::SetFilePermissions(const FileSpec &file_spec, 782 uint32_t file_permissions) { 783 if (IsHost()) { 784 auto Perms = static_cast<llvm::sys::fs::perms>(file_permissions); 785 return llvm::sys::fs::setPermissions(file_spec.GetPath(), Perms); 786 } else { 787 Status error; 788 error.SetErrorStringWithFormatv("remote platform {0} doesn't support {1}", 789 GetPluginName(), LLVM_PRETTY_FUNCTION); 790 return error; 791 } 792 } 793 794 user_id_t Platform::OpenFile(const FileSpec &file_spec, 795 File::OpenOptions flags, uint32_t mode, 796 Status &error) { 797 if (IsHost()) 798 return FileCache::GetInstance().OpenFile(file_spec, flags, mode, error); 799 return UINT64_MAX; 800 } 801 802 bool Platform::CloseFile(user_id_t fd, Status &error) { 803 if (IsHost()) 804 return FileCache::GetInstance().CloseFile(fd, error); 805 return false; 806 } 807 808 user_id_t Platform::GetFileSize(const FileSpec &file_spec) { 809 if (!IsHost()) 810 return UINT64_MAX; 811 812 uint64_t Size; 813 if (llvm::sys::fs::file_size(file_spec.GetPath(), Size)) 814 return 0; 815 return Size; 816 } 817 818 uint64_t Platform::ReadFile(lldb::user_id_t fd, uint64_t offset, void *dst, 819 uint64_t dst_len, Status &error) { 820 if (IsHost()) 821 return FileCache::GetInstance().ReadFile(fd, offset, dst, dst_len, error); 822 error.SetErrorStringWithFormatv( 823 "Platform::ReadFile() is not supported in the {0} platform", 824 GetPluginName()); 825 return -1; 826 } 827 828 uint64_t Platform::WriteFile(lldb::user_id_t fd, uint64_t offset, 829 const void *src, uint64_t src_len, Status &error) { 830 if (IsHost()) 831 return FileCache::GetInstance().WriteFile(fd, offset, src, src_len, error); 832 error.SetErrorStringWithFormatv( 833 "Platform::WriteFile() is not supported in the {0} platform", 834 GetPluginName()); 835 return -1; 836 } 837 838 UserIDResolver &Platform::GetUserIDResolver() { 839 if (IsHost()) 840 return HostInfo::GetUserIDResolver(); 841 return UserIDResolver::GetNoopResolver(); 842 } 843 844 const char *Platform::GetHostname() { 845 if (IsHost()) 846 return "127.0.0.1"; 847 848 if (m_hostname.empty()) 849 return nullptr; 850 return m_hostname.c_str(); 851 } 852 853 ConstString Platform::GetFullNameForDylib(ConstString basename) { 854 return basename; 855 } 856 857 bool Platform::SetRemoteWorkingDirectory(const FileSpec &working_dir) { 858 Log *log = GetLog(LLDBLog::Platform); 859 LLDB_LOGF(log, "Platform::SetRemoteWorkingDirectory('%s')", 860 working_dir.GetCString()); 861 m_working_dir = working_dir; 862 return true; 863 } 864 865 bool Platform::SetOSVersion(llvm::VersionTuple version) { 866 if (IsHost()) { 867 // We don't need anyone setting the OS version for the host platform, we 868 // should be able to figure it out by calling HostInfo::GetOSVersion(...). 869 return false; 870 } else { 871 // We have a remote platform, allow setting the target OS version if we 872 // aren't connected, since if we are connected, we should be able to 873 // request the remote OS version from the connected platform. 874 if (IsConnected()) 875 return false; 876 else { 877 // We aren't connected and we might want to set the OS version ahead of 878 // time before we connect so we can peruse files and use a local SDK or 879 // PDK cache of support files to disassemble or do other things. 880 m_os_version = version; 881 return true; 882 } 883 } 884 return false; 885 } 886 887 Status 888 Platform::ResolveExecutable(const ModuleSpec &module_spec, 889 lldb::ModuleSP &exe_module_sp, 890 const FileSpecList *module_search_paths_ptr) { 891 Status error; 892 893 if (FileSystem::Instance().Exists(module_spec.GetFileSpec())) { 894 if (module_spec.GetArchitecture().IsValid()) { 895 error = ModuleList::GetSharedModule(module_spec, exe_module_sp, 896 module_search_paths_ptr, nullptr, 897 nullptr); 898 } else { 899 // No valid architecture was specified, ask the platform for the 900 // architectures that we should be using (in the correct order) and see 901 // if we can find a match that way 902 ModuleSpec arch_module_spec(module_spec); 903 ArchSpec process_host_arch; 904 for (const ArchSpec &arch : 905 GetSupportedArchitectures(process_host_arch)) { 906 arch_module_spec.GetArchitecture() = arch; 907 error = ModuleList::GetSharedModule(arch_module_spec, exe_module_sp, 908 module_search_paths_ptr, nullptr, 909 nullptr); 910 // Did we find an executable using one of the 911 if (error.Success() && exe_module_sp) 912 break; 913 } 914 } 915 } else { 916 error.SetErrorStringWithFormat( 917 "'%s' does not exist", module_spec.GetFileSpec().GetPath().c_str()); 918 } 919 return error; 920 } 921 922 Status 923 Platform::ResolveRemoteExecutable(const ModuleSpec &module_spec, 924 lldb::ModuleSP &exe_module_sp, 925 const FileSpecList *module_search_paths_ptr) { 926 Status error; 927 928 // We may connect to a process and use the provided executable (Don't use 929 // local $PATH). 930 ModuleSpec resolved_module_spec(module_spec); 931 932 // Resolve any executable within a bundle on MacOSX 933 Host::ResolveExecutableInBundle(resolved_module_spec.GetFileSpec()); 934 935 if (FileSystem::Instance().Exists(resolved_module_spec.GetFileSpec()) || 936 module_spec.GetUUID().IsValid()) { 937 if (resolved_module_spec.GetArchitecture().IsValid() || 938 resolved_module_spec.GetUUID().IsValid()) { 939 error = ModuleList::GetSharedModule(resolved_module_spec, exe_module_sp, 940 module_search_paths_ptr, nullptr, 941 nullptr); 942 943 if (exe_module_sp && exe_module_sp->GetObjectFile()) 944 return error; 945 exe_module_sp.reset(); 946 } 947 // No valid architecture was specified or the exact arch wasn't found so 948 // ask the platform for the architectures that we should be using (in the 949 // correct order) and see if we can find a match that way 950 StreamString arch_names; 951 llvm::ListSeparator LS; 952 ArchSpec process_host_arch; 953 for (const ArchSpec &arch : GetSupportedArchitectures(process_host_arch)) { 954 resolved_module_spec.GetArchitecture() = arch; 955 error = ModuleList::GetSharedModule(resolved_module_spec, exe_module_sp, 956 module_search_paths_ptr, nullptr, 957 nullptr); 958 // Did we find an executable using one of the 959 if (error.Success()) { 960 if (exe_module_sp && exe_module_sp->GetObjectFile()) 961 break; 962 else 963 error.SetErrorToGenericError(); 964 } 965 966 arch_names << LS << arch.GetArchitectureName(); 967 } 968 969 if (error.Fail() || !exe_module_sp) { 970 if (FileSystem::Instance().Readable(resolved_module_spec.GetFileSpec())) { 971 error.SetErrorStringWithFormatv( 972 "'{0}' doesn't contain any '{1}' platform architectures: {2}", 973 resolved_module_spec.GetFileSpec(), GetPluginName(), 974 arch_names.GetData()); 975 } else { 976 error.SetErrorStringWithFormatv("'{0}' is not readable", 977 resolved_module_spec.GetFileSpec()); 978 } 979 } 980 } else { 981 error.SetErrorStringWithFormatv("'{0}' does not exist", 982 resolved_module_spec.GetFileSpec()); 983 } 984 985 return error; 986 } 987 988 Status Platform::ResolveSymbolFile(Target &target, const ModuleSpec &sym_spec, 989 FileSpec &sym_file) { 990 Status error; 991 if (FileSystem::Instance().Exists(sym_spec.GetSymbolFileSpec())) 992 sym_file = sym_spec.GetSymbolFileSpec(); 993 else 994 error.SetErrorString("unable to resolve symbol file"); 995 return error; 996 } 997 998 bool Platform::ResolveRemotePath(const FileSpec &platform_path, 999 FileSpec &resolved_platform_path) { 1000 resolved_platform_path = platform_path; 1001 FileSystem::Instance().Resolve(resolved_platform_path); 1002 return true; 1003 } 1004 1005 const ArchSpec &Platform::GetSystemArchitecture() { 1006 if (IsHost()) { 1007 if (!m_system_arch.IsValid()) { 1008 // We have a local host platform 1009 m_system_arch = HostInfo::GetArchitecture(); 1010 m_system_arch_set_while_connected = m_system_arch.IsValid(); 1011 } 1012 } else { 1013 // We have a remote platform. We can only fetch the remote system 1014 // architecture if we are connected, and we don't want to do it more than 1015 // once. 1016 1017 const bool is_connected = IsConnected(); 1018 1019 bool fetch = false; 1020 if (m_system_arch.IsValid()) { 1021 // We have valid OS version info, check to make sure it wasn't manually 1022 // set prior to connecting. If it was manually set prior to connecting, 1023 // then lets fetch the actual OS version info if we are now connected. 1024 if (is_connected && !m_system_arch_set_while_connected) 1025 fetch = true; 1026 } else { 1027 // We don't have valid OS version info, fetch it if we are connected 1028 fetch = is_connected; 1029 } 1030 1031 if (fetch) { 1032 m_system_arch = GetRemoteSystemArchitecture(); 1033 m_system_arch_set_while_connected = m_system_arch.IsValid(); 1034 } 1035 } 1036 return m_system_arch; 1037 } 1038 1039 ArchSpec Platform::GetAugmentedArchSpec(llvm::StringRef triple) { 1040 if (triple.empty()) 1041 return ArchSpec(); 1042 llvm::Triple normalized_triple(llvm::Triple::normalize(triple)); 1043 if (!ArchSpec::ContainsOnlyArch(normalized_triple)) 1044 return ArchSpec(triple); 1045 1046 if (auto kind = HostInfo::ParseArchitectureKind(triple)) 1047 return HostInfo::GetArchitecture(*kind); 1048 1049 ArchSpec compatible_arch; 1050 ArchSpec raw_arch(triple); 1051 if (!IsCompatibleArchitecture(raw_arch, {}, false, &compatible_arch)) 1052 return raw_arch; 1053 1054 if (!compatible_arch.IsValid()) 1055 return ArchSpec(normalized_triple); 1056 1057 const llvm::Triple &compatible_triple = compatible_arch.GetTriple(); 1058 if (normalized_triple.getVendorName().empty()) 1059 normalized_triple.setVendor(compatible_triple.getVendor()); 1060 if (normalized_triple.getOSName().empty()) 1061 normalized_triple.setOS(compatible_triple.getOS()); 1062 if (normalized_triple.getEnvironmentName().empty()) 1063 normalized_triple.setEnvironment(compatible_triple.getEnvironment()); 1064 return ArchSpec(normalized_triple); 1065 } 1066 1067 Status Platform::ConnectRemote(Args &args) { 1068 Status error; 1069 if (IsHost()) 1070 error.SetErrorStringWithFormatv( 1071 "The currently selected platform ({0}) is " 1072 "the host platform and is always connected.", 1073 GetPluginName()); 1074 else 1075 error.SetErrorStringWithFormatv( 1076 "Platform::ConnectRemote() is not supported by {0}", GetPluginName()); 1077 return error; 1078 } 1079 1080 Status Platform::DisconnectRemote() { 1081 Status error; 1082 if (IsHost()) 1083 error.SetErrorStringWithFormatv( 1084 "The currently selected platform ({0}) is " 1085 "the host platform and is always connected.", 1086 GetPluginName()); 1087 else 1088 error.SetErrorStringWithFormatv( 1089 "Platform::DisconnectRemote() is not supported by {0}", 1090 GetPluginName()); 1091 return error; 1092 } 1093 1094 bool Platform::GetProcessInfo(lldb::pid_t pid, 1095 ProcessInstanceInfo &process_info) { 1096 // Take care of the host case so that each subclass can just call this 1097 // function to get the host functionality. 1098 if (IsHost()) 1099 return Host::GetProcessInfo(pid, process_info); 1100 return false; 1101 } 1102 1103 uint32_t Platform::FindProcesses(const ProcessInstanceInfoMatch &match_info, 1104 ProcessInstanceInfoList &process_infos) { 1105 // Take care of the host case so that each subclass can just call this 1106 // function to get the host functionality. 1107 uint32_t match_count = 0; 1108 if (IsHost()) 1109 match_count = Host::FindProcesses(match_info, process_infos); 1110 return match_count; 1111 } 1112 1113 Status Platform::LaunchProcess(ProcessLaunchInfo &launch_info) { 1114 Status error; 1115 Log *log = GetLog(LLDBLog::Platform); 1116 LLDB_LOGF(log, "Platform::%s()", __FUNCTION__); 1117 1118 // Take care of the host case so that each subclass can just call this 1119 // function to get the host functionality. 1120 if (IsHost()) { 1121 if (::getenv("LLDB_LAUNCH_FLAG_LAUNCH_IN_TTY")) 1122 launch_info.GetFlags().Set(eLaunchFlagLaunchInTTY); 1123 1124 if (launch_info.GetFlags().Test(eLaunchFlagLaunchInShell)) { 1125 const bool will_debug = launch_info.GetFlags().Test(eLaunchFlagDebug); 1126 const bool first_arg_is_full_shell_command = false; 1127 uint32_t num_resumes = GetResumeCountForLaunchInfo(launch_info); 1128 if (log) { 1129 const FileSpec &shell = launch_info.GetShell(); 1130 std::string shell_str = (shell) ? shell.GetPath() : "<null>"; 1131 LLDB_LOGF(log, 1132 "Platform::%s GetResumeCountForLaunchInfo() returned %" PRIu32 1133 ", shell is '%s'", 1134 __FUNCTION__, num_resumes, shell_str.c_str()); 1135 } 1136 1137 if (!launch_info.ConvertArgumentsForLaunchingInShell( 1138 error, will_debug, first_arg_is_full_shell_command, num_resumes)) 1139 return error; 1140 } else if (launch_info.GetFlags().Test(eLaunchFlagShellExpandArguments)) { 1141 error = ShellExpandArguments(launch_info); 1142 if (error.Fail()) { 1143 error.SetErrorStringWithFormat("shell expansion failed (reason: %s). " 1144 "consider launching with 'process " 1145 "launch'.", 1146 error.AsCString("unknown")); 1147 return error; 1148 } 1149 } 1150 1151 LLDB_LOGF(log, "Platform::%s final launch_info resume count: %" PRIu32, 1152 __FUNCTION__, launch_info.GetResumeCount()); 1153 1154 error = Host::LaunchProcess(launch_info); 1155 } else 1156 error.SetErrorString( 1157 "base lldb_private::Platform class can't launch remote processes"); 1158 return error; 1159 } 1160 1161 Status Platform::ShellExpandArguments(ProcessLaunchInfo &launch_info) { 1162 if (IsHost()) 1163 return Host::ShellExpandArguments(launch_info); 1164 return Status("base lldb_private::Platform class can't expand arguments"); 1165 } 1166 1167 Status Platform::KillProcess(const lldb::pid_t pid) { 1168 Log *log = GetLog(LLDBLog::Platform); 1169 LLDB_LOGF(log, "Platform::%s, pid %" PRIu64, __FUNCTION__, pid); 1170 1171 if (!IsHost()) { 1172 return Status( 1173 "base lldb_private::Platform class can't kill remote processes"); 1174 } 1175 Host::Kill(pid, SIGKILL); 1176 return Status(); 1177 } 1178 1179 lldb::ProcessSP Platform::DebugProcess(ProcessLaunchInfo &launch_info, 1180 Debugger &debugger, Target &target, 1181 Status &error) { 1182 Log *log = GetLog(LLDBLog::Platform); 1183 LLDB_LOG(log, "target = {0})", &target); 1184 1185 ProcessSP process_sp; 1186 // Make sure we stop at the entry point 1187 launch_info.GetFlags().Set(eLaunchFlagDebug); 1188 // We always launch the process we are going to debug in a separate process 1189 // group, since then we can handle ^C interrupts ourselves w/o having to 1190 // worry about the target getting them as well. 1191 launch_info.SetLaunchInSeparateProcessGroup(true); 1192 1193 // Allow any StructuredData process-bound plugins to adjust the launch info 1194 // if needed 1195 size_t i = 0; 1196 bool iteration_complete = false; 1197 // Note iteration can't simply go until a nullptr callback is returned, as it 1198 // is valid for a plugin to not supply a filter. 1199 auto get_filter_func = PluginManager::GetStructuredDataFilterCallbackAtIndex; 1200 for (auto filter_callback = get_filter_func(i, iteration_complete); 1201 !iteration_complete; 1202 filter_callback = get_filter_func(++i, iteration_complete)) { 1203 if (filter_callback) { 1204 // Give this ProcessLaunchInfo filter a chance to adjust the launch info. 1205 error = (*filter_callback)(launch_info, &target); 1206 if (!error.Success()) { 1207 LLDB_LOGF(log, 1208 "Platform::%s() StructuredDataPlugin launch " 1209 "filter failed.", 1210 __FUNCTION__); 1211 return process_sp; 1212 } 1213 } 1214 } 1215 1216 error = LaunchProcess(launch_info); 1217 if (error.Success()) { 1218 LLDB_LOGF(log, 1219 "Platform::%s LaunchProcess() call succeeded (pid=%" PRIu64 ")", 1220 __FUNCTION__, launch_info.GetProcessID()); 1221 if (launch_info.GetProcessID() != LLDB_INVALID_PROCESS_ID) { 1222 ProcessAttachInfo attach_info(launch_info); 1223 process_sp = Attach(attach_info, debugger, &target, error); 1224 if (process_sp) { 1225 LLDB_LOG(log, "Attach() succeeded, Process plugin: {0}", 1226 process_sp->GetPluginName()); 1227 launch_info.SetHijackListener(attach_info.GetHijackListener()); 1228 1229 // Since we attached to the process, it will think it needs to detach 1230 // if the process object just goes away without an explicit call to 1231 // Process::Kill() or Process::Detach(), so let it know to kill the 1232 // process if this happens. 1233 process_sp->SetShouldDetach(false); 1234 1235 // If we didn't have any file actions, the pseudo terminal might have 1236 // been used where the secondary side was given as the file to open for 1237 // stdin/out/err after we have already opened the primary so we can 1238 // read/write stdin/out/err. 1239 int pty_fd = launch_info.GetPTY().ReleasePrimaryFileDescriptor(); 1240 if (pty_fd != PseudoTerminal::invalid_fd) { 1241 process_sp->SetSTDIOFileDescriptor(pty_fd); 1242 } 1243 } else { 1244 LLDB_LOGF(log, "Platform::%s Attach() failed: %s", __FUNCTION__, 1245 error.AsCString()); 1246 } 1247 } else { 1248 LLDB_LOGF(log, 1249 "Platform::%s LaunchProcess() returned launch_info with " 1250 "invalid process id", 1251 __FUNCTION__); 1252 } 1253 } else { 1254 LLDB_LOGF(log, "Platform::%s LaunchProcess() failed: %s", __FUNCTION__, 1255 error.AsCString()); 1256 } 1257 1258 return process_sp; 1259 } 1260 1261 lldb::PlatformSP 1262 Platform::GetPlatformForArchitecture(const ArchSpec &arch, 1263 const ArchSpec &process_host_arch, 1264 ArchSpec *platform_arch_ptr) { 1265 lldb::PlatformSP platform_sp; 1266 Status error; 1267 if (arch.IsValid()) 1268 platform_sp = 1269 Platform::Create(arch, process_host_arch, platform_arch_ptr, error); 1270 return platform_sp; 1271 } 1272 1273 lldb::PlatformSP Platform::GetPlatformForArchitectures( 1274 std::vector<ArchSpec> archs, const ArchSpec &process_host_arch, 1275 lldb::PlatformSP selected_platform_sp, 1276 std::vector<lldb::PlatformSP> &candidates) { 1277 candidates.clear(); 1278 candidates.reserve(archs.size()); 1279 1280 if (archs.empty()) 1281 return nullptr; 1282 1283 PlatformSP host_platform_sp = Platform::GetHostPlatform(); 1284 1285 // Prefer the selected platform if it matches at least one architecture. 1286 if (selected_platform_sp) { 1287 for (const ArchSpec &arch : archs) { 1288 if (selected_platform_sp->IsCompatibleArchitecture( 1289 arch, process_host_arch, false, nullptr)) 1290 return selected_platform_sp; 1291 } 1292 } 1293 1294 // Prefer the host platform if it matches at least one architecture. 1295 if (host_platform_sp) { 1296 for (const ArchSpec &arch : archs) { 1297 if (host_platform_sp->IsCompatibleArchitecture(arch, process_host_arch, 1298 false, nullptr)) 1299 return host_platform_sp; 1300 } 1301 } 1302 1303 // Collect a list of candidate platforms for the architectures. 1304 for (const ArchSpec &arch : archs) { 1305 if (PlatformSP platform = 1306 Platform::GetPlatformForArchitecture(arch, process_host_arch)) 1307 candidates.push_back(platform); 1308 } 1309 1310 // The selected or host platform didn't match any of the architectures. If 1311 // the same platform supports all architectures then that's the obvious next 1312 // best thing. 1313 if (candidates.size() == archs.size()) { 1314 if (std::all_of(candidates.begin(), candidates.end(), 1315 [&](const PlatformSP &p) -> bool { 1316 return p->GetName() == candidates.front()->GetName(); 1317 })) { 1318 return candidates.front(); 1319 } 1320 } 1321 1322 // At this point we either have no platforms that match the given 1323 // architectures or multiple platforms with no good way to disambiguate 1324 // between them. 1325 return nullptr; 1326 } 1327 1328 std::vector<ArchSpec> 1329 Platform::CreateArchList(llvm::ArrayRef<llvm::Triple::ArchType> archs, 1330 llvm::Triple::OSType os) { 1331 std::vector<ArchSpec> list; 1332 for(auto arch : archs) { 1333 llvm::Triple triple; 1334 triple.setArch(arch); 1335 triple.setOS(os); 1336 list.push_back(ArchSpec(triple)); 1337 } 1338 return list; 1339 } 1340 1341 /// Lets a platform answer if it is compatible with a given 1342 /// architecture and the target triple contained within. 1343 bool Platform::IsCompatibleArchitecture(const ArchSpec &arch, 1344 const ArchSpec &process_host_arch, 1345 bool exact_arch_match, 1346 ArchSpec *compatible_arch_ptr) { 1347 // If the architecture is invalid, we must answer true... 1348 if (arch.IsValid()) { 1349 ArchSpec platform_arch; 1350 auto match = exact_arch_match ? &ArchSpec::IsExactMatch 1351 : &ArchSpec::IsCompatibleMatch; 1352 for (const ArchSpec &platform_arch : 1353 GetSupportedArchitectures(process_host_arch)) { 1354 if ((arch.*match)(platform_arch)) { 1355 if (compatible_arch_ptr) 1356 *compatible_arch_ptr = platform_arch; 1357 return true; 1358 } 1359 } 1360 } 1361 if (compatible_arch_ptr) 1362 compatible_arch_ptr->Clear(); 1363 return false; 1364 } 1365 1366 Status Platform::PutFile(const FileSpec &source, const FileSpec &destination, 1367 uint32_t uid, uint32_t gid) { 1368 Log *log = GetLog(LLDBLog::Platform); 1369 LLDB_LOGF(log, "[PutFile] Using block by block transfer....\n"); 1370 1371 auto source_open_options = 1372 File::eOpenOptionReadOnly | File::eOpenOptionCloseOnExec; 1373 namespace fs = llvm::sys::fs; 1374 if (fs::is_symlink_file(source.GetPath())) 1375 source_open_options |= File::eOpenOptionDontFollowSymlinks; 1376 1377 auto source_file = FileSystem::Instance().Open(source, source_open_options, 1378 lldb::eFilePermissionsUserRW); 1379 if (!source_file) 1380 return Status(source_file.takeError()); 1381 Status error; 1382 uint32_t permissions = source_file.get()->GetPermissions(error); 1383 if (permissions == 0) 1384 permissions = lldb::eFilePermissionsFileDefault; 1385 1386 lldb::user_id_t dest_file = OpenFile( 1387 destination, File::eOpenOptionCanCreate | File::eOpenOptionWriteOnly | 1388 File::eOpenOptionTruncate | File::eOpenOptionCloseOnExec, 1389 permissions, error); 1390 LLDB_LOGF(log, "dest_file = %" PRIu64 "\n", dest_file); 1391 1392 if (error.Fail()) 1393 return error; 1394 if (dest_file == UINT64_MAX) 1395 return Status("unable to open target file"); 1396 lldb::WritableDataBufferSP buffer_sp(new DataBufferHeap(1024 * 16, 0)); 1397 uint64_t offset = 0; 1398 for (;;) { 1399 size_t bytes_read = buffer_sp->GetByteSize(); 1400 error = source_file.get()->Read(buffer_sp->GetBytes(), bytes_read); 1401 if (error.Fail() || bytes_read == 0) 1402 break; 1403 1404 const uint64_t bytes_written = 1405 WriteFile(dest_file, offset, buffer_sp->GetBytes(), bytes_read, error); 1406 if (error.Fail()) 1407 break; 1408 1409 offset += bytes_written; 1410 if (bytes_written != bytes_read) { 1411 // We didn't write the correct number of bytes, so adjust the file 1412 // position in the source file we are reading from... 1413 source_file.get()->SeekFromStart(offset); 1414 } 1415 } 1416 CloseFile(dest_file, error); 1417 1418 if (uid == UINT32_MAX && gid == UINT32_MAX) 1419 return error; 1420 1421 // TODO: ChownFile? 1422 1423 return error; 1424 } 1425 1426 Status Platform::GetFile(const FileSpec &source, const FileSpec &destination) { 1427 Status error("unimplemented"); 1428 return error; 1429 } 1430 1431 Status 1432 Platform::CreateSymlink(const FileSpec &src, // The name of the link is in src 1433 const FileSpec &dst) // The symlink points to dst 1434 { 1435 if (IsHost()) 1436 return FileSystem::Instance().Symlink(src, dst); 1437 return Status("unimplemented"); 1438 } 1439 1440 bool Platform::GetFileExists(const lldb_private::FileSpec &file_spec) { 1441 if (IsHost()) 1442 return FileSystem::Instance().Exists(file_spec); 1443 return false; 1444 } 1445 1446 Status Platform::Unlink(const FileSpec &path) { 1447 if (IsHost()) 1448 return llvm::sys::fs::remove(path.GetPath()); 1449 return Status("unimplemented"); 1450 } 1451 1452 MmapArgList Platform::GetMmapArgumentList(const ArchSpec &arch, addr_t addr, 1453 addr_t length, unsigned prot, 1454 unsigned flags, addr_t fd, 1455 addr_t offset) { 1456 uint64_t flags_platform = 0; 1457 if (flags & eMmapFlagsPrivate) 1458 flags_platform |= MAP_PRIVATE; 1459 if (flags & eMmapFlagsAnon) 1460 flags_platform |= MAP_ANON; 1461 1462 MmapArgList args({addr, length, prot, flags_platform, fd, offset}); 1463 return args; 1464 } 1465 1466 lldb_private::Status Platform::RunShellCommand( 1467 llvm::StringRef command, 1468 const FileSpec & 1469 working_dir, // Pass empty FileSpec to use the current working directory 1470 int *status_ptr, // Pass nullptr if you don't want the process exit status 1471 int *signo_ptr, // Pass nullptr if you don't want the signal that caused the 1472 // process to exit 1473 std::string 1474 *command_output, // Pass nullptr if you don't want the command output 1475 const Timeout<std::micro> &timeout) { 1476 return RunShellCommand(llvm::StringRef(), command, working_dir, status_ptr, 1477 signo_ptr, command_output, timeout); 1478 } 1479 1480 lldb_private::Status Platform::RunShellCommand( 1481 llvm::StringRef shell, // Pass empty if you want to use the default 1482 // shell interpreter 1483 llvm::StringRef command, // Shouldn't be empty 1484 const FileSpec & 1485 working_dir, // Pass empty FileSpec to use the current working directory 1486 int *status_ptr, // Pass nullptr if you don't want the process exit status 1487 int *signo_ptr, // Pass nullptr if you don't want the signal that caused the 1488 // process to exit 1489 std::string 1490 *command_output, // Pass nullptr if you don't want the command output 1491 const Timeout<std::micro> &timeout) { 1492 if (IsHost()) 1493 return Host::RunShellCommand(shell, command, working_dir, status_ptr, 1494 signo_ptr, command_output, timeout); 1495 return Status("unable to run a remote command without a platform"); 1496 } 1497 1498 bool Platform::CalculateMD5(const FileSpec &file_spec, uint64_t &low, 1499 uint64_t &high) { 1500 if (!IsHost()) 1501 return false; 1502 auto Result = llvm::sys::fs::md5_contents(file_spec.GetPath()); 1503 if (!Result) 1504 return false; 1505 std::tie(high, low) = Result->words(); 1506 return true; 1507 } 1508 1509 void Platform::SetLocalCacheDirectory(const char *local) { 1510 m_local_cache_directory.assign(local); 1511 } 1512 1513 const char *Platform::GetLocalCacheDirectory() { 1514 return m_local_cache_directory.c_str(); 1515 } 1516 1517 static constexpr OptionDefinition g_rsync_option_table[] = { 1518 {LLDB_OPT_SET_ALL, false, "rsync", 'r', OptionParser::eNoArgument, nullptr, 1519 {}, 0, eArgTypeNone, "Enable rsync."}, 1520 {LLDB_OPT_SET_ALL, false, "rsync-opts", 'R', 1521 OptionParser::eRequiredArgument, nullptr, {}, 0, eArgTypeCommandName, 1522 "Platform-specific options required for rsync to work."}, 1523 {LLDB_OPT_SET_ALL, false, "rsync-prefix", 'P', 1524 OptionParser::eRequiredArgument, nullptr, {}, 0, eArgTypeCommandName, 1525 "Platform-specific rsync prefix put before the remote path."}, 1526 {LLDB_OPT_SET_ALL, false, "ignore-remote-hostname", 'i', 1527 OptionParser::eNoArgument, nullptr, {}, 0, eArgTypeNone, 1528 "Do not automatically fill in the remote hostname when composing the " 1529 "rsync command."}, 1530 }; 1531 1532 static constexpr OptionDefinition g_ssh_option_table[] = { 1533 {LLDB_OPT_SET_ALL, false, "ssh", 's', OptionParser::eNoArgument, nullptr, 1534 {}, 0, eArgTypeNone, "Enable SSH."}, 1535 {LLDB_OPT_SET_ALL, false, "ssh-opts", 'S', OptionParser::eRequiredArgument, 1536 nullptr, {}, 0, eArgTypeCommandName, 1537 "Platform-specific options required for SSH to work."}, 1538 }; 1539 1540 static constexpr OptionDefinition g_caching_option_table[] = { 1541 {LLDB_OPT_SET_ALL, false, "local-cache-dir", 'c', 1542 OptionParser::eRequiredArgument, nullptr, {}, 0, eArgTypePath, 1543 "Path in which to store local copies of files."}, 1544 }; 1545 1546 llvm::ArrayRef<OptionDefinition> OptionGroupPlatformRSync::GetDefinitions() { 1547 return llvm::makeArrayRef(g_rsync_option_table); 1548 } 1549 1550 void OptionGroupPlatformRSync::OptionParsingStarting( 1551 ExecutionContext *execution_context) { 1552 m_rsync = false; 1553 m_rsync_opts.clear(); 1554 m_rsync_prefix.clear(); 1555 m_ignores_remote_hostname = false; 1556 } 1557 1558 lldb_private::Status 1559 OptionGroupPlatformRSync::SetOptionValue(uint32_t option_idx, 1560 llvm::StringRef option_arg, 1561 ExecutionContext *execution_context) { 1562 Status error; 1563 char short_option = (char)GetDefinitions()[option_idx].short_option; 1564 switch (short_option) { 1565 case 'r': 1566 m_rsync = true; 1567 break; 1568 1569 case 'R': 1570 m_rsync_opts.assign(std::string(option_arg)); 1571 break; 1572 1573 case 'P': 1574 m_rsync_prefix.assign(std::string(option_arg)); 1575 break; 1576 1577 case 'i': 1578 m_ignores_remote_hostname = true; 1579 break; 1580 1581 default: 1582 error.SetErrorStringWithFormat("unrecognized option '%c'", short_option); 1583 break; 1584 } 1585 1586 return error; 1587 } 1588 1589 lldb::BreakpointSP 1590 Platform::SetThreadCreationBreakpoint(lldb_private::Target &target) { 1591 return lldb::BreakpointSP(); 1592 } 1593 1594 llvm::ArrayRef<OptionDefinition> OptionGroupPlatformSSH::GetDefinitions() { 1595 return llvm::makeArrayRef(g_ssh_option_table); 1596 } 1597 1598 void OptionGroupPlatformSSH::OptionParsingStarting( 1599 ExecutionContext *execution_context) { 1600 m_ssh = false; 1601 m_ssh_opts.clear(); 1602 } 1603 1604 lldb_private::Status 1605 OptionGroupPlatformSSH::SetOptionValue(uint32_t option_idx, 1606 llvm::StringRef option_arg, 1607 ExecutionContext *execution_context) { 1608 Status error; 1609 char short_option = (char)GetDefinitions()[option_idx].short_option; 1610 switch (short_option) { 1611 case 's': 1612 m_ssh = true; 1613 break; 1614 1615 case 'S': 1616 m_ssh_opts.assign(std::string(option_arg)); 1617 break; 1618 1619 default: 1620 error.SetErrorStringWithFormat("unrecognized option '%c'", short_option); 1621 break; 1622 } 1623 1624 return error; 1625 } 1626 1627 llvm::ArrayRef<OptionDefinition> OptionGroupPlatformCaching::GetDefinitions() { 1628 return llvm::makeArrayRef(g_caching_option_table); 1629 } 1630 1631 void OptionGroupPlatformCaching::OptionParsingStarting( 1632 ExecutionContext *execution_context) { 1633 m_cache_dir.clear(); 1634 } 1635 1636 lldb_private::Status OptionGroupPlatformCaching::SetOptionValue( 1637 uint32_t option_idx, llvm::StringRef option_arg, 1638 ExecutionContext *execution_context) { 1639 Status error; 1640 char short_option = (char)GetDefinitions()[option_idx].short_option; 1641 switch (short_option) { 1642 case 'c': 1643 m_cache_dir.assign(std::string(option_arg)); 1644 break; 1645 1646 default: 1647 error.SetErrorStringWithFormat("unrecognized option '%c'", short_option); 1648 break; 1649 } 1650 1651 return error; 1652 } 1653 1654 Environment Platform::GetEnvironment() { 1655 if (IsHost()) 1656 return Host::GetEnvironment(); 1657 return Environment(); 1658 } 1659 1660 const std::vector<ConstString> &Platform::GetTrapHandlerSymbolNames() { 1661 if (!m_calculated_trap_handlers) { 1662 std::lock_guard<std::mutex> guard(m_mutex); 1663 if (!m_calculated_trap_handlers) { 1664 CalculateTrapHandlerSymbolNames(); 1665 m_calculated_trap_handlers = true; 1666 } 1667 } 1668 return m_trap_handlers; 1669 } 1670 1671 Status 1672 Platform::GetCachedExecutable(ModuleSpec &module_spec, 1673 lldb::ModuleSP &module_sp, 1674 const FileSpecList *module_search_paths_ptr) { 1675 FileSpec platform_spec = module_spec.GetFileSpec(); 1676 Status error = GetRemoteSharedModule( 1677 module_spec, nullptr, module_sp, 1678 [&](const ModuleSpec &spec) { 1679 return ResolveRemoteExecutable(spec, module_sp, 1680 module_search_paths_ptr); 1681 }, 1682 nullptr); 1683 if (error.Success()) { 1684 module_spec.GetFileSpec() = module_sp->GetFileSpec(); 1685 module_spec.GetPlatformFileSpec() = platform_spec; 1686 } 1687 1688 return error; 1689 } 1690 1691 Status Platform::GetRemoteSharedModule(const ModuleSpec &module_spec, 1692 Process *process, 1693 lldb::ModuleSP &module_sp, 1694 const ModuleResolver &module_resolver, 1695 bool *did_create_ptr) { 1696 // Get module information from a target. 1697 ModuleSpec resolved_module_spec; 1698 ArchSpec process_host_arch; 1699 bool got_module_spec = false; 1700 if (process) { 1701 process_host_arch = process->GetSystemArchitecture(); 1702 // Try to get module information from the process 1703 if (process->GetModuleSpec(module_spec.GetFileSpec(), 1704 module_spec.GetArchitecture(), 1705 resolved_module_spec)) { 1706 if (!module_spec.GetUUID().IsValid() || 1707 module_spec.GetUUID() == resolved_module_spec.GetUUID()) { 1708 got_module_spec = true; 1709 } 1710 } 1711 } 1712 1713 if (!module_spec.GetArchitecture().IsValid()) { 1714 Status error; 1715 // No valid architecture was specified, ask the platform for the 1716 // architectures that we should be using (in the correct order) and see if 1717 // we can find a match that way 1718 ModuleSpec arch_module_spec(module_spec); 1719 for (const ArchSpec &arch : GetSupportedArchitectures(process_host_arch)) { 1720 arch_module_spec.GetArchitecture() = arch; 1721 error = ModuleList::GetSharedModule(arch_module_spec, module_sp, nullptr, 1722 nullptr, nullptr); 1723 // Did we find an executable using one of the 1724 if (error.Success() && module_sp) 1725 break; 1726 } 1727 if (module_sp) { 1728 resolved_module_spec = arch_module_spec; 1729 got_module_spec = true; 1730 } 1731 } 1732 1733 if (!got_module_spec) { 1734 // Get module information from a target. 1735 if (GetModuleSpec(module_spec.GetFileSpec(), module_spec.GetArchitecture(), 1736 resolved_module_spec)) { 1737 if (!module_spec.GetUUID().IsValid() || 1738 module_spec.GetUUID() == resolved_module_spec.GetUUID()) { 1739 got_module_spec = true; 1740 } 1741 } 1742 } 1743 1744 if (!got_module_spec) { 1745 // Fall back to the given module resolver, which may have its own 1746 // search logic. 1747 return module_resolver(module_spec); 1748 } 1749 1750 // If we are looking for a specific UUID, make sure resolved_module_spec has 1751 // the same one before we search. 1752 if (module_spec.GetUUID().IsValid()) { 1753 resolved_module_spec.GetUUID() = module_spec.GetUUID(); 1754 } 1755 1756 // Trying to find a module by UUID on local file system. 1757 const auto error = module_resolver(resolved_module_spec); 1758 if (error.Fail()) { 1759 if (GetCachedSharedModule(resolved_module_spec, module_sp, did_create_ptr)) 1760 return Status(); 1761 } 1762 1763 return error; 1764 } 1765 1766 bool Platform::GetCachedSharedModule(const ModuleSpec &module_spec, 1767 lldb::ModuleSP &module_sp, 1768 bool *did_create_ptr) { 1769 if (IsHost() || !GetGlobalPlatformProperties().GetUseModuleCache() || 1770 !GetGlobalPlatformProperties().GetModuleCacheDirectory()) 1771 return false; 1772 1773 Log *log = GetLog(LLDBLog::Platform); 1774 1775 // Check local cache for a module. 1776 auto error = m_module_cache->GetAndPut( 1777 GetModuleCacheRoot(), GetCacheHostname(), module_spec, 1778 [this](const ModuleSpec &module_spec, 1779 const FileSpec &tmp_download_file_spec) { 1780 return DownloadModuleSlice( 1781 module_spec.GetFileSpec(), module_spec.GetObjectOffset(), 1782 module_spec.GetObjectSize(), tmp_download_file_spec); 1783 1784 }, 1785 [this](const ModuleSP &module_sp, 1786 const FileSpec &tmp_download_file_spec) { 1787 return DownloadSymbolFile(module_sp, tmp_download_file_spec); 1788 }, 1789 module_sp, did_create_ptr); 1790 if (error.Success()) 1791 return true; 1792 1793 LLDB_LOGF(log, "Platform::%s - module %s not found in local cache: %s", 1794 __FUNCTION__, module_spec.GetUUID().GetAsString().c_str(), 1795 error.AsCString()); 1796 return false; 1797 } 1798 1799 Status Platform::DownloadModuleSlice(const FileSpec &src_file_spec, 1800 const uint64_t src_offset, 1801 const uint64_t src_size, 1802 const FileSpec &dst_file_spec) { 1803 Status error; 1804 1805 std::error_code EC; 1806 llvm::raw_fd_ostream dst(dst_file_spec.GetPath(), EC, llvm::sys::fs::OF_None); 1807 if (EC) { 1808 error.SetErrorStringWithFormat("unable to open destination file: %s", 1809 dst_file_spec.GetPath().c_str()); 1810 return error; 1811 } 1812 1813 auto src_fd = OpenFile(src_file_spec, File::eOpenOptionReadOnly, 1814 lldb::eFilePermissionsFileDefault, error); 1815 1816 if (error.Fail()) { 1817 error.SetErrorStringWithFormat("unable to open source file: %s", 1818 error.AsCString()); 1819 return error; 1820 } 1821 1822 std::vector<char> buffer(1024); 1823 auto offset = src_offset; 1824 uint64_t total_bytes_read = 0; 1825 while (total_bytes_read < src_size) { 1826 const auto to_read = std::min(static_cast<uint64_t>(buffer.size()), 1827 src_size - total_bytes_read); 1828 const uint64_t n_read = 1829 ReadFile(src_fd, offset, &buffer[0], to_read, error); 1830 if (error.Fail()) 1831 break; 1832 if (n_read == 0) { 1833 error.SetErrorString("read 0 bytes"); 1834 break; 1835 } 1836 offset += n_read; 1837 total_bytes_read += n_read; 1838 dst.write(&buffer[0], n_read); 1839 } 1840 1841 Status close_error; 1842 CloseFile(src_fd, close_error); // Ignoring close error. 1843 1844 return error; 1845 } 1846 1847 Status Platform::DownloadSymbolFile(const lldb::ModuleSP &module_sp, 1848 const FileSpec &dst_file_spec) { 1849 return Status( 1850 "Symbol file downloading not supported by the default platform."); 1851 } 1852 1853 FileSpec Platform::GetModuleCacheRoot() { 1854 auto dir_spec = GetGlobalPlatformProperties().GetModuleCacheDirectory(); 1855 dir_spec.AppendPathComponent(GetPluginName()); 1856 return dir_spec; 1857 } 1858 1859 const char *Platform::GetCacheHostname() { return GetHostname(); } 1860 1861 const UnixSignalsSP &Platform::GetRemoteUnixSignals() { 1862 static const auto s_default_unix_signals_sp = std::make_shared<UnixSignals>(); 1863 return s_default_unix_signals_sp; 1864 } 1865 1866 UnixSignalsSP Platform::GetUnixSignals() { 1867 if (IsHost()) 1868 return UnixSignals::CreateForHost(); 1869 return GetRemoteUnixSignals(); 1870 } 1871 1872 uint32_t Platform::LoadImage(lldb_private::Process *process, 1873 const lldb_private::FileSpec &local_file, 1874 const lldb_private::FileSpec &remote_file, 1875 lldb_private::Status &error) { 1876 if (local_file && remote_file) { 1877 // Both local and remote file was specified. Install the local file to the 1878 // given location. 1879 if (IsRemote() || local_file != remote_file) { 1880 error = Install(local_file, remote_file); 1881 if (error.Fail()) 1882 return LLDB_INVALID_IMAGE_TOKEN; 1883 } 1884 return DoLoadImage(process, remote_file, nullptr, error); 1885 } 1886 1887 if (local_file) { 1888 // Only local file was specified. Install it to the current working 1889 // directory. 1890 FileSpec target_file = GetWorkingDirectory(); 1891 target_file.AppendPathComponent(local_file.GetFilename().AsCString()); 1892 if (IsRemote() || local_file != target_file) { 1893 error = Install(local_file, target_file); 1894 if (error.Fail()) 1895 return LLDB_INVALID_IMAGE_TOKEN; 1896 } 1897 return DoLoadImage(process, target_file, nullptr, error); 1898 } 1899 1900 if (remote_file) { 1901 // Only remote file was specified so we don't have to do any copying 1902 return DoLoadImage(process, remote_file, nullptr, error); 1903 } 1904 1905 error.SetErrorString("Neither local nor remote file was specified"); 1906 return LLDB_INVALID_IMAGE_TOKEN; 1907 } 1908 1909 uint32_t Platform::DoLoadImage(lldb_private::Process *process, 1910 const lldb_private::FileSpec &remote_file, 1911 const std::vector<std::string> *paths, 1912 lldb_private::Status &error, 1913 lldb_private::FileSpec *loaded_image) { 1914 error.SetErrorString("LoadImage is not supported on the current platform"); 1915 return LLDB_INVALID_IMAGE_TOKEN; 1916 } 1917 1918 uint32_t Platform::LoadImageUsingPaths(lldb_private::Process *process, 1919 const lldb_private::FileSpec &remote_filename, 1920 const std::vector<std::string> &paths, 1921 lldb_private::Status &error, 1922 lldb_private::FileSpec *loaded_path) 1923 { 1924 FileSpec file_to_use; 1925 if (remote_filename.IsAbsolute()) 1926 file_to_use = FileSpec(remote_filename.GetFilename().GetStringRef(), 1927 1928 remote_filename.GetPathStyle()); 1929 else 1930 file_to_use = remote_filename; 1931 1932 return DoLoadImage(process, file_to_use, &paths, error, loaded_path); 1933 } 1934 1935 Status Platform::UnloadImage(lldb_private::Process *process, 1936 uint32_t image_token) { 1937 return Status("UnloadImage is not supported on the current platform"); 1938 } 1939 1940 lldb::ProcessSP Platform::ConnectProcess(llvm::StringRef connect_url, 1941 llvm::StringRef plugin_name, 1942 Debugger &debugger, Target *target, 1943 Status &error) { 1944 return DoConnectProcess(connect_url, plugin_name, debugger, nullptr, target, 1945 error); 1946 } 1947 1948 lldb::ProcessSP Platform::ConnectProcessSynchronous( 1949 llvm::StringRef connect_url, llvm::StringRef plugin_name, 1950 Debugger &debugger, Stream &stream, Target *target, Status &error) { 1951 return DoConnectProcess(connect_url, plugin_name, debugger, &stream, target, 1952 error); 1953 } 1954 1955 lldb::ProcessSP Platform::DoConnectProcess(llvm::StringRef connect_url, 1956 llvm::StringRef plugin_name, 1957 Debugger &debugger, Stream *stream, 1958 Target *target, Status &error) { 1959 error.Clear(); 1960 1961 if (!target) { 1962 ArchSpec arch; 1963 if (target && target->GetArchitecture().IsValid()) 1964 arch = target->GetArchitecture(); 1965 else 1966 arch = Target::GetDefaultArchitecture(); 1967 1968 const char *triple = ""; 1969 if (arch.IsValid()) 1970 triple = arch.GetTriple().getTriple().c_str(); 1971 1972 TargetSP new_target_sp; 1973 error = debugger.GetTargetList().CreateTarget( 1974 debugger, "", triple, eLoadDependentsNo, nullptr, new_target_sp); 1975 target = new_target_sp.get(); 1976 } 1977 1978 if (!target || error.Fail()) 1979 return nullptr; 1980 1981 lldb::ProcessSP process_sp = 1982 target->CreateProcess(debugger.GetListener(), plugin_name, nullptr, true); 1983 1984 if (!process_sp) 1985 return nullptr; 1986 1987 // If this private method is called with a stream we are synchronous. 1988 const bool synchronous = stream != nullptr; 1989 1990 ListenerSP listener_sp( 1991 Listener::MakeListener("lldb.Process.ConnectProcess.hijack")); 1992 if (synchronous) 1993 process_sp->HijackProcessEvents(listener_sp); 1994 1995 error = process_sp->ConnectRemote(connect_url); 1996 if (error.Fail()) { 1997 if (synchronous) 1998 process_sp->RestoreProcessEvents(); 1999 return nullptr; 2000 } 2001 2002 if (synchronous) { 2003 EventSP event_sp; 2004 process_sp->WaitForProcessToStop(llvm::None, &event_sp, true, listener_sp, 2005 nullptr); 2006 process_sp->RestoreProcessEvents(); 2007 bool pop_process_io_handler = false; 2008 Process::HandleProcessStateChangedEvent(event_sp, stream, 2009 pop_process_io_handler); 2010 } 2011 2012 return process_sp; 2013 } 2014 2015 size_t Platform::ConnectToWaitingProcesses(lldb_private::Debugger &debugger, 2016 lldb_private::Status &error) { 2017 error.Clear(); 2018 return 0; 2019 } 2020 2021 size_t Platform::GetSoftwareBreakpointTrapOpcode(Target &target, 2022 BreakpointSite *bp_site) { 2023 ArchSpec arch = target.GetArchitecture(); 2024 assert(arch.IsValid()); 2025 const uint8_t *trap_opcode = nullptr; 2026 size_t trap_opcode_size = 0; 2027 2028 switch (arch.GetMachine()) { 2029 case llvm::Triple::aarch64_32: 2030 case llvm::Triple::aarch64: { 2031 static const uint8_t g_aarch64_opcode[] = {0x00, 0x00, 0x20, 0xd4}; 2032 trap_opcode = g_aarch64_opcode; 2033 trap_opcode_size = sizeof(g_aarch64_opcode); 2034 } break; 2035 2036 case llvm::Triple::arc: { 2037 static const uint8_t g_hex_opcode[] = { 0xff, 0x7f }; 2038 trap_opcode = g_hex_opcode; 2039 trap_opcode_size = sizeof(g_hex_opcode); 2040 } break; 2041 2042 // TODO: support big-endian arm and thumb trap codes. 2043 case llvm::Triple::arm: { 2044 // The ARM reference recommends the use of 0xe7fddefe and 0xdefe but the 2045 // linux kernel does otherwise. 2046 static const uint8_t g_arm_breakpoint_opcode[] = {0xf0, 0x01, 0xf0, 0xe7}; 2047 static const uint8_t g_thumb_breakpoint_opcode[] = {0x01, 0xde}; 2048 2049 lldb::BreakpointLocationSP bp_loc_sp(bp_site->GetOwnerAtIndex(0)); 2050 AddressClass addr_class = AddressClass::eUnknown; 2051 2052 if (bp_loc_sp) { 2053 addr_class = bp_loc_sp->GetAddress().GetAddressClass(); 2054 if (addr_class == AddressClass::eUnknown && 2055 (bp_loc_sp->GetAddress().GetFileAddress() & 1)) 2056 addr_class = AddressClass::eCodeAlternateISA; 2057 } 2058 2059 if (addr_class == AddressClass::eCodeAlternateISA) { 2060 trap_opcode = g_thumb_breakpoint_opcode; 2061 trap_opcode_size = sizeof(g_thumb_breakpoint_opcode); 2062 } else { 2063 trap_opcode = g_arm_breakpoint_opcode; 2064 trap_opcode_size = sizeof(g_arm_breakpoint_opcode); 2065 } 2066 } break; 2067 2068 case llvm::Triple::avr: { 2069 static const uint8_t g_hex_opcode[] = {0x98, 0x95}; 2070 trap_opcode = g_hex_opcode; 2071 trap_opcode_size = sizeof(g_hex_opcode); 2072 } break; 2073 2074 case llvm::Triple::mips: 2075 case llvm::Triple::mips64: { 2076 static const uint8_t g_hex_opcode[] = {0x00, 0x00, 0x00, 0x0d}; 2077 trap_opcode = g_hex_opcode; 2078 trap_opcode_size = sizeof(g_hex_opcode); 2079 } break; 2080 2081 case llvm::Triple::mipsel: 2082 case llvm::Triple::mips64el: { 2083 static const uint8_t g_hex_opcode[] = {0x0d, 0x00, 0x00, 0x00}; 2084 trap_opcode = g_hex_opcode; 2085 trap_opcode_size = sizeof(g_hex_opcode); 2086 } break; 2087 2088 case llvm::Triple::systemz: { 2089 static const uint8_t g_hex_opcode[] = {0x00, 0x01}; 2090 trap_opcode = g_hex_opcode; 2091 trap_opcode_size = sizeof(g_hex_opcode); 2092 } break; 2093 2094 case llvm::Triple::hexagon: { 2095 static const uint8_t g_hex_opcode[] = {0x0c, 0xdb, 0x00, 0x54}; 2096 trap_opcode = g_hex_opcode; 2097 trap_opcode_size = sizeof(g_hex_opcode); 2098 } break; 2099 2100 case llvm::Triple::ppc: 2101 case llvm::Triple::ppc64: { 2102 static const uint8_t g_ppc_opcode[] = {0x7f, 0xe0, 0x00, 0x08}; 2103 trap_opcode = g_ppc_opcode; 2104 trap_opcode_size = sizeof(g_ppc_opcode); 2105 } break; 2106 2107 case llvm::Triple::ppc64le: { 2108 static const uint8_t g_ppc64le_opcode[] = {0x08, 0x00, 0xe0, 0x7f}; // trap 2109 trap_opcode = g_ppc64le_opcode; 2110 trap_opcode_size = sizeof(g_ppc64le_opcode); 2111 } break; 2112 2113 case llvm::Triple::x86: 2114 case llvm::Triple::x86_64: { 2115 static const uint8_t g_i386_opcode[] = {0xCC}; 2116 trap_opcode = g_i386_opcode; 2117 trap_opcode_size = sizeof(g_i386_opcode); 2118 } break; 2119 2120 default: 2121 return 0; 2122 } 2123 2124 assert(bp_site); 2125 if (bp_site->SetTrapOpcode(trap_opcode, trap_opcode_size)) 2126 return trap_opcode_size; 2127 2128 return 0; 2129 } 2130 2131 CompilerType Platform::GetSiginfoType(const llvm::Triple& triple) { 2132 return CompilerType(); 2133 } 2134