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 const char *user_name = GetCachedUserName(uid); 780 if (user_name) 781 return user_name; 782 if (IsHost()) 783 { 784 std::string name; 785 if (Host::GetUserName(uid, name)) 786 return SetCachedUserName (uid, name.c_str(), name.size()); 787 } 788 return NULL; 789 } 790 791 const char * 792 Platform::GetGroupName (uint32_t gid) 793 { 794 const char *group_name = GetCachedGroupName(gid); 795 if (group_name) 796 return group_name; 797 if (IsHost()) 798 { 799 std::string name; 800 if (Host::GetGroupName(gid, name)) 801 return SetCachedGroupName (gid, name.c_str(), name.size()); 802 } 803 return NULL; 804 } 805 806 bool 807 Platform::SetOSVersion (uint32_t major, 808 uint32_t minor, 809 uint32_t update) 810 { 811 if (IsHost()) 812 { 813 // We don't need anyone setting the OS version for the host platform, 814 // we should be able to figure it out by calling HostInfo::GetOSVersion(...). 815 return false; 816 } 817 else 818 { 819 // We have a remote platform, allow setting the target OS version if 820 // we aren't connected, since if we are connected, we should be able to 821 // request the remote OS version from the connected platform. 822 if (IsConnected()) 823 return false; 824 else 825 { 826 // We aren't connected and we might want to set the OS version 827 // ahead of time before we connect so we can peruse files and 828 // use a local SDK or PDK cache of support files to disassemble 829 // or do other things. 830 m_major_os_version = major; 831 m_minor_os_version = minor; 832 m_update_os_version = update; 833 return true; 834 } 835 } 836 return false; 837 } 838 839 840 Error 841 Platform::ResolveExecutable (const FileSpec &exe_file, 842 const ArchSpec &exe_arch, 843 lldb::ModuleSP &exe_module_sp, 844 const FileSpecList *module_search_paths_ptr) 845 { 846 Error error; 847 if (exe_file.Exists()) 848 { 849 ModuleSpec module_spec (exe_file, exe_arch); 850 if (module_spec.GetArchitecture().IsValid()) 851 { 852 error = ModuleList::GetSharedModule (module_spec, 853 exe_module_sp, 854 module_search_paths_ptr, 855 NULL, 856 NULL); 857 } 858 else 859 { 860 // No valid architecture was specified, ask the platform for 861 // the architectures that we should be using (in the correct order) 862 // and see if we can find a match that way 863 for (uint32_t idx = 0; GetSupportedArchitectureAtIndex (idx, module_spec.GetArchitecture()); ++idx) 864 { 865 error = ModuleList::GetSharedModule (module_spec, 866 exe_module_sp, 867 module_search_paths_ptr, 868 NULL, 869 NULL); 870 // Did we find an executable using one of the 871 if (error.Success() && exe_module_sp) 872 break; 873 } 874 } 875 } 876 else 877 { 878 error.SetErrorStringWithFormat ("'%s' does not exist", 879 exe_file.GetPath().c_str()); 880 } 881 return error; 882 } 883 884 Error 885 Platform::ResolveSymbolFile (Target &target, 886 const ModuleSpec &sym_spec, 887 FileSpec &sym_file) 888 { 889 Error error; 890 if (sym_spec.GetSymbolFileSpec().Exists()) 891 sym_file = sym_spec.GetSymbolFileSpec(); 892 else 893 error.SetErrorString("unable to resolve symbol file"); 894 return error; 895 896 } 897 898 899 900 bool 901 Platform::ResolveRemotePath (const FileSpec &platform_path, 902 FileSpec &resolved_platform_path) 903 { 904 resolved_platform_path = platform_path; 905 return resolved_platform_path.ResolvePath(); 906 } 907 908 909 const ArchSpec & 910 Platform::GetSystemArchitecture() 911 { 912 if (IsHost()) 913 { 914 if (!m_system_arch.IsValid()) 915 { 916 // We have a local host platform 917 m_system_arch = Host::GetArchitecture(); 918 m_system_arch_set_while_connected = m_system_arch.IsValid(); 919 } 920 } 921 else 922 { 923 // We have a remote platform. We can only fetch the remote 924 // system architecture if we are connected, and we don't want to do it 925 // more than once. 926 927 const bool is_connected = IsConnected(); 928 929 bool fetch = false; 930 if (m_system_arch.IsValid()) 931 { 932 // We have valid OS version info, check to make sure it wasn't 933 // manually set prior to connecting. If it was manually set prior 934 // to connecting, then lets fetch the actual OS version info 935 // if we are now connected. 936 if (is_connected && !m_system_arch_set_while_connected) 937 fetch = true; 938 } 939 else 940 { 941 // We don't have valid OS version info, fetch it if we are connected 942 fetch = is_connected; 943 } 944 945 if (fetch) 946 { 947 m_system_arch = GetRemoteSystemArchitecture (); 948 m_system_arch_set_while_connected = m_system_arch.IsValid(); 949 } 950 } 951 return m_system_arch; 952 } 953 954 955 Error 956 Platform::ConnectRemote (Args& args) 957 { 958 Error error; 959 if (IsHost()) 960 error.SetErrorStringWithFormat ("The currently selected platform (%s) is the host platform and is always connected.", GetPluginName().GetCString()); 961 else 962 error.SetErrorStringWithFormat ("Platform::ConnectRemote() is not supported by %s", GetPluginName().GetCString()); 963 return error; 964 } 965 966 Error 967 Platform::DisconnectRemote () 968 { 969 Error error; 970 if (IsHost()) 971 error.SetErrorStringWithFormat ("The currently selected platform (%s) is the host platform and is always connected.", GetPluginName().GetCString()); 972 else 973 error.SetErrorStringWithFormat ("Platform::DisconnectRemote() is not supported by %s", GetPluginName().GetCString()); 974 return error; 975 } 976 977 bool 978 Platform::GetProcessInfo (lldb::pid_t pid, ProcessInstanceInfo &process_info) 979 { 980 // Take care of the host case so that each subclass can just 981 // call this function to get the host functionality. 982 if (IsHost()) 983 return Host::GetProcessInfo (pid, process_info); 984 return false; 985 } 986 987 uint32_t 988 Platform::FindProcesses (const ProcessInstanceInfoMatch &match_info, 989 ProcessInstanceInfoList &process_infos) 990 { 991 // Take care of the host case so that each subclass can just 992 // call this function to get the host functionality. 993 uint32_t match_count = 0; 994 if (IsHost()) 995 match_count = Host::FindProcesses (match_info, process_infos); 996 return match_count; 997 } 998 999 1000 Error 1001 Platform::LaunchProcess (ProcessLaunchInfo &launch_info) 1002 { 1003 Error error; 1004 // Take care of the host case so that each subclass can just 1005 // call this function to get the host functionality. 1006 if (IsHost()) 1007 { 1008 if (::getenv ("LLDB_LAUNCH_FLAG_LAUNCH_IN_TTY")) 1009 launch_info.GetFlags().Set (eLaunchFlagLaunchInTTY); 1010 1011 if (launch_info.GetFlags().Test (eLaunchFlagLaunchInShell)) 1012 { 1013 const bool is_localhost = true; 1014 const bool will_debug = launch_info.GetFlags().Test(eLaunchFlagDebug); 1015 const bool first_arg_is_full_shell_command = false; 1016 uint32_t num_resumes = GetResumeCountForLaunchInfo (launch_info); 1017 if (!launch_info.ConvertArgumentsForLaunchingInShell (error, 1018 is_localhost, 1019 will_debug, 1020 first_arg_is_full_shell_command, 1021 num_resumes)) 1022 return error; 1023 } 1024 1025 error = Host::LaunchProcess (launch_info); 1026 } 1027 else 1028 error.SetErrorString ("base lldb_private::Platform class can't launch remote processes"); 1029 return error; 1030 } 1031 1032 lldb::ProcessSP 1033 Platform::DebugProcess (ProcessLaunchInfo &launch_info, 1034 Debugger &debugger, 1035 Target *target, // Can be NULL, if NULL create a new target, else use existing one 1036 Listener &listener, 1037 Error &error) 1038 { 1039 ProcessSP process_sp; 1040 // Make sure we stop at the entry point 1041 launch_info.GetFlags ().Set (eLaunchFlagDebug); 1042 // We always launch the process we are going to debug in a separate process 1043 // group, since then we can handle ^C interrupts ourselves w/o having to worry 1044 // about the target getting them as well. 1045 launch_info.SetLaunchInSeparateProcessGroup(true); 1046 1047 error = LaunchProcess (launch_info); 1048 if (error.Success()) 1049 { 1050 if (launch_info.GetProcessID() != LLDB_INVALID_PROCESS_ID) 1051 { 1052 ProcessAttachInfo attach_info (launch_info); 1053 process_sp = Attach (attach_info, debugger, target, listener, error); 1054 if (process_sp) 1055 { 1056 launch_info.SetHijackListener(attach_info.GetHijackListener()); 1057 1058 // Since we attached to the process, it will think it needs to detach 1059 // if the process object just goes away without an explicit call to 1060 // Process::Kill() or Process::Detach(), so let it know to kill the 1061 // process if this happens. 1062 process_sp->SetShouldDetach (false); 1063 1064 // If we didn't have any file actions, the pseudo terminal might 1065 // have been used where the slave side was given as the file to 1066 // open for stdin/out/err after we have already opened the master 1067 // so we can read/write stdin/out/err. 1068 int pty_fd = launch_info.GetPTY().ReleaseMasterFileDescriptor(); 1069 if (pty_fd != lldb_utility::PseudoTerminal::invalid_fd) 1070 { 1071 process_sp->SetSTDIOFileDescriptor(pty_fd); 1072 } 1073 } 1074 } 1075 } 1076 return process_sp; 1077 } 1078 1079 1080 lldb::PlatformSP 1081 Platform::GetPlatformForArchitecture (const ArchSpec &arch, ArchSpec *platform_arch_ptr) 1082 { 1083 lldb::PlatformSP platform_sp; 1084 Error error; 1085 if (arch.IsValid()) 1086 platform_sp = Platform::Create (arch, platform_arch_ptr, error); 1087 return platform_sp; 1088 } 1089 1090 1091 //------------------------------------------------------------------ 1092 /// Lets a platform answer if it is compatible with a given 1093 /// architecture and the target triple contained within. 1094 //------------------------------------------------------------------ 1095 bool 1096 Platform::IsCompatibleArchitecture (const ArchSpec &arch, bool exact_arch_match, ArchSpec *compatible_arch_ptr) 1097 { 1098 // If the architecture is invalid, we must answer true... 1099 if (arch.IsValid()) 1100 { 1101 ArchSpec platform_arch; 1102 // Try for an exact architecture match first. 1103 if (exact_arch_match) 1104 { 1105 for (uint32_t arch_idx=0; GetSupportedArchitectureAtIndex (arch_idx, platform_arch); ++arch_idx) 1106 { 1107 if (arch.IsExactMatch(platform_arch)) 1108 { 1109 if (compatible_arch_ptr) 1110 *compatible_arch_ptr = platform_arch; 1111 return true; 1112 } 1113 } 1114 } 1115 else 1116 { 1117 for (uint32_t arch_idx=0; GetSupportedArchitectureAtIndex (arch_idx, platform_arch); ++arch_idx) 1118 { 1119 if (arch.IsCompatibleMatch(platform_arch)) 1120 { 1121 if (compatible_arch_ptr) 1122 *compatible_arch_ptr = platform_arch; 1123 return true; 1124 } 1125 } 1126 } 1127 } 1128 if (compatible_arch_ptr) 1129 compatible_arch_ptr->Clear(); 1130 return false; 1131 } 1132 1133 Error 1134 Platform::PutFile (const FileSpec& source, 1135 const FileSpec& destination, 1136 uint32_t uid, 1137 uint32_t gid) 1138 { 1139 Error error("unimplemented"); 1140 return error; 1141 } 1142 1143 Error 1144 Platform::GetFile (const FileSpec& source, 1145 const FileSpec& destination) 1146 { 1147 Error error("unimplemented"); 1148 return error; 1149 } 1150 1151 Error 1152 Platform::CreateSymlink (const char *src, // The name of the link is in src 1153 const char *dst)// The symlink points to dst 1154 { 1155 Error error("unimplemented"); 1156 return error; 1157 } 1158 1159 bool 1160 Platform::GetFileExists (const lldb_private::FileSpec& file_spec) 1161 { 1162 return false; 1163 } 1164 1165 Error 1166 Platform::Unlink (const char *path) 1167 { 1168 Error error("unimplemented"); 1169 return error; 1170 } 1171 1172 1173 1174 lldb_private::Error 1175 Platform::RunShellCommand (const char *command, // Shouldn't be NULL 1176 const char *working_dir, // Pass NULL to use the current working directory 1177 int *status_ptr, // Pass NULL if you don't want the process exit status 1178 int *signo_ptr, // Pass NULL if you don't want the signal that caused the process to exit 1179 std::string *command_output, // Pass NULL if you don't want the command output 1180 uint32_t timeout_sec) // Timeout in seconds to wait for shell program to finish 1181 { 1182 if (IsHost()) 1183 return Host::RunShellCommand (command, working_dir, status_ptr, signo_ptr, command_output, timeout_sec); 1184 else 1185 return Error("unimplemented"); 1186 } 1187 1188 1189 bool 1190 Platform::CalculateMD5 (const FileSpec& file_spec, 1191 uint64_t &low, 1192 uint64_t &high) 1193 { 1194 if (IsHost()) 1195 return FileSystem::CalculateMD5(file_spec, low, high); 1196 else 1197 return false; 1198 } 1199 1200 Error 1201 Platform::LaunchNativeProcess ( 1202 ProcessLaunchInfo &launch_info, 1203 lldb_private::NativeProcessProtocol::NativeDelegate &native_delegate, 1204 NativeProcessProtocolSP &process_sp) 1205 { 1206 // Platforms should override this implementation if they want to 1207 // support lldb-gdbserver. 1208 return Error("unimplemented"); 1209 } 1210 1211 Error 1212 Platform::AttachNativeProcess (lldb::pid_t pid, 1213 lldb_private::NativeProcessProtocol::NativeDelegate &native_delegate, 1214 NativeProcessProtocolSP &process_sp) 1215 { 1216 // Platforms should override this implementation if they want to 1217 // support lldb-gdbserver. 1218 return Error("unimplemented"); 1219 } 1220 1221 void 1222 Platform::SetLocalCacheDirectory (const char* local) 1223 { 1224 m_local_cache_directory.assign(local); 1225 } 1226 1227 const char* 1228 Platform::GetLocalCacheDirectory () 1229 { 1230 return m_local_cache_directory.c_str(); 1231 } 1232 1233 static OptionDefinition 1234 g_rsync_option_table[] = 1235 { 1236 { LLDB_OPT_SET_ALL, false, "rsync" , 'r', OptionParser::eNoArgument, NULL, NULL, 0, eArgTypeNone , "Enable rsync." }, 1237 { LLDB_OPT_SET_ALL, false, "rsync-opts" , 'R', OptionParser::eRequiredArgument, NULL, NULL, 0, eArgTypeCommandName , "Platform-specific options required for rsync to work." }, 1238 { LLDB_OPT_SET_ALL, false, "rsync-prefix" , 'P', OptionParser::eRequiredArgument, NULL, NULL, 0, eArgTypeCommandName , "Platform-specific rsync prefix put before the remote path." }, 1239 { 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." }, 1240 }; 1241 1242 static OptionDefinition 1243 g_ssh_option_table[] = 1244 { 1245 { LLDB_OPT_SET_ALL, false, "ssh" , 's', OptionParser::eNoArgument, NULL, NULL, 0, eArgTypeNone , "Enable SSH." }, 1246 { LLDB_OPT_SET_ALL, false, "ssh-opts" , 'S', OptionParser::eRequiredArgument, NULL, NULL, 0, eArgTypeCommandName , "Platform-specific options required for SSH to work." }, 1247 }; 1248 1249 static OptionDefinition 1250 g_caching_option_table[] = 1251 { 1252 { LLDB_OPT_SET_ALL, false, "local-cache-dir" , 'c', OptionParser::eRequiredArgument, NULL, NULL, 0, eArgTypePath , "Path in which to store local copies of files." }, 1253 }; 1254 1255 OptionGroupPlatformRSync::OptionGroupPlatformRSync () 1256 { 1257 } 1258 1259 OptionGroupPlatformRSync::~OptionGroupPlatformRSync () 1260 { 1261 } 1262 1263 const lldb_private::OptionDefinition* 1264 OptionGroupPlatformRSync::GetDefinitions () 1265 { 1266 return g_rsync_option_table; 1267 } 1268 1269 void 1270 OptionGroupPlatformRSync::OptionParsingStarting (CommandInterpreter &interpreter) 1271 { 1272 m_rsync = false; 1273 m_rsync_opts.clear(); 1274 m_rsync_prefix.clear(); 1275 m_ignores_remote_hostname = false; 1276 } 1277 1278 lldb_private::Error 1279 OptionGroupPlatformRSync::SetOptionValue (CommandInterpreter &interpreter, 1280 uint32_t option_idx, 1281 const char *option_arg) 1282 { 1283 Error error; 1284 char short_option = (char) GetDefinitions()[option_idx].short_option; 1285 switch (short_option) 1286 { 1287 case 'r': 1288 m_rsync = true; 1289 break; 1290 1291 case 'R': 1292 m_rsync_opts.assign(option_arg); 1293 break; 1294 1295 case 'P': 1296 m_rsync_prefix.assign(option_arg); 1297 break; 1298 1299 case 'i': 1300 m_ignores_remote_hostname = true; 1301 break; 1302 1303 default: 1304 error.SetErrorStringWithFormat ("unrecognized option '%c'", short_option); 1305 break; 1306 } 1307 1308 return error; 1309 } 1310 1311 uint32_t 1312 OptionGroupPlatformRSync::GetNumDefinitions () 1313 { 1314 return llvm::array_lengthof(g_rsync_option_table); 1315 } 1316 1317 lldb::BreakpointSP 1318 Platform::SetThreadCreationBreakpoint (lldb_private::Target &target) 1319 { 1320 return lldb::BreakpointSP(); 1321 } 1322 1323 OptionGroupPlatformSSH::OptionGroupPlatformSSH () 1324 { 1325 } 1326 1327 OptionGroupPlatformSSH::~OptionGroupPlatformSSH () 1328 { 1329 } 1330 1331 const lldb_private::OptionDefinition* 1332 OptionGroupPlatformSSH::GetDefinitions () 1333 { 1334 return g_ssh_option_table; 1335 } 1336 1337 void 1338 OptionGroupPlatformSSH::OptionParsingStarting (CommandInterpreter &interpreter) 1339 { 1340 m_ssh = false; 1341 m_ssh_opts.clear(); 1342 } 1343 1344 lldb_private::Error 1345 OptionGroupPlatformSSH::SetOptionValue (CommandInterpreter &interpreter, 1346 uint32_t option_idx, 1347 const char *option_arg) 1348 { 1349 Error error; 1350 char short_option = (char) GetDefinitions()[option_idx].short_option; 1351 switch (short_option) 1352 { 1353 case 's': 1354 m_ssh = true; 1355 break; 1356 1357 case 'S': 1358 m_ssh_opts.assign(option_arg); 1359 break; 1360 1361 default: 1362 error.SetErrorStringWithFormat ("unrecognized option '%c'", short_option); 1363 break; 1364 } 1365 1366 return error; 1367 } 1368 1369 uint32_t 1370 OptionGroupPlatformSSH::GetNumDefinitions () 1371 { 1372 return llvm::array_lengthof(g_ssh_option_table); 1373 } 1374 1375 OptionGroupPlatformCaching::OptionGroupPlatformCaching () 1376 { 1377 } 1378 1379 OptionGroupPlatformCaching::~OptionGroupPlatformCaching () 1380 { 1381 } 1382 1383 const lldb_private::OptionDefinition* 1384 OptionGroupPlatformCaching::GetDefinitions () 1385 { 1386 return g_caching_option_table; 1387 } 1388 1389 void 1390 OptionGroupPlatformCaching::OptionParsingStarting (CommandInterpreter &interpreter) 1391 { 1392 m_cache_dir.clear(); 1393 } 1394 1395 lldb_private::Error 1396 OptionGroupPlatformCaching::SetOptionValue (CommandInterpreter &interpreter, 1397 uint32_t option_idx, 1398 const char *option_arg) 1399 { 1400 Error error; 1401 char short_option = (char) GetDefinitions()[option_idx].short_option; 1402 switch (short_option) 1403 { 1404 case 'c': 1405 m_cache_dir.assign(option_arg); 1406 break; 1407 1408 default: 1409 error.SetErrorStringWithFormat ("unrecognized option '%c'", short_option); 1410 break; 1411 } 1412 1413 return error; 1414 } 1415 1416 uint32_t 1417 OptionGroupPlatformCaching::GetNumDefinitions () 1418 { 1419 return llvm::array_lengthof(g_caching_option_table); 1420 } 1421 1422 size_t 1423 Platform::GetEnvironment (StringList &environment) 1424 { 1425 environment.Clear(); 1426 return false; 1427 } 1428 1429 const std::vector<ConstString> & 1430 Platform::GetTrapHandlerSymbolNames () 1431 { 1432 if (!m_calculated_trap_handlers) 1433 { 1434 Mutex::Locker locker (m_trap_handler_mutex); 1435 if (!m_calculated_trap_handlers) 1436 { 1437 CalculateTrapHandlerSymbolNames(); 1438 m_calculated_trap_handlers = true; 1439 } 1440 } 1441 return m_trap_handlers; 1442 } 1443 1444