Platform.h revision f2bf870da5819415d52bc7da98c151cedf1e6dff
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 (lldb::pid_t pid, 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 421 protected: 422 bool m_is_host; 423 // Set to true when we are able to actually set the OS version while 424 // being connected. For remote platforms, we might set the version ahead 425 // of time before we actually connect and this version might change when 426 // we actually connect to a remote platform. For the host platform this 427 // will be set to the once we call Host::GetOSVersion(). 428 bool m_os_version_set_while_connected; 429 bool m_system_arch_set_while_connected; 430 ConstString m_sdk_sysroot; // the root location of where the SDK files are all located 431 ConstString m_sdk_build; 432 std::string m_remote_url; 433 std::string m_name; 434 uint32_t m_major_os_version; 435 uint32_t m_minor_os_version; 436 uint32_t m_update_os_version; 437 ArchSpec m_system_arch; // The architecture of the kernel or the remote platform 438 typedef std::map<uint32_t, ConstString> IDToNameMap; 439 Mutex m_uid_map_mutex; 440 Mutex m_gid_map_mutex; 441 IDToNameMap m_uid_map; 442 IDToNameMap m_gid_map; 443 uint32_t m_max_uid_name_len; 444 uint32_t m_max_gid_name_len; 445 446 const char * 447 GetCachedUserName (uint32_t uid) 448 { 449 Mutex::Locker locker (m_uid_map_mutex); 450 IDToNameMap::iterator pos = m_uid_map.find (uid); 451 if (pos != m_uid_map.end()) 452 { 453 // return the empty string if our string is NULL 454 // so we can tell when things were in the negative 455 // cached (didn't find a valid user name, don't keep 456 // trying) 457 return pos->second.AsCString(""); 458 } 459 return NULL; 460 } 461 462 const char * 463 SetCachedUserName (uint32_t uid, const char *name, size_t name_len) 464 { 465 Mutex::Locker locker (m_uid_map_mutex); 466 ConstString const_name (name); 467 m_uid_map[uid] = const_name; 468 if (m_max_uid_name_len < name_len) 469 m_max_uid_name_len = name_len; 470 // Const strings lives forever in our const string pool, so we can return the const char * 471 return const_name.GetCString(); 472 } 473 474 void 475 SetUserNameNotFound (uint32_t uid) 476 { 477 Mutex::Locker locker (m_uid_map_mutex); 478 m_uid_map[uid] = ConstString(); 479 } 480 481 482 void 483 ClearCachedUserNames () 484 { 485 Mutex::Locker locker (m_uid_map_mutex); 486 m_uid_map.clear(); 487 } 488 489 const char * 490 GetCachedGroupName (uint32_t gid) 491 { 492 Mutex::Locker locker (m_gid_map_mutex); 493 IDToNameMap::iterator pos = m_gid_map.find (gid); 494 if (pos != m_gid_map.end()) 495 { 496 // return the empty string if our string is NULL 497 // so we can tell when things were in the negative 498 // cached (didn't find a valid group name, don't keep 499 // trying) 500 return pos->second.AsCString(""); 501 } 502 return NULL; 503 } 504 505 const char * 506 SetCachedGroupName (uint32_t gid, const char *name, size_t name_len) 507 { 508 Mutex::Locker locker (m_gid_map_mutex); 509 ConstString const_name (name); 510 m_gid_map[gid] = const_name; 511 if (m_max_gid_name_len < name_len) 512 m_max_gid_name_len = name_len; 513 // Const strings lives forever in our const string pool, so we can return the const char * 514 return const_name.GetCString(); 515 } 516 517 void 518 SetGroupNameNotFound (uint32_t gid) 519 { 520 Mutex::Locker locker (m_gid_map_mutex); 521 m_gid_map[gid] = ConstString(); 522 } 523 524 void 525 ClearCachedGroupNames () 526 { 527 Mutex::Locker locker (m_gid_map_mutex); 528 m_gid_map.clear(); 529 } 530 531 private: 532 DISALLOW_COPY_AND_ASSIGN (Platform); 533 }; 534 535 536 class PlatformList 537 { 538 public: 539 PlatformList() : 540 m_mutex (Mutex::eMutexTypeRecursive), 541 m_platforms (), 542 m_selected_platform_sp() 543 { 544 } 545 546 ~PlatformList() 547 { 548 } 549 550 void 551 Append (const lldb::PlatformSP &platform_sp, bool set_selected) 552 { 553 Mutex::Locker locker (m_mutex); 554 m_platforms.push_back (platform_sp); 555 if (set_selected) 556 m_selected_platform_sp = m_platforms.back(); 557 } 558 559 size_t 560 GetSize() 561 { 562 Mutex::Locker locker (m_mutex); 563 return m_platforms.size(); 564 } 565 566 lldb::PlatformSP 567 GetAtIndex (uint32_t idx) 568 { 569 lldb::PlatformSP platform_sp; 570 { 571 Mutex::Locker locker (m_mutex); 572 if (idx < m_platforms.size()) 573 platform_sp = m_platforms[idx]; 574 } 575 return platform_sp; 576 } 577 578 //------------------------------------------------------------------ 579 /// Select the active platform. 580 /// 581 /// In order to debug remotely, other platform's can be remotely 582 /// connected to and set as the selected platform for any subsequent 583 /// debugging. This allows connection to remote targets and allows 584 /// the ability to discover process info, launch and attach to remote 585 /// processes. 586 //------------------------------------------------------------------ 587 lldb::PlatformSP 588 GetSelectedPlatform () 589 { 590 Mutex::Locker locker (m_mutex); 591 if (!m_selected_platform_sp && !m_platforms.empty()) 592 m_selected_platform_sp = m_platforms.front(); 593 594 return m_selected_platform_sp; 595 } 596 597 void 598 SetSelectedPlatform (const lldb::PlatformSP &platform_sp) 599 { 600 if (platform_sp) 601 { 602 Mutex::Locker locker (m_mutex); 603 const size_t num_platforms = m_platforms.size(); 604 for (size_t idx=0; idx<num_platforms; ++idx) 605 { 606 if (m_platforms[idx].get() == platform_sp.get()) 607 { 608 m_selected_platform_sp = m_platforms[idx]; 609 return; 610 } 611 } 612 m_platforms.push_back (platform_sp); 613 m_selected_platform_sp = m_platforms.back(); 614 } 615 } 616 617 protected: 618 typedef std::vector<lldb::PlatformSP> collection; 619 mutable Mutex m_mutex; 620 collection m_platforms; 621 lldb::PlatformSP m_selected_platform_sp; 622 623 private: 624 DISALLOW_COPY_AND_ASSIGN (PlatformList); 625 }; 626} // namespace lldb_private 627 628#endif // liblldb_Platform_h_ 629