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/Host.h" 23 #include "lldb/Target/Process.h" 24 #include "lldb/Target/Target.h" 25 26 using namespace lldb; 27 using namespace lldb_private; 28 29 // Use a singleton function for g_local_platform_sp to avoid init 30 // constructors since LLDB is often part of a shared library 31 static PlatformSP& 32 GetDefaultPlatformSP () 33 { 34 static PlatformSP g_default_platform_sp; 35 return g_default_platform_sp; 36 } 37 38 static Mutex & 39 GetConnectedPlatformListMutex () 40 { 41 static Mutex g_remote_connected_platforms_mutex (Mutex::eMutexTypeRecursive); 42 return g_remote_connected_platforms_mutex; 43 } 44 static std::vector<PlatformSP> & 45 GetConnectedPlatformList () 46 { 47 static std::vector<PlatformSP> g_remote_connected_platforms; 48 return g_remote_connected_platforms; 49 } 50 51 52 const char * 53 Platform::GetHostPlatformName () 54 { 55 return "host"; 56 } 57 58 //------------------------------------------------------------------ 59 /// Get the native host platform plug-in. 60 /// 61 /// There should only be one of these for each host that LLDB runs 62 /// upon that should be statically compiled in and registered using 63 /// preprocessor macros or other similar build mechanisms. 64 /// 65 /// This platform will be used as the default platform when launching 66 /// or attaching to processes unless another platform is specified. 67 //------------------------------------------------------------------ 68 PlatformSP 69 Platform::GetDefaultPlatform () 70 { 71 return GetDefaultPlatformSP (); 72 } 73 74 void 75 Platform::SetDefaultPlatform (const lldb::PlatformSP &platform_sp) 76 { 77 // The native platform should use its static void Platform::Initialize() 78 // function to register itself as the native platform. 79 GetDefaultPlatformSP () = platform_sp; 80 } 81 82 Error 83 Platform::GetFile (const FileSpec &platform_file, 84 const UUID *uuid_ptr, 85 FileSpec &local_file) 86 { 87 // Default to the local case 88 local_file = platform_file; 89 return Error(); 90 } 91 92 FileSpecList 93 Platform::LocateExecutableScriptingResources (Target *target, Module &module) 94 { 95 return FileSpecList(); 96 } 97 98 Platform* 99 Platform::FindPlugin (Process *process, const ConstString &plugin_name) 100 { 101 PlatformCreateInstance create_callback = NULL; 102 if (plugin_name) 103 { 104 create_callback = PluginManager::GetPlatformCreateCallbackForPluginName (plugin_name); 105 if (create_callback) 106 { 107 ArchSpec arch; 108 if (process) 109 { 110 arch = process->GetTarget().GetArchitecture(); 111 } 112 std::unique_ptr<Platform> instance_ap(create_callback(process, &arch)); 113 if (instance_ap.get()) 114 return instance_ap.release(); 115 } 116 } 117 else 118 { 119 for (uint32_t idx = 0; (create_callback = PluginManager::GetPlatformCreateCallbackAtIndex(idx)) != NULL; ++idx) 120 { 121 std::unique_ptr<Platform> instance_ap(create_callback(process, nullptr)); 122 if (instance_ap.get()) 123 return instance_ap.release(); 124 } 125 } 126 return NULL; 127 } 128 129 Error 130 Platform::GetSharedModule (const ModuleSpec &module_spec, 131 ModuleSP &module_sp, 132 const FileSpecList *module_search_paths_ptr, 133 ModuleSP *old_module_sp_ptr, 134 bool *did_create_ptr) 135 { 136 // Don't do any path remapping for the default implementation 137 // of the platform GetSharedModule function, just call through 138 // to our static ModuleList function. Platform subclasses that 139 // implement remote debugging, might have a developer kits 140 // installed that have cached versions of the files for the 141 // remote target, or might implement a download and cache 142 // locally implementation. 143 const bool always_create = false; 144 return ModuleList::GetSharedModule (module_spec, 145 module_sp, 146 module_search_paths_ptr, 147 old_module_sp_ptr, 148 did_create_ptr, 149 always_create); 150 } 151 152 PlatformSP 153 Platform::Create (const char *platform_name, Error &error) 154 { 155 PlatformCreateInstance create_callback = NULL; 156 lldb::PlatformSP platform_sp; 157 if (platform_name && platform_name[0]) 158 { 159 ConstString const_platform_name (platform_name); 160 create_callback = PluginManager::GetPlatformCreateCallbackForPluginName (const_platform_name); 161 if (create_callback) 162 platform_sp.reset(create_callback(true, NULL)); 163 else 164 error.SetErrorStringWithFormat ("unable to find a plug-in for the platform named \"%s\"", platform_name); 165 } 166 else 167 error.SetErrorString ("invalid platform name"); 168 return platform_sp; 169 } 170 171 172 PlatformSP 173 Platform::Create (const ArchSpec &arch, ArchSpec *platform_arch_ptr, Error &error) 174 { 175 lldb::PlatformSP platform_sp; 176 if (arch.IsValid()) 177 { 178 uint32_t idx; 179 PlatformCreateInstance create_callback; 180 // First try exact arch matches across all platform plug-ins 181 bool exact = true; 182 for (idx = 0; (create_callback = PluginManager::GetPlatformCreateCallbackAtIndex (idx)); ++idx) 183 { 184 if (create_callback) 185 { 186 platform_sp.reset(create_callback(false, &arch)); 187 if (platform_sp && platform_sp->IsCompatibleArchitecture(arch, exact, platform_arch_ptr)) 188 return platform_sp; 189 } 190 } 191 // Next try compatible arch matches across all platform plug-ins 192 exact = false; 193 for (idx = 0; (create_callback = PluginManager::GetPlatformCreateCallbackAtIndex (idx)); ++idx) 194 { 195 if (create_callback) 196 { 197 platform_sp.reset(create_callback(false, &arch)); 198 if (platform_sp && platform_sp->IsCompatibleArchitecture(arch, exact, platform_arch_ptr)) 199 return platform_sp; 200 } 201 } 202 } 203 else 204 error.SetErrorString ("invalid platform name"); 205 if (platform_arch_ptr) 206 platform_arch_ptr->Clear(); 207 platform_sp.reset(); 208 return platform_sp; 209 } 210 211 uint32_t 212 Platform::GetNumConnectedRemotePlatforms () 213 { 214 Mutex::Locker locker (GetConnectedPlatformListMutex ()); 215 return GetConnectedPlatformList().size(); 216 } 217 218 PlatformSP 219 Platform::GetConnectedRemotePlatformAtIndex (uint32_t idx) 220 { 221 PlatformSP platform_sp; 222 { 223 Mutex::Locker locker (GetConnectedPlatformListMutex ()); 224 if (idx < GetConnectedPlatformList().size()) 225 platform_sp = GetConnectedPlatformList ()[idx]; 226 } 227 return platform_sp; 228 } 229 230 //------------------------------------------------------------------ 231 /// Default Constructor 232 //------------------------------------------------------------------ 233 Platform::Platform (bool is_host) : 234 m_is_host (is_host), 235 m_os_version_set_while_connected (false), 236 m_system_arch_set_while_connected (false), 237 m_sdk_sysroot (), 238 m_sdk_build (), 239 m_remote_url (), 240 m_name (), 241 m_major_os_version (UINT32_MAX), 242 m_minor_os_version (UINT32_MAX), 243 m_update_os_version (UINT32_MAX), 244 m_system_arch(), 245 m_uid_map_mutex (Mutex::eMutexTypeNormal), 246 m_gid_map_mutex (Mutex::eMutexTypeNormal), 247 m_uid_map(), 248 m_gid_map(), 249 m_max_uid_name_len (0), 250 m_max_gid_name_len (0) 251 { 252 Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_OBJECT)); 253 if (log) 254 log->Printf ("%p Platform::Platform()", this); 255 } 256 257 //------------------------------------------------------------------ 258 /// Destructor. 259 /// 260 /// The destructor is virtual since this class is designed to be 261 /// inherited from by the plug-in instance. 262 //------------------------------------------------------------------ 263 Platform::~Platform() 264 { 265 Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_OBJECT)); 266 if (log) 267 log->Printf ("%p Platform::~Platform()", this); 268 } 269 270 void 271 Platform::GetStatus (Stream &strm) 272 { 273 uint32_t major = UINT32_MAX; 274 uint32_t minor = UINT32_MAX; 275 uint32_t update = UINT32_MAX; 276 std::string s; 277 strm.Printf (" Platform: %s\n", GetPluginName().GetCString()); 278 279 ArchSpec arch (GetSystemArchitecture()); 280 if (arch.IsValid()) 281 { 282 if (!arch.GetTriple().str().empty()) 283 strm.Printf(" Triple: %s\n", arch.GetTriple().str().c_str()); 284 } 285 286 if (GetOSVersion(major, minor, update)) 287 { 288 strm.Printf("OS Version: %u", major); 289 if (minor != UINT32_MAX) 290 strm.Printf(".%u", minor); 291 if (update != UINT32_MAX) 292 strm.Printf(".%u", update); 293 294 if (GetOSBuildString (s)) 295 strm.Printf(" (%s)", s.c_str()); 296 297 strm.EOL(); 298 } 299 300 if (GetOSKernelDescription (s)) 301 strm.Printf(" Kernel: %s\n", s.c_str()); 302 303 if (IsHost()) 304 { 305 strm.Printf(" Hostname: %s\n", GetHostname()); 306 } 307 else 308 { 309 const bool is_connected = IsConnected(); 310 if (is_connected) 311 strm.Printf(" Hostname: %s\n", GetHostname()); 312 strm.Printf(" Connected: %s\n", is_connected ? "yes" : "no"); 313 } 314 } 315 316 317 bool 318 Platform::GetOSVersion (uint32_t &major, 319 uint32_t &minor, 320 uint32_t &update) 321 { 322 bool success = m_major_os_version != UINT32_MAX; 323 if (IsHost()) 324 { 325 if (!success) 326 { 327 // We have a local host platform 328 success = Host::GetOSVersion (m_major_os_version, 329 m_minor_os_version, 330 m_update_os_version); 331 m_os_version_set_while_connected = success; 332 } 333 } 334 else 335 { 336 // We have a remote platform. We can only fetch the remote 337 // OS version if we are connected, and we don't want to do it 338 // more than once. 339 340 const bool is_connected = IsConnected(); 341 342 bool fetch = false; 343 if (success) 344 { 345 // We have valid OS version info, check to make sure it wasn't 346 // manually set prior to connecting. If it was manually set prior 347 // to connecting, then lets fetch the actual OS version info 348 // if we are now connected. 349 if (is_connected && !m_os_version_set_while_connected) 350 fetch = true; 351 } 352 else 353 { 354 // We don't have valid OS version info, fetch it if we are connected 355 fetch = is_connected; 356 } 357 358 if (fetch) 359 { 360 success = GetRemoteOSVersion (); 361 m_os_version_set_while_connected = success; 362 } 363 } 364 365 if (success) 366 { 367 major = m_major_os_version; 368 minor = m_minor_os_version; 369 update = m_update_os_version; 370 } 371 return success; 372 } 373 374 bool 375 Platform::GetOSBuildString (std::string &s) 376 { 377 if (IsHost()) 378 return Host::GetOSBuildString (s); 379 else 380 return GetRemoteOSBuildString (s); 381 } 382 383 bool 384 Platform::GetOSKernelDescription (std::string &s) 385 { 386 if (IsHost()) 387 return Host::GetOSKernelDescription (s); 388 else 389 return GetRemoteOSKernelDescription (s); 390 } 391 392 ConstString 393 Platform::GetName () 394 { 395 const char *name = GetHostname(); 396 if (name == NULL || name[0] == '\0') 397 return GetPluginName(); 398 return ConstString (name); 399 } 400 401 const char * 402 Platform::GetHostname () 403 { 404 if (IsHost()) 405 return "localhost"; 406 407 if (m_name.empty()) 408 return NULL; 409 return m_name.c_str(); 410 } 411 412 const char * 413 Platform::GetUserName (uint32_t uid) 414 { 415 const char *user_name = GetCachedUserName(uid); 416 if (user_name) 417 return user_name; 418 if (IsHost()) 419 { 420 std::string name; 421 if (Host::GetUserName(uid, name)) 422 return SetCachedUserName (uid, name.c_str(), name.size()); 423 } 424 return NULL; 425 } 426 427 const char * 428 Platform::GetGroupName (uint32_t gid) 429 { 430 const char *group_name = GetCachedGroupName(gid); 431 if (group_name) 432 return group_name; 433 if (IsHost()) 434 { 435 std::string name; 436 if (Host::GetGroupName(gid, name)) 437 return SetCachedGroupName (gid, name.c_str(), name.size()); 438 } 439 return NULL; 440 } 441 442 bool 443 Platform::SetOSVersion (uint32_t major, 444 uint32_t minor, 445 uint32_t update) 446 { 447 if (IsHost()) 448 { 449 // We don't need anyone setting the OS version for the host platform, 450 // we should be able to figure it out by calling Host::GetOSVersion(...). 451 return false; 452 } 453 else 454 { 455 // We have a remote platform, allow setting the target OS version if 456 // we aren't connected, since if we are connected, we should be able to 457 // request the remote OS version from the connected platform. 458 if (IsConnected()) 459 return false; 460 else 461 { 462 // We aren't connected and we might want to set the OS version 463 // ahead of time before we connect so we can peruse files and 464 // use a local SDK or PDK cache of support files to disassemble 465 // or do other things. 466 m_major_os_version = major; 467 m_minor_os_version = minor; 468 m_update_os_version = update; 469 return true; 470 } 471 } 472 return false; 473 } 474 475 476 Error 477 Platform::ResolveExecutable (const FileSpec &exe_file, 478 const ArchSpec &exe_arch, 479 lldb::ModuleSP &exe_module_sp, 480 const FileSpecList *module_search_paths_ptr) 481 { 482 Error error; 483 if (exe_file.Exists()) 484 { 485 ModuleSpec module_spec (exe_file, exe_arch); 486 if (module_spec.GetArchitecture().IsValid()) 487 { 488 error = ModuleList::GetSharedModule (module_spec, 489 exe_module_sp, 490 module_search_paths_ptr, 491 NULL, 492 NULL); 493 } 494 else 495 { 496 // No valid architecture was specified, ask the platform for 497 // the architectures that we should be using (in the correct order) 498 // and see if we can find a match that way 499 for (uint32_t idx = 0; GetSupportedArchitectureAtIndex (idx, module_spec.GetArchitecture()); ++idx) 500 { 501 error = ModuleList::GetSharedModule (module_spec, 502 exe_module_sp, 503 module_search_paths_ptr, 504 NULL, 505 NULL); 506 // Did we find an executable using one of the 507 if (error.Success() && exe_module_sp) 508 break; 509 } 510 } 511 } 512 else 513 { 514 error.SetErrorStringWithFormat ("'%s' does not exist", 515 exe_file.GetPath().c_str()); 516 } 517 return error; 518 } 519 520 Error 521 Platform::ResolveSymbolFile (Target &target, 522 const ModuleSpec &sym_spec, 523 FileSpec &sym_file) 524 { 525 Error error; 526 if (sym_spec.GetSymbolFileSpec().Exists()) 527 sym_file = sym_spec.GetSymbolFileSpec(); 528 else 529 error.SetErrorString("unable to resolve symbol file"); 530 return error; 531 532 } 533 534 535 536 bool 537 Platform::ResolveRemotePath (const FileSpec &platform_path, 538 FileSpec &resolved_platform_path) 539 { 540 resolved_platform_path = platform_path; 541 return resolved_platform_path.ResolvePath(); 542 } 543 544 545 const ArchSpec & 546 Platform::GetSystemArchitecture() 547 { 548 if (IsHost()) 549 { 550 if (!m_system_arch.IsValid()) 551 { 552 // We have a local host platform 553 m_system_arch = Host::GetArchitecture(); 554 m_system_arch_set_while_connected = m_system_arch.IsValid(); 555 } 556 } 557 else 558 { 559 // We have a remote platform. We can only fetch the remote 560 // system architecture if we are connected, and we don't want to do it 561 // more than once. 562 563 const bool is_connected = IsConnected(); 564 565 bool fetch = false; 566 if (m_system_arch.IsValid()) 567 { 568 // We have valid OS version info, check to make sure it wasn't 569 // manually set prior to connecting. If it was manually set prior 570 // to connecting, then lets fetch the actual OS version info 571 // if we are now connected. 572 if (is_connected && !m_system_arch_set_while_connected) 573 fetch = true; 574 } 575 else 576 { 577 // We don't have valid OS version info, fetch it if we are connected 578 fetch = is_connected; 579 } 580 581 if (fetch) 582 { 583 m_system_arch = GetRemoteSystemArchitecture (); 584 m_system_arch_set_while_connected = m_system_arch.IsValid(); 585 } 586 } 587 return m_system_arch; 588 } 589 590 591 Error 592 Platform::ConnectRemote (Args& args) 593 { 594 Error error; 595 if (IsHost()) 596 error.SetErrorStringWithFormat ("The currently selected platform (%s) is the host platform and is always connected.", GetPluginName().GetCString()); 597 else 598 error.SetErrorStringWithFormat ("Platform::ConnectRemote() is not supported by %s", GetPluginName().GetCString()); 599 return error; 600 } 601 602 Error 603 Platform::DisconnectRemote () 604 { 605 Error error; 606 if (IsHost()) 607 error.SetErrorStringWithFormat ("The currently selected platform (%s) is the host platform and is always connected.", GetPluginName().GetCString()); 608 else 609 error.SetErrorStringWithFormat ("Platform::DisconnectRemote() is not supported by %s", GetPluginName().GetCString()); 610 return error; 611 } 612 613 bool 614 Platform::GetProcessInfo (lldb::pid_t pid, ProcessInstanceInfo &process_info) 615 { 616 // Take care of the host case so that each subclass can just 617 // call this function to get the host functionality. 618 if (IsHost()) 619 return Host::GetProcessInfo (pid, process_info); 620 return false; 621 } 622 623 uint32_t 624 Platform::FindProcesses (const ProcessInstanceInfoMatch &match_info, 625 ProcessInstanceInfoList &process_infos) 626 { 627 // Take care of the host case so that each subclass can just 628 // call this function to get the host functionality. 629 uint32_t match_count = 0; 630 if (IsHost()) 631 match_count = Host::FindProcesses (match_info, process_infos); 632 return match_count; 633 } 634 635 636 Error 637 Platform::LaunchProcess (ProcessLaunchInfo &launch_info) 638 { 639 Error error; 640 // Take care of the host case so that each subclass can just 641 // call this function to get the host functionality. 642 if (IsHost()) 643 { 644 if (::getenv ("LLDB_LAUNCH_FLAG_LAUNCH_IN_TTY")) 645 launch_info.GetFlags().Set (eLaunchFlagLaunchInTTY); 646 647 if (launch_info.GetFlags().Test (eLaunchFlagLaunchInShell)) 648 { 649 const bool is_localhost = true; 650 const bool will_debug = launch_info.GetFlags().Test(eLaunchFlagDebug); 651 const bool first_arg_is_full_shell_command = false; 652 if (!launch_info.ConvertArgumentsForLaunchingInShell (error, 653 is_localhost, 654 will_debug, 655 first_arg_is_full_shell_command)) 656 return error; 657 } 658 659 error = Host::LaunchProcess (launch_info); 660 } 661 else 662 error.SetErrorString ("base lldb_private::Platform class can't launch remote processes"); 663 return error; 664 } 665 666 lldb::ProcessSP 667 Platform::DebugProcess (ProcessLaunchInfo &launch_info, 668 Debugger &debugger, 669 Target *target, // Can be NULL, if NULL create a new target, else use existing one 670 Listener &listener, 671 Error &error) 672 { 673 ProcessSP process_sp; 674 // Make sure we stop at the entry point 675 launch_info.GetFlags ().Set (eLaunchFlagDebug); 676 // We always launch the process we are going to debug in a separate process 677 // group, since then we can handle ^C interrupts ourselves w/o having to worry 678 // about the target getting them as well. 679 launch_info.SetLaunchInSeparateProcessGroup(true); 680 681 error = LaunchProcess (launch_info); 682 if (error.Success()) 683 { 684 if (launch_info.GetProcessID() != LLDB_INVALID_PROCESS_ID) 685 { 686 ProcessAttachInfo attach_info (launch_info); 687 process_sp = Attach (attach_info, debugger, target, listener, error); 688 if (process_sp) 689 { 690 // Since we attached to the process, it will think it needs to detach 691 // if the process object just goes away without an explicit call to 692 // Process::Kill() or Process::Detach(), so let it know to kill the 693 // process if this happens. 694 process_sp->SetShouldDetach (false); 695 696 // If we didn't have any file actions, the pseudo terminal might 697 // have been used where the slave side was given as the file to 698 // open for stdin/out/err after we have already opened the master 699 // so we can read/write stdin/out/err. 700 int pty_fd = launch_info.GetPTY().ReleaseMasterFileDescriptor(); 701 if (pty_fd != lldb_utility::PseudoTerminal::invalid_fd) 702 { 703 process_sp->SetSTDIOFileDescriptor(pty_fd); 704 } 705 } 706 } 707 } 708 return process_sp; 709 } 710 711 712 lldb::PlatformSP 713 Platform::GetPlatformForArchitecture (const ArchSpec &arch, ArchSpec *platform_arch_ptr) 714 { 715 lldb::PlatformSP platform_sp; 716 Error error; 717 if (arch.IsValid()) 718 platform_sp = Platform::Create (arch, platform_arch_ptr, error); 719 return platform_sp; 720 } 721 722 723 //------------------------------------------------------------------ 724 /// Lets a platform answer if it is compatible with a given 725 /// architecture and the target triple contained within. 726 //------------------------------------------------------------------ 727 bool 728 Platform::IsCompatibleArchitecture (const ArchSpec &arch, bool exact_arch_match, ArchSpec *compatible_arch_ptr) 729 { 730 // If the architecture is invalid, we must answer true... 731 if (arch.IsValid()) 732 { 733 ArchSpec platform_arch; 734 // Try for an exact architecture match first. 735 if (exact_arch_match) 736 { 737 for (uint32_t arch_idx=0; GetSupportedArchitectureAtIndex (arch_idx, platform_arch); ++arch_idx) 738 { 739 if (arch.IsExactMatch(platform_arch)) 740 { 741 if (compatible_arch_ptr) 742 *compatible_arch_ptr = platform_arch; 743 return true; 744 } 745 } 746 } 747 else 748 { 749 for (uint32_t arch_idx=0; GetSupportedArchitectureAtIndex (arch_idx, platform_arch); ++arch_idx) 750 { 751 if (arch.IsCompatibleMatch(platform_arch)) 752 { 753 if (compatible_arch_ptr) 754 *compatible_arch_ptr = platform_arch; 755 return true; 756 } 757 } 758 } 759 } 760 if (compatible_arch_ptr) 761 compatible_arch_ptr->Clear(); 762 return false; 763 764 } 765 766 767 lldb::BreakpointSP 768 Platform::SetThreadCreationBreakpoint (lldb_private::Target &target) 769 { 770 return lldb::BreakpointSP(); 771 } 772 773 size_t 774 Platform::GetEnvironment (StringList &environment) 775 { 776 environment.Clear(); 777 return false; 778 } 779 780