Platform.h revision 527154d8e532f27f25af226c9e1dac607c48b5d1
1//===-- Platform.h ----------------------------------------------*- 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#ifndef liblldb_Platform_h_ 11#define liblldb_Platform_h_ 12 13// C Includes 14// C++ Includes 15#include <map> 16#include <string> 17#include <vector> 18 19// Other libraries and framework includes 20// Project includes 21#include "lldb/lldb-public.h" 22#include "lldb/Core/ArchSpec.h" 23#include "lldb/Core/ConstString.h" 24#include "lldb/Core/PluginInterface.h" 25#include "lldb/Host/Mutex.h" 26 27namespace lldb_private { 28 29 //---------------------------------------------------------------------- 30 /// @class Platform Platform.h "lldb/Target/Platform.h" 31 /// @brief A plug-in interface definition class for debug platform that 32 /// includes many platform abilities such as: 33 /// @li getting platform information such as supported architectures, 34 /// supported binary file formats and more 35 /// @li launching new processes 36 /// @li attaching to existing processes 37 /// @li download/upload files 38 /// @li execute shell commands 39 /// @li listing and getting info for existing processes 40 /// @li attaching and possibly debugging the platform's kernel 41 //---------------------------------------------------------------------- 42 class Platform : public PluginInterface 43 { 44 public: 45 46 //------------------------------------------------------------------ 47 /// Get the native host platform plug-in. 48 /// 49 /// There should only be one of these for each host that LLDB runs 50 /// upon that should be statically compiled in and registered using 51 /// preprocessor macros or other similar build mechanisms in a 52 /// PlatformSubclass::Initialize() function. 53 /// 54 /// This platform will be used as the default platform when launching 55 /// or attaching to processes unless another platform is specified. 56 //------------------------------------------------------------------ 57 static lldb::PlatformSP 58 GetDefaultPlatform (); 59 60 static const char * 61 GetHostPlatformName (); 62 63 static void 64 SetDefaultPlatform (const lldb::PlatformSP &platform_sp); 65 66 static lldb::PlatformSP 67 Create (const char *platform_name, Error &error); 68 69 static uint32_t 70 GetNumConnectedRemotePlatforms (); 71 72 static lldb::PlatformSP 73 GetConnectedRemotePlatformAtIndex (uint32_t idx); 74 75 //------------------------------------------------------------------ 76 /// Default Constructor 77 //------------------------------------------------------------------ 78 Platform (bool is_host_platform); 79 80 //------------------------------------------------------------------ 81 /// Destructor. 82 /// 83 /// The destructor is virtual since this class is designed to be 84 /// inherited from by the plug-in instance. 85 //------------------------------------------------------------------ 86 virtual 87 ~Platform(); 88 89 //------------------------------------------------------------------ 90 /// Set the target's executable based off of the existing 91 /// architecture information in \a target given a path to an 92 /// executable \a exe_file. 93 /// 94 /// Each platform knows the architectures that it supports and can 95 /// select the correct architecture slice within \a exe_file by 96 /// inspecting the architecture in \a target. If the target had an 97 /// architecture specified, then in can try and obey that request 98 /// and optionally fail if the architecture doesn't match up. 99 /// If no architecture is specified, the platform should select the 100 /// default architecture from \a exe_file. Any application bundles 101 /// or executable wrappers can also be inspected for the actual 102 /// application binary within the bundle that should be used. 103 /// 104 /// @return 105 /// Returns \b true if this Platform plug-in was able to find 106 /// a suitable executable, \b false otherwise. 107 //------------------------------------------------------------------ 108 virtual Error 109 ResolveExecutable (const FileSpec &exe_file, 110 const ArchSpec &arch, 111 lldb::ModuleSP &module_sp); 112 113 //------------------------------------------------------------------ 114 /// Resolves the FileSpec to a (possibly) remote path. Remote 115 /// platforms must override this to resolve to a path on the remote 116 /// side. 117 //------------------------------------------------------------------ 118 virtual bool 119 ResolveRemotePath (const FileSpec &platform_path, 120 FileSpec &resolved_platform_path); 121 122 bool 123 GetOSVersion (uint32_t &major, 124 uint32_t &minor, 125 uint32_t &update); 126 127 bool 128 SetOSVersion (uint32_t major, 129 uint32_t minor, 130 uint32_t update); 131 132 bool 133 GetOSBuildString (std::string &s); 134 135 bool 136 GetOSKernelDescription (std::string &s); 137 138 // Returns the the hostname if we are connected, else the short plugin 139 // name. 140 const char * 141 GetName (); 142 143 virtual const char * 144 GetHostname (); 145 146 virtual const char * 147 GetDescription () = 0; 148 149 //------------------------------------------------------------------ 150 /// Report the current status for this platform. 151 /// 152 /// The returned string usually involves returning the OS version 153 /// (if available), and any SDK directory that might be being used 154 /// for local file caching, and if connected a quick blurb about 155 /// what this platform is connected to. 156 //------------------------------------------------------------------ 157 virtual void 158 GetStatus (Stream &strm); 159 160 //------------------------------------------------------------------ 161 // Subclasses must be able to fetch the current OS version 162 // 163 // Remote classes must be connected for this to succeed. Local 164 // subclasses don't need to override this function as it will just 165 // call the Host::GetOSVersion(). 166 //------------------------------------------------------------------ 167 virtual bool 168 GetRemoteOSVersion () 169 { 170 return false; 171 } 172 173 virtual bool 174 GetRemoteOSBuildString (std::string &s) 175 { 176 s.clear(); 177 return false; 178 } 179 180 virtual bool 181 GetRemoteOSKernelDescription (std::string &s) 182 { 183 s.clear(); 184 return false; 185 } 186 187 // Remote Platform subclasses need to override this function 188 virtual ArchSpec 189 GetRemoteSystemArchitecture () 190 { 191 return ArchSpec(); // Return an invalid architecture 192 } 193 194 virtual const char * 195 GetUserName (uint32_t uid); 196 197 virtual const char * 198 GetGroupName (uint32_t gid); 199 200 //------------------------------------------------------------------ 201 /// Locate a file for a platform. 202 /// 203 /// The default implementation of this function will return the same 204 /// file patch in \a local_file as was in \a platform_file. 205 /// 206 /// @param[in] platform_file 207 /// The platform file path to locate and cache locally. 208 /// 209 /// @param[in] uuid_ptr 210 /// If we know the exact UUID of the file we are looking for, it 211 /// can be specified. If it is not specified, we might now know 212 /// the exact file. The UUID is usually some sort of MD5 checksum 213 /// for the file and is sometimes known by dynamic linkers/loaders. 214 /// If the UUID is known, it is best to supply it to platform 215 /// file queries to ensure we are finding the correct file, not 216 /// just a file at the correct path. 217 /// 218 /// @param[out] local_file 219 /// A locally cached version of the platform file. For platforms 220 /// that describe the current host computer, this will just be 221 /// the same file. For remote platforms, this file might come from 222 /// and SDK directory, or might need to be sync'ed over to the 223 /// current machine for efficient debugging access. 224 /// 225 /// @return 226 /// An error object. 227 //------------------------------------------------------------------ 228 virtual Error 229 GetFile (const FileSpec &platform_file, 230 const UUID *uuid_ptr, 231 FileSpec &local_file); 232 233 virtual Error 234 GetSharedModule (const FileSpec &platform_file, 235 const ArchSpec &arch, 236 const UUID *uuid_ptr, 237 const ConstString *object_name_ptr, 238 off_t object_offset, 239 lldb::ModuleSP &module_sp, 240 lldb::ModuleSP *old_module_sp_ptr, 241 bool *did_create_ptr); 242 243 virtual Error 244 ConnectRemote (Args& args); 245 246 virtual Error 247 DisconnectRemote (); 248 249 //------------------------------------------------------------------ 250 /// Get the platform's supported architectures in the order in which 251 /// they should be searched. 252 /// 253 /// @param[in] idx 254 /// A zero based architecture index 255 /// 256 /// @param[out] arch 257 /// A copy of the archgitecture at index if the return value is 258 /// \b true. 259 /// 260 /// @return 261 /// \b true if \a arch was filled in and is valid, \b false 262 /// otherwise. 263 //------------------------------------------------------------------ 264 virtual bool 265 GetSupportedArchitectureAtIndex (uint32_t idx, ArchSpec &arch) = 0; 266 267 virtual size_t 268 GetSoftwareBreakpointTrapOpcode (Target &target, 269 BreakpointSite *bp_site) = 0; 270 271 //------------------------------------------------------------------ 272 /// Launch a new process on a platform, not necessarily for 273 /// debugging, it could be just for running the process. 274 //------------------------------------------------------------------ 275 virtual Error 276 LaunchProcess (ProcessLaunchInfo &launch_info); 277 278 //------------------------------------------------------------------ 279 /// Subclasses should NOT need to implement this function as it uses 280 /// the Platform::LaunchProcess() followed by Platform::Attach () 281 //------------------------------------------------------------------ 282 lldb::ProcessSP 283 DebugProcess (ProcessLaunchInfo &launch_info, 284 Debugger &debugger, 285 Target *target, // Can be NULL, if NULL create a new target, else use existing one 286 Listener &listener, 287 Error &error); 288 289 //------------------------------------------------------------------ 290 /// Attach to an existing process using a process ID. 291 /// 292 /// Each platform subclass needs to implement this function and 293 /// attempt to attach to the process with the process ID of \a pid. 294 /// The platform subclass should return an appropriate ProcessSP 295 /// subclass that is attached to the process, or an empty shared 296 /// pointer with an appriopriate error. 297 /// 298 /// @param[in] pid 299 /// The process ID that we should attempt to attach to. 300 /// 301 /// @return 302 /// An appropriate ProcessSP containing a valid shared pointer 303 /// to the default Process subclass for the platform that is 304 /// attached to the process, or an empty shared pointer with an 305 /// appriopriate error fill into the \a error object. 306 //------------------------------------------------------------------ 307 virtual lldb::ProcessSP 308 Attach (ProcessAttachInfo &attach_info, 309 Debugger &debugger, 310 Target *target, // Can be NULL, if NULL create a new target, else use existing one 311 Listener &listener, 312 Error &error) = 0; 313 314 //------------------------------------------------------------------ 315 /// Attach to an existing process by process name. 316 /// 317 /// This function is not meant to be overridden by Process 318 /// subclasses. It will first call 319 /// Process::WillAttach (const char *) and if that returns \b 320 /// true, Process::DoAttach (const char *) will be called to 321 /// actually do the attach. If DoAttach returns \b true, then 322 /// Process::DidAttach() will be called. 323 /// 324 /// @param[in] process_name 325 /// A process name to match against the current process list. 326 /// 327 /// @return 328 /// Returns \a pid if attaching was successful, or 329 /// LLDB_INVALID_PROCESS_ID if attaching fails. 330 //------------------------------------------------------------------ 331// virtual lldb::ProcessSP 332// Attach (const char *process_name, 333// bool wait_for_launch, 334// Error &error) = 0; 335 336 //------------------------------------------------------------------ 337 // The base class Platform will take care of the host platform. 338 // Subclasses will need to fill in the remote case. 339 //------------------------------------------------------------------ 340 virtual uint32_t 341 FindProcesses (const ProcessInstanceInfoMatch &match_info, 342 ProcessInstanceInfoList &proc_infos); 343 344 virtual bool 345 GetProcessInfo (lldb::pid_t pid, ProcessInstanceInfo &proc_info); 346 347 const std::string & 348 GetRemoteURL () const 349 { 350 return m_remote_url; 351 } 352 353 bool 354 IsHost () const 355 { 356 return m_is_host; // Is this the default host platform? 357 } 358 359 bool 360 IsRemote () const 361 { 362 return !m_is_host; 363 } 364 365 virtual bool 366 IsConnected () const 367 { 368 // Remote subclasses should override this function 369 return IsHost(); 370 } 371 372 const ArchSpec & 373 GetSystemArchitecture(); 374 375 void 376 SetSystemArchitecture (const ArchSpec &arch) 377 { 378 m_system_arch = arch; 379 if (IsHost()) 380 m_os_version_set_while_connected = m_system_arch.IsValid(); 381 } 382 383 // Used for column widths 384 uint32_t 385 GetMaxUserIDNameLength() const 386 { 387 return m_max_uid_name_len; 388 } 389 // Used for column widths 390 uint32_t 391 GetMaxGroupIDNameLength() const 392 { 393 return m_max_gid_name_len; 394 } 395 396 const ConstString & 397 GetSDKRootDirectory () const 398 { 399 return m_sdk_sysroot; 400 } 401 402 void 403 SetSDKRootDirectory (const ConstString &dir) 404 { 405 m_sdk_sysroot = dir; 406 } 407 408 const ConstString & 409 GetSDKBuild () const 410 { 411 return m_sdk_build; 412 } 413 414 void 415 SetSDKBuild (const ConstString &sdk_build) 416 { 417 m_sdk_build = sdk_build; 418 } 419 420 // There may be modules that we don't want to find by default for operations like "setting breakpoint by name". 421 // The platform will return "true" from this call if the passed in module happens to be one of these. 422 423 virtual bool 424 ModuleIsExcludedForNonModuleSpecificSearches (Target &target, const lldb::ModuleSP &module_sp) 425 { 426 return false; 427 } 428 429 protected: 430 bool m_is_host; 431 // Set to true when we are able to actually set the OS version while 432 // being connected. For remote platforms, we might set the version ahead 433 // of time before we actually connect and this version might change when 434 // we actually connect to a remote platform. For the host platform this 435 // will be set to the once we call Host::GetOSVersion(). 436 bool m_os_version_set_while_connected; 437 bool m_system_arch_set_while_connected; 438 ConstString m_sdk_sysroot; // the root location of where the SDK files are all located 439 ConstString m_sdk_build; 440 std::string m_remote_url; 441 std::string m_name; 442 uint32_t m_major_os_version; 443 uint32_t m_minor_os_version; 444 uint32_t m_update_os_version; 445 ArchSpec m_system_arch; // The architecture of the kernel or the remote platform 446 typedef std::map<uint32_t, ConstString> IDToNameMap; 447 Mutex m_uid_map_mutex; 448 Mutex m_gid_map_mutex; 449 IDToNameMap m_uid_map; 450 IDToNameMap m_gid_map; 451 uint32_t m_max_uid_name_len; 452 uint32_t m_max_gid_name_len; 453 454 const char * 455 GetCachedUserName (uint32_t uid) 456 { 457 Mutex::Locker locker (m_uid_map_mutex); 458 IDToNameMap::iterator pos = m_uid_map.find (uid); 459 if (pos != m_uid_map.end()) 460 { 461 // return the empty string if our string is NULL 462 // so we can tell when things were in the negative 463 // cached (didn't find a valid user name, don't keep 464 // trying) 465 return pos->second.AsCString(""); 466 } 467 return NULL; 468 } 469 470 const char * 471 SetCachedUserName (uint32_t uid, const char *name, size_t name_len) 472 { 473 Mutex::Locker locker (m_uid_map_mutex); 474 ConstString const_name (name); 475 m_uid_map[uid] = const_name; 476 if (m_max_uid_name_len < name_len) 477 m_max_uid_name_len = name_len; 478 // Const strings lives forever in our const string pool, so we can return the const char * 479 return const_name.GetCString(); 480 } 481 482 void 483 SetUserNameNotFound (uint32_t uid) 484 { 485 Mutex::Locker locker (m_uid_map_mutex); 486 m_uid_map[uid] = ConstString(); 487 } 488 489 490 void 491 ClearCachedUserNames () 492 { 493 Mutex::Locker locker (m_uid_map_mutex); 494 m_uid_map.clear(); 495 } 496 497 const char * 498 GetCachedGroupName (uint32_t gid) 499 { 500 Mutex::Locker locker (m_gid_map_mutex); 501 IDToNameMap::iterator pos = m_gid_map.find (gid); 502 if (pos != m_gid_map.end()) 503 { 504 // return the empty string if our string is NULL 505 // so we can tell when things were in the negative 506 // cached (didn't find a valid group name, don't keep 507 // trying) 508 return pos->second.AsCString(""); 509 } 510 return NULL; 511 } 512 513 const char * 514 SetCachedGroupName (uint32_t gid, const char *name, size_t name_len) 515 { 516 Mutex::Locker locker (m_gid_map_mutex); 517 ConstString const_name (name); 518 m_gid_map[gid] = const_name; 519 if (m_max_gid_name_len < name_len) 520 m_max_gid_name_len = name_len; 521 // Const strings lives forever in our const string pool, so we can return the const char * 522 return const_name.GetCString(); 523 } 524 525 void 526 SetGroupNameNotFound (uint32_t gid) 527 { 528 Mutex::Locker locker (m_gid_map_mutex); 529 m_gid_map[gid] = ConstString(); 530 } 531 532 void 533 ClearCachedGroupNames () 534 { 535 Mutex::Locker locker (m_gid_map_mutex); 536 m_gid_map.clear(); 537 } 538 539 private: 540 DISALLOW_COPY_AND_ASSIGN (Platform); 541 }; 542 543 544 class PlatformList 545 { 546 public: 547 PlatformList() : 548 m_mutex (Mutex::eMutexTypeRecursive), 549 m_platforms (), 550 m_selected_platform_sp() 551 { 552 } 553 554 ~PlatformList() 555 { 556 } 557 558 void 559 Append (const lldb::PlatformSP &platform_sp, bool set_selected) 560 { 561 Mutex::Locker locker (m_mutex); 562 m_platforms.push_back (platform_sp); 563 if (set_selected) 564 m_selected_platform_sp = m_platforms.back(); 565 } 566 567 size_t 568 GetSize() 569 { 570 Mutex::Locker locker (m_mutex); 571 return m_platforms.size(); 572 } 573 574 lldb::PlatformSP 575 GetAtIndex (uint32_t idx) 576 { 577 lldb::PlatformSP platform_sp; 578 { 579 Mutex::Locker locker (m_mutex); 580 if (idx < m_platforms.size()) 581 platform_sp = m_platforms[idx]; 582 } 583 return platform_sp; 584 } 585 586 //------------------------------------------------------------------ 587 /// Select the active platform. 588 /// 589 /// In order to debug remotely, other platform's can be remotely 590 /// connected to and set as the selected platform for any subsequent 591 /// debugging. This allows connection to remote targets and allows 592 /// the ability to discover process info, launch and attach to remote 593 /// processes. 594 //------------------------------------------------------------------ 595 lldb::PlatformSP 596 GetSelectedPlatform () 597 { 598 Mutex::Locker locker (m_mutex); 599 if (!m_selected_platform_sp && !m_platforms.empty()) 600 m_selected_platform_sp = m_platforms.front(); 601 602 return m_selected_platform_sp; 603 } 604 605 void 606 SetSelectedPlatform (const lldb::PlatformSP &platform_sp) 607 { 608 if (platform_sp) 609 { 610 Mutex::Locker locker (m_mutex); 611 const size_t num_platforms = m_platforms.size(); 612 for (size_t idx=0; idx<num_platforms; ++idx) 613 { 614 if (m_platforms[idx].get() == platform_sp.get()) 615 { 616 m_selected_platform_sp = m_platforms[idx]; 617 return; 618 } 619 } 620 m_platforms.push_back (platform_sp); 621 m_selected_platform_sp = m_platforms.back(); 622 } 623 } 624 625 protected: 626 typedef std::vector<lldb::PlatformSP> collection; 627 mutable Mutex m_mutex; 628 collection m_platforms; 629 lldb::PlatformSP m_selected_platform_sp; 630 631 private: 632 DISALLOW_COPY_AND_ASSIGN (PlatformList); 633 }; 634} // namespace lldb_private 635 636#endif // liblldb_Platform_h_ 637