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