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