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