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 #include "lldb/Target/Platform.h" 11 12 // C Includes 13 // C++ Includes 14 // Other libraries and framework includes 15 // Project includes 16 #include "lldb/Breakpoint/BreakpointIDList.h" 17 #include "lldb/Core/Error.h" 18 #include "lldb/Core/Log.h" 19 #include "lldb/Core/ModuleSpec.h" 20 #include "lldb/Core/PluginManager.h" 21 #include "lldb/Host/FileSpec.h" 22 #include "lldb/Host/FileSystem.h" 23 #include "lldb/Host/Host.h" 24 #include "lldb/Host/HostInfo.h" 25 #include "lldb/Target/Process.h" 26 #include "lldb/Target/Target.h" 27 #include "lldb/Utility/Utils.h" 28 29 using namespace lldb; 30 using namespace lldb_private; 31 32 // Use a singleton function for g_local_platform_sp to avoid init 33 // constructors since LLDB is often part of a shared library 34 static PlatformSP& 35 GetDefaultPlatformSP () 36 { 37 static PlatformSP g_default_platform_sp; 38 return g_default_platform_sp; 39 } 40 41 static Mutex & 42 GetConnectedPlatformListMutex () 43 { 44 static Mutex g_remote_connected_platforms_mutex (Mutex::eMutexTypeRecursive); 45 return g_remote_connected_platforms_mutex; 46 } 47 static std::vector<PlatformSP> & 48 GetConnectedPlatformList () 49 { 50 static std::vector<PlatformSP> g_remote_connected_platforms; 51 return g_remote_connected_platforms; 52 } 53 54 55 const char * 56 Platform::GetHostPlatformName () 57 { 58 return "host"; 59 } 60 61 //------------------------------------------------------------------ 62 /// Get the native host platform plug-in. 63 /// 64 /// There should only be one of these for each host that LLDB runs 65 /// upon that should be statically compiled in and registered using 66 /// preprocessor macros or other similar build mechanisms. 67 /// 68 /// This platform will be used as the default platform when launching 69 /// or attaching to processes unless another platform is specified. 70 //------------------------------------------------------------------ 71 PlatformSP 72 Platform::GetDefaultPlatform () 73 { 74 return GetDefaultPlatformSP (); 75 } 76 77 void 78 Platform::SetDefaultPlatform (const lldb::PlatformSP &platform_sp) 79 { 80 // The native platform should use its static void Platform::Initialize() 81 // function to register itself as the native platform. 82 GetDefaultPlatformSP () = platform_sp; 83 } 84 85 Error 86 Platform::GetFileWithUUID (const FileSpec &platform_file, 87 const UUID *uuid_ptr, 88 FileSpec &local_file) 89 { 90 // Default to the local case 91 local_file = platform_file; 92 return Error(); 93 } 94 95 FileSpecList 96 Platform::LocateExecutableScriptingResources (Target *target, Module &module, Stream* feedback_stream) 97 { 98 return FileSpecList(); 99 } 100 101 Platform* 102 Platform::FindPlugin (Process *process, const ConstString &plugin_name) 103 { 104 PlatformCreateInstance create_callback = NULL; 105 if (plugin_name) 106 { 107 create_callback = PluginManager::GetPlatformCreateCallbackForPluginName (plugin_name); 108 if (create_callback) 109 { 110 ArchSpec arch; 111 if (process) 112 { 113 arch = process->GetTarget().GetArchitecture(); 114 } 115 std::unique_ptr<Platform> instance_ap(create_callback(process, &arch)); 116 if (instance_ap.get()) 117 return instance_ap.release(); 118 } 119 } 120 else 121 { 122 for (uint32_t idx = 0; (create_callback = PluginManager::GetPlatformCreateCallbackAtIndex(idx)) != NULL; ++idx) 123 { 124 std::unique_ptr<Platform> instance_ap(create_callback(process, nullptr)); 125 if (instance_ap.get()) 126 return instance_ap.release(); 127 } 128 } 129 return NULL; 130 } 131 132 Error 133 Platform::GetSharedModule (const ModuleSpec &module_spec, 134 ModuleSP &module_sp, 135 const FileSpecList *module_search_paths_ptr, 136 ModuleSP *old_module_sp_ptr, 137 bool *did_create_ptr) 138 { 139 // Don't do any path remapping for the default implementation 140 // of the platform GetSharedModule function, just call through 141 // to our static ModuleList function. Platform subclasses that 142 // implement remote debugging, might have a developer kits 143 // installed that have cached versions of the files for the 144 // remote target, or might implement a download and cache 145 // locally implementation. 146 const bool always_create = false; 147 return ModuleList::GetSharedModule (module_spec, 148 module_sp, 149 module_search_paths_ptr, 150 old_module_sp_ptr, 151 did_create_ptr, 152 always_create); 153 } 154 155 PlatformSP 156 Platform::Create (const char *platform_name, Error &error) 157 { 158 PlatformCreateInstance create_callback = NULL; 159 lldb::PlatformSP platform_sp; 160 if (platform_name && platform_name[0]) 161 { 162 ConstString const_platform_name (platform_name); 163 create_callback = PluginManager::GetPlatformCreateCallbackForPluginName (const_platform_name); 164 if (create_callback) 165 platform_sp.reset(create_callback(true, NULL)); 166 else 167 error.SetErrorStringWithFormat ("unable to find a plug-in for the platform named \"%s\"", platform_name); 168 } 169 else 170 error.SetErrorString ("invalid platform name"); 171 return platform_sp; 172 } 173 174 175 PlatformSP 176 Platform::Create (const ArchSpec &arch, ArchSpec *platform_arch_ptr, Error &error) 177 { 178 lldb::PlatformSP platform_sp; 179 if (arch.IsValid()) 180 { 181 uint32_t idx; 182 PlatformCreateInstance create_callback; 183 // First try exact arch matches across all platform plug-ins 184 bool exact = true; 185 for (idx = 0; (create_callback = PluginManager::GetPlatformCreateCallbackAtIndex (idx)); ++idx) 186 { 187 if (create_callback) 188 { 189 platform_sp.reset(create_callback(false, &arch)); 190 if (platform_sp && platform_sp->IsCompatibleArchitecture(arch, exact, platform_arch_ptr)) 191 return platform_sp; 192 } 193 } 194 // Next try compatible arch matches across all platform plug-ins 195 exact = false; 196 for (idx = 0; (create_callback = PluginManager::GetPlatformCreateCallbackAtIndex (idx)); ++idx) 197 { 198 if (create_callback) 199 { 200 platform_sp.reset(create_callback(false, &arch)); 201 if (platform_sp && platform_sp->IsCompatibleArchitecture(arch, exact, platform_arch_ptr)) 202 return platform_sp; 203 } 204 } 205 } 206 else 207 error.SetErrorString ("invalid platform name"); 208 if (platform_arch_ptr) 209 platform_arch_ptr->Clear(); 210 platform_sp.reset(); 211 return platform_sp; 212 } 213 214 uint32_t 215 Platform::GetNumConnectedRemotePlatforms () 216 { 217 Mutex::Locker locker (GetConnectedPlatformListMutex ()); 218 return GetConnectedPlatformList().size(); 219 } 220 221 PlatformSP 222 Platform::GetConnectedRemotePlatformAtIndex (uint32_t idx) 223 { 224 PlatformSP platform_sp; 225 { 226 Mutex::Locker locker (GetConnectedPlatformListMutex ()); 227 if (idx < GetConnectedPlatformList().size()) 228 platform_sp = GetConnectedPlatformList ()[idx]; 229 } 230 return platform_sp; 231 } 232 233 //------------------------------------------------------------------ 234 /// Default Constructor 235 //------------------------------------------------------------------ 236 Platform::Platform (bool is_host) : 237 m_is_host (is_host), 238 m_os_version_set_while_connected (false), 239 m_system_arch_set_while_connected (false), 240 m_sdk_sysroot (), 241 m_sdk_build (), 242 m_working_dir (), 243 m_remote_url (), 244 m_name (), 245 m_major_os_version (UINT32_MAX), 246 m_minor_os_version (UINT32_MAX), 247 m_update_os_version (UINT32_MAX), 248 m_system_arch(), 249 m_uid_map_mutex (Mutex::eMutexTypeNormal), 250 m_gid_map_mutex (Mutex::eMutexTypeNormal), 251 m_uid_map(), 252 m_gid_map(), 253 m_max_uid_name_len (0), 254 m_max_gid_name_len (0), 255 m_supports_rsync (false), 256 m_rsync_opts (), 257 m_rsync_prefix (), 258 m_supports_ssh (false), 259 m_ssh_opts (), 260 m_ignores_remote_hostname (false), 261 m_trap_handlers(), 262 m_calculated_trap_handlers (false), 263 m_trap_handler_mutex() 264 { 265 Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_OBJECT)); 266 if (log) 267 log->Printf ("%p Platform::Platform()", static_cast<void*>(this)); 268 } 269 270 //------------------------------------------------------------------ 271 /// Destructor. 272 /// 273 /// The destructor is virtual since this class is designed to be 274 /// inherited from by the plug-in instance. 275 //------------------------------------------------------------------ 276 Platform::~Platform() 277 { 278 Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_OBJECT)); 279 if (log) 280 log->Printf ("%p Platform::~Platform()", static_cast<void*>(this)); 281 } 282 283 void 284 Platform::GetStatus (Stream &strm) 285 { 286 uint32_t major = UINT32_MAX; 287 uint32_t minor = UINT32_MAX; 288 uint32_t update = UINT32_MAX; 289 std::string s; 290 strm.Printf (" Platform: %s\n", GetPluginName().GetCString()); 291 292 ArchSpec arch (GetSystemArchitecture()); 293 if (arch.IsValid()) 294 { 295 if (!arch.GetTriple().str().empty()) 296 strm.Printf(" Triple: %s\n", arch.GetTriple().str().c_str()); 297 } 298 299 if (GetOSVersion(major, minor, update)) 300 { 301 strm.Printf("OS Version: %u", major); 302 if (minor != UINT32_MAX) 303 strm.Printf(".%u", minor); 304 if (update != UINT32_MAX) 305 strm.Printf(".%u", update); 306 307 if (GetOSBuildString (s)) 308 strm.Printf(" (%s)", s.c_str()); 309 310 strm.EOL(); 311 } 312 313 if (GetOSKernelDescription (s)) 314 strm.Printf(" Kernel: %s\n", s.c_str()); 315 316 if (IsHost()) 317 { 318 strm.Printf(" Hostname: %s\n", GetHostname()); 319 } 320 else 321 { 322 const bool is_connected = IsConnected(); 323 if (is_connected) 324 strm.Printf(" Hostname: %s\n", GetHostname()); 325 strm.Printf(" Connected: %s\n", is_connected ? "yes" : "no"); 326 } 327 328 if (GetWorkingDirectory()) 329 { 330 strm.Printf("WorkingDir: %s\n", GetWorkingDirectory().GetCString()); 331 } 332 if (!IsConnected()) 333 return; 334 335 std::string specific_info(GetPlatformSpecificConnectionInformation()); 336 337 if (specific_info.empty() == false) 338 strm.Printf("Platform-specific connection: %s\n", specific_info.c_str()); 339 } 340 341 342 bool 343 Platform::GetOSVersion (uint32_t &major, 344 uint32_t &minor, 345 uint32_t &update) 346 { 347 bool success = m_major_os_version != UINT32_MAX; 348 if (IsHost()) 349 { 350 if (!success) 351 { 352 // We have a local host platform 353 success = HostInfo::GetOSVersion(m_major_os_version, m_minor_os_version, m_update_os_version); 354 m_os_version_set_while_connected = success; 355 } 356 } 357 else 358 { 359 // We have a remote platform. We can only fetch the remote 360 // OS version if we are connected, and we don't want to do it 361 // more than once. 362 363 const bool is_connected = IsConnected(); 364 365 bool fetch = false; 366 if (success) 367 { 368 // We have valid OS version info, check to make sure it wasn't 369 // manually set prior to connecting. If it was manually set prior 370 // to connecting, then lets fetch the actual OS version info 371 // if we are now connected. 372 if (is_connected && !m_os_version_set_while_connected) 373 fetch = true; 374 } 375 else 376 { 377 // We don't have valid OS version info, fetch it if we are connected 378 fetch = is_connected; 379 } 380 381 if (fetch) 382 { 383 success = GetRemoteOSVersion (); 384 m_os_version_set_while_connected = success; 385 } 386 } 387 388 if (success) 389 { 390 major = m_major_os_version; 391 minor = m_minor_os_version; 392 update = m_update_os_version; 393 } 394 return success; 395 } 396 397 bool 398 Platform::GetOSBuildString (std::string &s) 399 { 400 s.clear(); 401 402 if (IsHost()) 403 #if !defined(__linux__) 404 return HostInfo::GetOSBuildString(s); 405 #else 406 return false; 407 #endif 408 else 409 return GetRemoteOSBuildString (s); 410 } 411 412 bool 413 Platform::GetOSKernelDescription (std::string &s) 414 { 415 if (IsHost()) 416 #if !defined(__linux__) 417 return HostInfo::GetOSKernelDescription(s); 418 #else 419 return false; 420 #endif 421 else 422 return GetRemoteOSKernelDescription (s); 423 } 424 425 ConstString 426 Platform::GetWorkingDirectory () 427 { 428 if (IsHost()) 429 { 430 char cwd[PATH_MAX]; 431 if (getcwd(cwd, sizeof(cwd))) 432 return ConstString(cwd); 433 else 434 return ConstString(); 435 } 436 else 437 { 438 if (!m_working_dir) 439 m_working_dir = GetRemoteWorkingDirectory(); 440 return m_working_dir; 441 } 442 } 443 444 445 struct RecurseCopyBaton 446 { 447 const FileSpec& dst; 448 Platform *platform_ptr; 449 Error error; 450 }; 451 452 453 static FileSpec::EnumerateDirectoryResult 454 RecurseCopy_Callback (void *baton, 455 FileSpec::FileType file_type, 456 const FileSpec &src) 457 { 458 RecurseCopyBaton* rc_baton = (RecurseCopyBaton*)baton; 459 switch (file_type) 460 { 461 case FileSpec::eFileTypePipe: 462 case FileSpec::eFileTypeSocket: 463 // we have no way to copy pipes and sockets - ignore them and continue 464 return FileSpec::eEnumerateDirectoryResultNext; 465 break; 466 467 case FileSpec::eFileTypeDirectory: 468 { 469 // make the new directory and get in there 470 FileSpec dst_dir = rc_baton->dst; 471 if (!dst_dir.GetFilename()) 472 dst_dir.GetFilename() = src.GetLastPathComponent(); 473 std::string dst_dir_path (dst_dir.GetPath()); 474 Error error = rc_baton->platform_ptr->MakeDirectory(dst_dir_path.c_str(), lldb::eFilePermissionsDirectoryDefault); 475 if (error.Fail()) 476 { 477 rc_baton->error.SetErrorStringWithFormat("unable to setup directory %s on remote end", dst_dir_path.c_str()); 478 return FileSpec::eEnumerateDirectoryResultQuit; // got an error, bail out 479 } 480 481 // now recurse 482 std::string src_dir_path (src.GetPath()); 483 484 // Make a filespec that only fills in the directory of a FileSpec so 485 // when we enumerate we can quickly fill in the filename for dst copies 486 FileSpec recurse_dst; 487 recurse_dst.GetDirectory().SetCString(dst_dir.GetPath().c_str()); 488 RecurseCopyBaton rc_baton2 = { recurse_dst, rc_baton->platform_ptr, Error() }; 489 FileSpec::EnumerateDirectory(src_dir_path.c_str(), true, true, true, RecurseCopy_Callback, &rc_baton2); 490 if (rc_baton2.error.Fail()) 491 { 492 rc_baton->error.SetErrorString(rc_baton2.error.AsCString()); 493 return FileSpec::eEnumerateDirectoryResultQuit; // got an error, bail out 494 } 495 return FileSpec::eEnumerateDirectoryResultNext; 496 } 497 break; 498 499 case FileSpec::eFileTypeSymbolicLink: 500 { 501 // copy the file and keep going 502 FileSpec dst_file = rc_baton->dst; 503 if (!dst_file.GetFilename()) 504 dst_file.GetFilename() = src.GetFilename(); 505 506 char buf[PATH_MAX]; 507 508 rc_baton->error = FileSystem::Readlink(src.GetPath().c_str(), buf, sizeof(buf)); 509 510 if (rc_baton->error.Fail()) 511 return FileSpec::eEnumerateDirectoryResultQuit; // got an error, bail out 512 513 rc_baton->error = rc_baton->platform_ptr->CreateSymlink(dst_file.GetPath().c_str(), buf); 514 515 if (rc_baton->error.Fail()) 516 return FileSpec::eEnumerateDirectoryResultQuit; // got an error, bail out 517 518 return FileSpec::eEnumerateDirectoryResultNext; 519 } 520 break; 521 case FileSpec::eFileTypeRegular: 522 { 523 // copy the file and keep going 524 FileSpec dst_file = rc_baton->dst; 525 if (!dst_file.GetFilename()) 526 dst_file.GetFilename() = src.GetFilename(); 527 Error err = rc_baton->platform_ptr->PutFile(src, dst_file); 528 if (err.Fail()) 529 { 530 rc_baton->error.SetErrorString(err.AsCString()); 531 return FileSpec::eEnumerateDirectoryResultQuit; // got an error, bail out 532 } 533 return FileSpec::eEnumerateDirectoryResultNext; 534 } 535 break; 536 537 case FileSpec::eFileTypeInvalid: 538 case FileSpec::eFileTypeOther: 539 case FileSpec::eFileTypeUnknown: 540 default: 541 rc_baton->error.SetErrorStringWithFormat("invalid file detected during copy: %s", src.GetPath().c_str()); 542 return FileSpec::eEnumerateDirectoryResultQuit; // got an error, bail out 543 break; 544 } 545 } 546 547 Error 548 Platform::Install (const FileSpec& src, const FileSpec& dst) 549 { 550 Error error; 551 552 Log *log = GetLogIfAnyCategoriesSet(LIBLLDB_LOG_PLATFORM); 553 if (log) 554 log->Printf ("Platform::Install (src='%s', dst='%s')", src.GetPath().c_str(), dst.GetPath().c_str()); 555 FileSpec fixed_dst(dst); 556 557 if (!fixed_dst.GetFilename()) 558 fixed_dst.GetFilename() = src.GetFilename(); 559 560 ConstString working_dir = GetWorkingDirectory(); 561 562 if (dst) 563 { 564 if (dst.GetDirectory()) 565 { 566 const char first_dst_dir_char = dst.GetDirectory().GetCString()[0]; 567 if (first_dst_dir_char == '/' || first_dst_dir_char == '\\') 568 { 569 fixed_dst.GetDirectory() = dst.GetDirectory(); 570 } 571 // If the fixed destination file doesn't have a directory yet, 572 // then we must have a relative path. We will resolve this relative 573 // path against the platform's working directory 574 if (!fixed_dst.GetDirectory()) 575 { 576 FileSpec relative_spec; 577 std::string path; 578 if (working_dir) 579 { 580 relative_spec.SetFile(working_dir.GetCString(), false); 581 relative_spec.AppendPathComponent(dst.GetPath().c_str()); 582 fixed_dst.GetDirectory() = relative_spec.GetDirectory(); 583 } 584 else 585 { 586 error.SetErrorStringWithFormat("platform working directory must be valid for relative path '%s'", dst.GetPath().c_str()); 587 return error; 588 } 589 } 590 } 591 else 592 { 593 if (working_dir) 594 { 595 fixed_dst.GetDirectory() = working_dir; 596 } 597 else 598 { 599 error.SetErrorStringWithFormat("platform working directory must be valid for relative path '%s'", dst.GetPath().c_str()); 600 return error; 601 } 602 } 603 } 604 else 605 { 606 if (working_dir) 607 { 608 fixed_dst.GetDirectory() = working_dir; 609 } 610 else 611 { 612 error.SetErrorStringWithFormat("platform working directory must be valid when destination directory is empty"); 613 return error; 614 } 615 } 616 617 if (log) 618 log->Printf ("Platform::Install (src='%s', dst='%s') fixed_dst='%s'", src.GetPath().c_str(), dst.GetPath().c_str(), fixed_dst.GetPath().c_str()); 619 620 if (GetSupportsRSync()) 621 { 622 error = PutFile(src, dst); 623 } 624 else 625 { 626 switch (src.GetFileType()) 627 { 628 case FileSpec::eFileTypeDirectory: 629 { 630 if (GetFileExists (fixed_dst)) 631 Unlink (fixed_dst.GetPath().c_str()); 632 uint32_t permissions = src.GetPermissions(); 633 if (permissions == 0) 634 permissions = eFilePermissionsDirectoryDefault; 635 std::string dst_dir_path(fixed_dst.GetPath()); 636 error = MakeDirectory(dst_dir_path.c_str(), permissions); 637 if (error.Success()) 638 { 639 // Make a filespec that only fills in the directory of a FileSpec so 640 // when we enumerate we can quickly fill in the filename for dst copies 641 FileSpec recurse_dst; 642 recurse_dst.GetDirectory().SetCString(dst_dir_path.c_str()); 643 std::string src_dir_path (src.GetPath()); 644 RecurseCopyBaton baton = { recurse_dst, this, Error() }; 645 FileSpec::EnumerateDirectory(src_dir_path.c_str(), true, true, true, RecurseCopy_Callback, &baton); 646 return baton.error; 647 } 648 } 649 break; 650 651 case FileSpec::eFileTypeRegular: 652 if (GetFileExists (fixed_dst)) 653 Unlink (fixed_dst.GetPath().c_str()); 654 error = PutFile(src, fixed_dst); 655 break; 656 657 case FileSpec::eFileTypeSymbolicLink: 658 { 659 if (GetFileExists (fixed_dst)) 660 Unlink (fixed_dst.GetPath().c_str()); 661 char buf[PATH_MAX]; 662 error = FileSystem::Readlink(src.GetPath().c_str(), buf, sizeof(buf)); 663 if (error.Success()) 664 error = CreateSymlink(dst.GetPath().c_str(), buf); 665 } 666 break; 667 case FileSpec::eFileTypePipe: 668 error.SetErrorString("platform install doesn't handle pipes"); 669 break; 670 case FileSpec::eFileTypeSocket: 671 error.SetErrorString("platform install doesn't handle sockets"); 672 break; 673 case FileSpec::eFileTypeInvalid: 674 case FileSpec::eFileTypeUnknown: 675 case FileSpec::eFileTypeOther: 676 error.SetErrorString("platform install doesn't handle non file or directory items"); 677 break; 678 } 679 } 680 return error; 681 } 682 683 bool 684 Platform::SetWorkingDirectory (const ConstString &path) 685 { 686 if (IsHost()) 687 { 688 Log *log = GetLogIfAnyCategoriesSet(LIBLLDB_LOG_PLATFORM); 689 if (log) 690 log->Printf("Platform::SetWorkingDirectory('%s')", path.GetCString()); 691 #ifdef _WIN32 692 // Not implemented on Windows 693 return false; 694 #else 695 if (path) 696 { 697 if (chdir(path.GetCString()) == 0) 698 return true; 699 } 700 return false; 701 #endif 702 } 703 else 704 { 705 m_working_dir.Clear(); 706 return SetRemoteWorkingDirectory(path); 707 } 708 } 709 710 Error 711 Platform::MakeDirectory (const char *path, uint32_t permissions) 712 { 713 if (IsHost()) 714 return FileSystem::MakeDirectory(path, permissions); 715 else 716 { 717 Error error; 718 error.SetErrorStringWithFormat("remote platform %s doesn't support %s", GetPluginName().GetCString(), __PRETTY_FUNCTION__); 719 return error; 720 } 721 } 722 723 Error 724 Platform::GetFilePermissions (const char *path, uint32_t &file_permissions) 725 { 726 if (IsHost()) 727 return FileSystem::GetFilePermissions(path, file_permissions); 728 else 729 { 730 Error error; 731 error.SetErrorStringWithFormat("remote platform %s doesn't support %s", GetPluginName().GetCString(), __PRETTY_FUNCTION__); 732 return error; 733 } 734 } 735 736 Error 737 Platform::SetFilePermissions (const char *path, uint32_t file_permissions) 738 { 739 if (IsHost()) 740 return FileSystem::SetFilePermissions(path, file_permissions); 741 else 742 { 743 Error error; 744 error.SetErrorStringWithFormat("remote platform %s doesn't support %s", GetPluginName().GetCString(), __PRETTY_FUNCTION__); 745 return error; 746 } 747 } 748 749 ConstString 750 Platform::GetName () 751 { 752 return GetPluginName(); 753 } 754 755 const char * 756 Platform::GetHostname () 757 { 758 if (IsHost()) 759 return "127.0.0.1"; 760 761 if (m_name.empty()) 762 return NULL; 763 return m_name.c_str(); 764 } 765 766 bool 767 Platform::SetRemoteWorkingDirectory(const ConstString &path) 768 { 769 Log *log = GetLogIfAnyCategoriesSet(LIBLLDB_LOG_PLATFORM); 770 if (log) 771 log->Printf("Platform::SetRemoteWorkingDirectory('%s')", path.GetCString()); 772 m_working_dir = path; 773 return true; 774 } 775 776 const char * 777 Platform::GetUserName (uint32_t uid) 778 { 779 #if !defined(LLDB_DISABLE_POSIX) 780 const char *user_name = GetCachedUserName(uid); 781 if (user_name) 782 return user_name; 783 if (IsHost()) 784 { 785 std::string name; 786 if (HostInfo::LookupUserName(uid, name)) 787 return SetCachedUserName (uid, name.c_str(), name.size()); 788 } 789 #endif 790 return NULL; 791 } 792 793 const char * 794 Platform::GetGroupName (uint32_t gid) 795 { 796 #if !defined(LLDB_DISABLE_POSIX) 797 const char *group_name = GetCachedGroupName(gid); 798 if (group_name) 799 return group_name; 800 if (IsHost()) 801 { 802 std::string name; 803 if (HostInfo::LookupGroupName(gid, name)) 804 return SetCachedGroupName (gid, name.c_str(), name.size()); 805 } 806 #endif 807 return NULL; 808 } 809 810 bool 811 Platform::SetOSVersion (uint32_t major, 812 uint32_t minor, 813 uint32_t update) 814 { 815 if (IsHost()) 816 { 817 // We don't need anyone setting the OS version for the host platform, 818 // we should be able to figure it out by calling HostInfo::GetOSVersion(...). 819 return false; 820 } 821 else 822 { 823 // We have a remote platform, allow setting the target OS version if 824 // we aren't connected, since if we are connected, we should be able to 825 // request the remote OS version from the connected platform. 826 if (IsConnected()) 827 return false; 828 else 829 { 830 // We aren't connected and we might want to set the OS version 831 // ahead of time before we connect so we can peruse files and 832 // use a local SDK or PDK cache of support files to disassemble 833 // or do other things. 834 m_major_os_version = major; 835 m_minor_os_version = minor; 836 m_update_os_version = update; 837 return true; 838 } 839 } 840 return false; 841 } 842 843 844 Error 845 Platform::ResolveExecutable (const FileSpec &exe_file, 846 const ArchSpec &exe_arch, 847 lldb::ModuleSP &exe_module_sp, 848 const FileSpecList *module_search_paths_ptr) 849 { 850 Error error; 851 if (exe_file.Exists()) 852 { 853 ModuleSpec module_spec (exe_file, exe_arch); 854 if (module_spec.GetArchitecture().IsValid()) 855 { 856 error = ModuleList::GetSharedModule (module_spec, 857 exe_module_sp, 858 module_search_paths_ptr, 859 NULL, 860 NULL); 861 } 862 else 863 { 864 // No valid architecture was specified, ask the platform for 865 // the architectures that we should be using (in the correct order) 866 // and see if we can find a match that way 867 for (uint32_t idx = 0; GetSupportedArchitectureAtIndex (idx, module_spec.GetArchitecture()); ++idx) 868 { 869 error = ModuleList::GetSharedModule (module_spec, 870 exe_module_sp, 871 module_search_paths_ptr, 872 NULL, 873 NULL); 874 // Did we find an executable using one of the 875 if (error.Success() && exe_module_sp) 876 break; 877 } 878 } 879 } 880 else 881 { 882 error.SetErrorStringWithFormat ("'%s' does not exist", 883 exe_file.GetPath().c_str()); 884 } 885 return error; 886 } 887 888 Error 889 Platform::ResolveSymbolFile (Target &target, 890 const ModuleSpec &sym_spec, 891 FileSpec &sym_file) 892 { 893 Error error; 894 if (sym_spec.GetSymbolFileSpec().Exists()) 895 sym_file = sym_spec.GetSymbolFileSpec(); 896 else 897 error.SetErrorString("unable to resolve symbol file"); 898 return error; 899 900 } 901 902 903 904 bool 905 Platform::ResolveRemotePath (const FileSpec &platform_path, 906 FileSpec &resolved_platform_path) 907 { 908 resolved_platform_path = platform_path; 909 return resolved_platform_path.ResolvePath(); 910 } 911 912 913 const ArchSpec & 914 Platform::GetSystemArchitecture() 915 { 916 if (IsHost()) 917 { 918 if (!m_system_arch.IsValid()) 919 { 920 // We have a local host platform 921 m_system_arch = HostInfo::GetArchitecture(); 922 m_system_arch_set_while_connected = m_system_arch.IsValid(); 923 } 924 } 925 else 926 { 927 // We have a remote platform. We can only fetch the remote 928 // system architecture if we are connected, and we don't want to do it 929 // more than once. 930 931 const bool is_connected = IsConnected(); 932 933 bool fetch = false; 934 if (m_system_arch.IsValid()) 935 { 936 // We have valid OS version info, check to make sure it wasn't 937 // manually set prior to connecting. If it was manually set prior 938 // to connecting, then lets fetch the actual OS version info 939 // if we are now connected. 940 if (is_connected && !m_system_arch_set_while_connected) 941 fetch = true; 942 } 943 else 944 { 945 // We don't have valid OS version info, fetch it if we are connected 946 fetch = is_connected; 947 } 948 949 if (fetch) 950 { 951 m_system_arch = GetRemoteSystemArchitecture (); 952 m_system_arch_set_while_connected = m_system_arch.IsValid(); 953 } 954 } 955 return m_system_arch; 956 } 957 958 959 Error 960 Platform::ConnectRemote (Args& args) 961 { 962 Error error; 963 if (IsHost()) 964 error.SetErrorStringWithFormat ("The currently selected platform (%s) is the host platform and is always connected.", GetPluginName().GetCString()); 965 else 966 error.SetErrorStringWithFormat ("Platform::ConnectRemote() is not supported by %s", GetPluginName().GetCString()); 967 return error; 968 } 969 970 Error 971 Platform::DisconnectRemote () 972 { 973 Error error; 974 if (IsHost()) 975 error.SetErrorStringWithFormat ("The currently selected platform (%s) is the host platform and is always connected.", GetPluginName().GetCString()); 976 else 977 error.SetErrorStringWithFormat ("Platform::DisconnectRemote() is not supported by %s", GetPluginName().GetCString()); 978 return error; 979 } 980 981 bool 982 Platform::GetProcessInfo (lldb::pid_t pid, ProcessInstanceInfo &process_info) 983 { 984 // Take care of the host case so that each subclass can just 985 // call this function to get the host functionality. 986 if (IsHost()) 987 return Host::GetProcessInfo (pid, process_info); 988 return false; 989 } 990 991 uint32_t 992 Platform::FindProcesses (const ProcessInstanceInfoMatch &match_info, 993 ProcessInstanceInfoList &process_infos) 994 { 995 // Take care of the host case so that each subclass can just 996 // call this function to get the host functionality. 997 uint32_t match_count = 0; 998 if (IsHost()) 999 match_count = Host::FindProcesses (match_info, process_infos); 1000 return match_count; 1001 } 1002 1003 1004 Error 1005 Platform::LaunchProcess (ProcessLaunchInfo &launch_info) 1006 { 1007 Error error; 1008 // Take care of the host case so that each subclass can just 1009 // call this function to get the host functionality. 1010 if (IsHost()) 1011 { 1012 if (::getenv ("LLDB_LAUNCH_FLAG_LAUNCH_IN_TTY")) 1013 launch_info.GetFlags().Set (eLaunchFlagLaunchInTTY); 1014 1015 if (launch_info.GetFlags().Test (eLaunchFlagLaunchInShell)) 1016 { 1017 const bool is_localhost = true; 1018 const bool will_debug = launch_info.GetFlags().Test(eLaunchFlagDebug); 1019 const bool first_arg_is_full_shell_command = false; 1020 uint32_t num_resumes = GetResumeCountForLaunchInfo (launch_info); 1021 if (!launch_info.ConvertArgumentsForLaunchingInShell (error, 1022 is_localhost, 1023 will_debug, 1024 first_arg_is_full_shell_command, 1025 num_resumes)) 1026 return error; 1027 } 1028 1029 error = Host::LaunchProcess (launch_info); 1030 } 1031 else 1032 error.SetErrorString ("base lldb_private::Platform class can't launch remote processes"); 1033 return error; 1034 } 1035 1036 lldb::ProcessSP 1037 Platform::DebugProcess (ProcessLaunchInfo &launch_info, 1038 Debugger &debugger, 1039 Target *target, // Can be NULL, if NULL create a new target, else use existing one 1040 Listener &listener, 1041 Error &error) 1042 { 1043 ProcessSP process_sp; 1044 // Make sure we stop at the entry point 1045 launch_info.GetFlags ().Set (eLaunchFlagDebug); 1046 // We always launch the process we are going to debug in a separate process 1047 // group, since then we can handle ^C interrupts ourselves w/o having to worry 1048 // about the target getting them as well. 1049 launch_info.SetLaunchInSeparateProcessGroup(true); 1050 1051 error = LaunchProcess (launch_info); 1052 if (error.Success()) 1053 { 1054 if (launch_info.GetProcessID() != LLDB_INVALID_PROCESS_ID) 1055 { 1056 ProcessAttachInfo attach_info (launch_info); 1057 process_sp = Attach (attach_info, debugger, target, listener, error); 1058 if (process_sp) 1059 { 1060 launch_info.SetHijackListener(attach_info.GetHijackListener()); 1061 1062 // Since we attached to the process, it will think it needs to detach 1063 // if the process object just goes away without an explicit call to 1064 // Process::Kill() or Process::Detach(), so let it know to kill the 1065 // process if this happens. 1066 process_sp->SetShouldDetach (false); 1067 1068 // If we didn't have any file actions, the pseudo terminal might 1069 // have been used where the slave side was given as the file to 1070 // open for stdin/out/err after we have already opened the master 1071 // so we can read/write stdin/out/err. 1072 int pty_fd = launch_info.GetPTY().ReleaseMasterFileDescriptor(); 1073 if (pty_fd != lldb_utility::PseudoTerminal::invalid_fd) 1074 { 1075 process_sp->SetSTDIOFileDescriptor(pty_fd); 1076 } 1077 } 1078 } 1079 } 1080 return process_sp; 1081 } 1082 1083 1084 lldb::PlatformSP 1085 Platform::GetPlatformForArchitecture (const ArchSpec &arch, ArchSpec *platform_arch_ptr) 1086 { 1087 lldb::PlatformSP platform_sp; 1088 Error error; 1089 if (arch.IsValid()) 1090 platform_sp = Platform::Create (arch, platform_arch_ptr, error); 1091 return platform_sp; 1092 } 1093 1094 1095 //------------------------------------------------------------------ 1096 /// Lets a platform answer if it is compatible with a given 1097 /// architecture and the target triple contained within. 1098 //------------------------------------------------------------------ 1099 bool 1100 Platform::IsCompatibleArchitecture (const ArchSpec &arch, bool exact_arch_match, ArchSpec *compatible_arch_ptr) 1101 { 1102 // If the architecture is invalid, we must answer true... 1103 if (arch.IsValid()) 1104 { 1105 ArchSpec platform_arch; 1106 // Try for an exact architecture match first. 1107 if (exact_arch_match) 1108 { 1109 for (uint32_t arch_idx=0; GetSupportedArchitectureAtIndex (arch_idx, platform_arch); ++arch_idx) 1110 { 1111 if (arch.IsExactMatch(platform_arch)) 1112 { 1113 if (compatible_arch_ptr) 1114 *compatible_arch_ptr = platform_arch; 1115 return true; 1116 } 1117 } 1118 } 1119 else 1120 { 1121 for (uint32_t arch_idx=0; GetSupportedArchitectureAtIndex (arch_idx, platform_arch); ++arch_idx) 1122 { 1123 if (arch.IsCompatibleMatch(platform_arch)) 1124 { 1125 if (compatible_arch_ptr) 1126 *compatible_arch_ptr = platform_arch; 1127 return true; 1128 } 1129 } 1130 } 1131 } 1132 if (compatible_arch_ptr) 1133 compatible_arch_ptr->Clear(); 1134 return false; 1135 } 1136 1137 Error 1138 Platform::PutFile (const FileSpec& source, 1139 const FileSpec& destination, 1140 uint32_t uid, 1141 uint32_t gid) 1142 { 1143 Error error("unimplemented"); 1144 return error; 1145 } 1146 1147 Error 1148 Platform::GetFile (const FileSpec& source, 1149 const FileSpec& destination) 1150 { 1151 Error error("unimplemented"); 1152 return error; 1153 } 1154 1155 Error 1156 Platform::CreateSymlink (const char *src, // The name of the link is in src 1157 const char *dst)// The symlink points to dst 1158 { 1159 Error error("unimplemented"); 1160 return error; 1161 } 1162 1163 bool 1164 Platform::GetFileExists (const lldb_private::FileSpec& file_spec) 1165 { 1166 return false; 1167 } 1168 1169 Error 1170 Platform::Unlink (const char *path) 1171 { 1172 Error error("unimplemented"); 1173 return error; 1174 } 1175 1176 1177 1178 lldb_private::Error 1179 Platform::RunShellCommand (const char *command, // Shouldn't be NULL 1180 const char *working_dir, // Pass NULL to use the current working directory 1181 int *status_ptr, // Pass NULL if you don't want the process exit status 1182 int *signo_ptr, // Pass NULL if you don't want the signal that caused the process to exit 1183 std::string *command_output, // Pass NULL if you don't want the command output 1184 uint32_t timeout_sec) // Timeout in seconds to wait for shell program to finish 1185 { 1186 if (IsHost()) 1187 return Host::RunShellCommand (command, working_dir, status_ptr, signo_ptr, command_output, timeout_sec); 1188 else 1189 return Error("unimplemented"); 1190 } 1191 1192 1193 bool 1194 Platform::CalculateMD5 (const FileSpec& file_spec, 1195 uint64_t &low, 1196 uint64_t &high) 1197 { 1198 if (IsHost()) 1199 return FileSystem::CalculateMD5(file_spec, low, high); 1200 else 1201 return false; 1202 } 1203 1204 Error 1205 Platform::LaunchNativeProcess ( 1206 ProcessLaunchInfo &launch_info, 1207 lldb_private::NativeProcessProtocol::NativeDelegate &native_delegate, 1208 NativeProcessProtocolSP &process_sp) 1209 { 1210 // Platforms should override this implementation if they want to 1211 // support lldb-gdbserver. 1212 return Error("unimplemented"); 1213 } 1214 1215 Error 1216 Platform::AttachNativeProcess (lldb::pid_t pid, 1217 lldb_private::NativeProcessProtocol::NativeDelegate &native_delegate, 1218 NativeProcessProtocolSP &process_sp) 1219 { 1220 // Platforms should override this implementation if they want to 1221 // support lldb-gdbserver. 1222 return Error("unimplemented"); 1223 } 1224 1225 void 1226 Platform::SetLocalCacheDirectory (const char* local) 1227 { 1228 m_local_cache_directory.assign(local); 1229 } 1230 1231 const char* 1232 Platform::GetLocalCacheDirectory () 1233 { 1234 return m_local_cache_directory.c_str(); 1235 } 1236 1237 static OptionDefinition 1238 g_rsync_option_table[] = 1239 { 1240 { LLDB_OPT_SET_ALL, false, "rsync" , 'r', OptionParser::eNoArgument, NULL, NULL, 0, eArgTypeNone , "Enable rsync." }, 1241 { LLDB_OPT_SET_ALL, false, "rsync-opts" , 'R', OptionParser::eRequiredArgument, NULL, NULL, 0, eArgTypeCommandName , "Platform-specific options required for rsync to work." }, 1242 { LLDB_OPT_SET_ALL, false, "rsync-prefix" , 'P', OptionParser::eRequiredArgument, NULL, NULL, 0, eArgTypeCommandName , "Platform-specific rsync prefix put before the remote path." }, 1243 { LLDB_OPT_SET_ALL, false, "ignore-remote-hostname" , 'i', OptionParser::eNoArgument, NULL, NULL, 0, eArgTypeNone , "Do not automatically fill in the remote hostname when composing the rsync command." }, 1244 }; 1245 1246 static OptionDefinition 1247 g_ssh_option_table[] = 1248 { 1249 { LLDB_OPT_SET_ALL, false, "ssh" , 's', OptionParser::eNoArgument, NULL, NULL, 0, eArgTypeNone , "Enable SSH." }, 1250 { LLDB_OPT_SET_ALL, false, "ssh-opts" , 'S', OptionParser::eRequiredArgument, NULL, NULL, 0, eArgTypeCommandName , "Platform-specific options required for SSH to work." }, 1251 }; 1252 1253 static OptionDefinition 1254 g_caching_option_table[] = 1255 { 1256 { LLDB_OPT_SET_ALL, false, "local-cache-dir" , 'c', OptionParser::eRequiredArgument, NULL, NULL, 0, eArgTypePath , "Path in which to store local copies of files." }, 1257 }; 1258 1259 OptionGroupPlatformRSync::OptionGroupPlatformRSync () 1260 { 1261 } 1262 1263 OptionGroupPlatformRSync::~OptionGroupPlatformRSync () 1264 { 1265 } 1266 1267 const lldb_private::OptionDefinition* 1268 OptionGroupPlatformRSync::GetDefinitions () 1269 { 1270 return g_rsync_option_table; 1271 } 1272 1273 void 1274 OptionGroupPlatformRSync::OptionParsingStarting (CommandInterpreter &interpreter) 1275 { 1276 m_rsync = false; 1277 m_rsync_opts.clear(); 1278 m_rsync_prefix.clear(); 1279 m_ignores_remote_hostname = false; 1280 } 1281 1282 lldb_private::Error 1283 OptionGroupPlatformRSync::SetOptionValue (CommandInterpreter &interpreter, 1284 uint32_t option_idx, 1285 const char *option_arg) 1286 { 1287 Error error; 1288 char short_option = (char) GetDefinitions()[option_idx].short_option; 1289 switch (short_option) 1290 { 1291 case 'r': 1292 m_rsync = true; 1293 break; 1294 1295 case 'R': 1296 m_rsync_opts.assign(option_arg); 1297 break; 1298 1299 case 'P': 1300 m_rsync_prefix.assign(option_arg); 1301 break; 1302 1303 case 'i': 1304 m_ignores_remote_hostname = true; 1305 break; 1306 1307 default: 1308 error.SetErrorStringWithFormat ("unrecognized option '%c'", short_option); 1309 break; 1310 } 1311 1312 return error; 1313 } 1314 1315 uint32_t 1316 OptionGroupPlatformRSync::GetNumDefinitions () 1317 { 1318 return llvm::array_lengthof(g_rsync_option_table); 1319 } 1320 1321 lldb::BreakpointSP 1322 Platform::SetThreadCreationBreakpoint (lldb_private::Target &target) 1323 { 1324 return lldb::BreakpointSP(); 1325 } 1326 1327 OptionGroupPlatformSSH::OptionGroupPlatformSSH () 1328 { 1329 } 1330 1331 OptionGroupPlatformSSH::~OptionGroupPlatformSSH () 1332 { 1333 } 1334 1335 const lldb_private::OptionDefinition* 1336 OptionGroupPlatformSSH::GetDefinitions () 1337 { 1338 return g_ssh_option_table; 1339 } 1340 1341 void 1342 OptionGroupPlatformSSH::OptionParsingStarting (CommandInterpreter &interpreter) 1343 { 1344 m_ssh = false; 1345 m_ssh_opts.clear(); 1346 } 1347 1348 lldb_private::Error 1349 OptionGroupPlatformSSH::SetOptionValue (CommandInterpreter &interpreter, 1350 uint32_t option_idx, 1351 const char *option_arg) 1352 { 1353 Error error; 1354 char short_option = (char) GetDefinitions()[option_idx].short_option; 1355 switch (short_option) 1356 { 1357 case 's': 1358 m_ssh = true; 1359 break; 1360 1361 case 'S': 1362 m_ssh_opts.assign(option_arg); 1363 break; 1364 1365 default: 1366 error.SetErrorStringWithFormat ("unrecognized option '%c'", short_option); 1367 break; 1368 } 1369 1370 return error; 1371 } 1372 1373 uint32_t 1374 OptionGroupPlatformSSH::GetNumDefinitions () 1375 { 1376 return llvm::array_lengthof(g_ssh_option_table); 1377 } 1378 1379 OptionGroupPlatformCaching::OptionGroupPlatformCaching () 1380 { 1381 } 1382 1383 OptionGroupPlatformCaching::~OptionGroupPlatformCaching () 1384 { 1385 } 1386 1387 const lldb_private::OptionDefinition* 1388 OptionGroupPlatformCaching::GetDefinitions () 1389 { 1390 return g_caching_option_table; 1391 } 1392 1393 void 1394 OptionGroupPlatformCaching::OptionParsingStarting (CommandInterpreter &interpreter) 1395 { 1396 m_cache_dir.clear(); 1397 } 1398 1399 lldb_private::Error 1400 OptionGroupPlatformCaching::SetOptionValue (CommandInterpreter &interpreter, 1401 uint32_t option_idx, 1402 const char *option_arg) 1403 { 1404 Error error; 1405 char short_option = (char) GetDefinitions()[option_idx].short_option; 1406 switch (short_option) 1407 { 1408 case 'c': 1409 m_cache_dir.assign(option_arg); 1410 break; 1411 1412 default: 1413 error.SetErrorStringWithFormat ("unrecognized option '%c'", short_option); 1414 break; 1415 } 1416 1417 return error; 1418 } 1419 1420 uint32_t 1421 OptionGroupPlatformCaching::GetNumDefinitions () 1422 { 1423 return llvm::array_lengthof(g_caching_option_table); 1424 } 1425 1426 size_t 1427 Platform::GetEnvironment (StringList &environment) 1428 { 1429 environment.Clear(); 1430 return false; 1431 } 1432 1433 const std::vector<ConstString> & 1434 Platform::GetTrapHandlerSymbolNames () 1435 { 1436 if (!m_calculated_trap_handlers) 1437 { 1438 Mutex::Locker locker (m_trap_handler_mutex); 1439 if (!m_calculated_trap_handlers) 1440 { 1441 CalculateTrapHandlerSymbolNames(); 1442 m_calculated_trap_handlers = true; 1443 } 1444 } 1445 return m_trap_handlers; 1446 } 1447 1448