1254721Semaste//===-- Platform.cpp --------------------------------------------*- C++ -*-===// 2254721Semaste// 3254721Semaste// The LLVM Compiler Infrastructure 4254721Semaste// 5254721Semaste// This file is distributed under the University of Illinois Open Source 6254721Semaste// License. See LICENSE.TXT for details. 7254721Semaste// 8254721Semaste//===----------------------------------------------------------------------===// 9254721Semaste 10254721Semaste#include "lldb/Target/Platform.h" 11254721Semaste 12254721Semaste// C Includes 13254721Semaste// C++ Includes 14254721Semaste// Other libraries and framework includes 15254721Semaste// Project includes 16254721Semaste#include "lldb/Breakpoint/BreakpointIDList.h" 17254721Semaste#include "lldb/Core/Error.h" 18254721Semaste#include "lldb/Core/Log.h" 19254721Semaste#include "lldb/Core/ModuleSpec.h" 20254721Semaste#include "lldb/Core/PluginManager.h" 21254721Semaste#include "lldb/Host/FileSpec.h" 22254721Semaste#include "lldb/Host/Host.h" 23254721Semaste#include "lldb/Target/Process.h" 24254721Semaste#include "lldb/Target/Target.h" 25263363Semaste#include "lldb/Utility/Utils.h" 26254721Semaste 27254721Semasteusing namespace lldb; 28254721Semasteusing namespace lldb_private; 29254721Semaste 30254721Semaste// Use a singleton function for g_local_platform_sp to avoid init 31254721Semaste// constructors since LLDB is often part of a shared library 32254721Semastestatic PlatformSP& 33254721SemasteGetDefaultPlatformSP () 34254721Semaste{ 35254721Semaste static PlatformSP g_default_platform_sp; 36254721Semaste return g_default_platform_sp; 37254721Semaste} 38254721Semaste 39254721Semastestatic Mutex & 40254721SemasteGetConnectedPlatformListMutex () 41254721Semaste{ 42254721Semaste static Mutex g_remote_connected_platforms_mutex (Mutex::eMutexTypeRecursive); 43254721Semaste return g_remote_connected_platforms_mutex; 44254721Semaste} 45254721Semastestatic std::vector<PlatformSP> & 46254721SemasteGetConnectedPlatformList () 47254721Semaste{ 48254721Semaste static std::vector<PlatformSP> g_remote_connected_platforms; 49254721Semaste return g_remote_connected_platforms; 50254721Semaste} 51254721Semaste 52254721Semaste 53254721Semasteconst char * 54254721SemastePlatform::GetHostPlatformName () 55254721Semaste{ 56254721Semaste return "host"; 57254721Semaste} 58254721Semaste 59254721Semaste//------------------------------------------------------------------ 60254721Semaste/// Get the native host platform plug-in. 61254721Semaste/// 62254721Semaste/// There should only be one of these for each host that LLDB runs 63254721Semaste/// upon that should be statically compiled in and registered using 64254721Semaste/// preprocessor macros or other similar build mechanisms. 65254721Semaste/// 66254721Semaste/// This platform will be used as the default platform when launching 67254721Semaste/// or attaching to processes unless another platform is specified. 68254721Semaste//------------------------------------------------------------------ 69254721SemastePlatformSP 70254721SemastePlatform::GetDefaultPlatform () 71254721Semaste{ 72254721Semaste return GetDefaultPlatformSP (); 73254721Semaste} 74254721Semaste 75254721Semastevoid 76254721SemastePlatform::SetDefaultPlatform (const lldb::PlatformSP &platform_sp) 77254721Semaste{ 78254721Semaste // The native platform should use its static void Platform::Initialize() 79254721Semaste // function to register itself as the native platform. 80254721Semaste GetDefaultPlatformSP () = platform_sp; 81254721Semaste} 82254721Semaste 83254721SemasteError 84269024SemastePlatform::GetFileWithUUID (const FileSpec &platform_file, 85269024Semaste const UUID *uuid_ptr, 86269024Semaste FileSpec &local_file) 87254721Semaste{ 88254721Semaste // Default to the local case 89254721Semaste local_file = platform_file; 90254721Semaste return Error(); 91254721Semaste} 92254721Semaste 93254721SemasteFileSpecList 94254721SemastePlatform::LocateExecutableScriptingResources (Target *target, Module &module) 95254721Semaste{ 96254721Semaste return FileSpecList(); 97254721Semaste} 98254721Semaste 99254721SemastePlatform* 100254721SemastePlatform::FindPlugin (Process *process, const ConstString &plugin_name) 101254721Semaste{ 102254721Semaste PlatformCreateInstance create_callback = NULL; 103254721Semaste if (plugin_name) 104254721Semaste { 105254721Semaste create_callback = PluginManager::GetPlatformCreateCallbackForPluginName (plugin_name); 106254721Semaste if (create_callback) 107254721Semaste { 108254721Semaste ArchSpec arch; 109254721Semaste if (process) 110254721Semaste { 111254721Semaste arch = process->GetTarget().GetArchitecture(); 112254721Semaste } 113254721Semaste std::unique_ptr<Platform> instance_ap(create_callback(process, &arch)); 114254721Semaste if (instance_ap.get()) 115254721Semaste return instance_ap.release(); 116254721Semaste } 117254721Semaste } 118254721Semaste else 119254721Semaste { 120254721Semaste for (uint32_t idx = 0; (create_callback = PluginManager::GetPlatformCreateCallbackAtIndex(idx)) != NULL; ++idx) 121254721Semaste { 122254721Semaste std::unique_ptr<Platform> instance_ap(create_callback(process, nullptr)); 123254721Semaste if (instance_ap.get()) 124254721Semaste return instance_ap.release(); 125254721Semaste } 126254721Semaste } 127254721Semaste return NULL; 128254721Semaste} 129254721Semaste 130254721SemasteError 131254721SemastePlatform::GetSharedModule (const ModuleSpec &module_spec, 132254721Semaste ModuleSP &module_sp, 133254721Semaste const FileSpecList *module_search_paths_ptr, 134254721Semaste ModuleSP *old_module_sp_ptr, 135254721Semaste bool *did_create_ptr) 136254721Semaste{ 137254721Semaste // Don't do any path remapping for the default implementation 138254721Semaste // of the platform GetSharedModule function, just call through 139254721Semaste // to our static ModuleList function. Platform subclasses that 140254721Semaste // implement remote debugging, might have a developer kits 141254721Semaste // installed that have cached versions of the files for the 142254721Semaste // remote target, or might implement a download and cache 143254721Semaste // locally implementation. 144254721Semaste const bool always_create = false; 145254721Semaste return ModuleList::GetSharedModule (module_spec, 146254721Semaste module_sp, 147254721Semaste module_search_paths_ptr, 148254721Semaste old_module_sp_ptr, 149254721Semaste did_create_ptr, 150254721Semaste always_create); 151254721Semaste} 152254721Semaste 153254721SemastePlatformSP 154254721SemastePlatform::Create (const char *platform_name, Error &error) 155254721Semaste{ 156254721Semaste PlatformCreateInstance create_callback = NULL; 157254721Semaste lldb::PlatformSP platform_sp; 158254721Semaste if (platform_name && platform_name[0]) 159254721Semaste { 160254721Semaste ConstString const_platform_name (platform_name); 161254721Semaste create_callback = PluginManager::GetPlatformCreateCallbackForPluginName (const_platform_name); 162254721Semaste if (create_callback) 163254721Semaste platform_sp.reset(create_callback(true, NULL)); 164254721Semaste else 165254721Semaste error.SetErrorStringWithFormat ("unable to find a plug-in for the platform named \"%s\"", platform_name); 166254721Semaste } 167254721Semaste else 168254721Semaste error.SetErrorString ("invalid platform name"); 169254721Semaste return platform_sp; 170254721Semaste} 171254721Semaste 172254721Semaste 173254721SemastePlatformSP 174254721SemastePlatform::Create (const ArchSpec &arch, ArchSpec *platform_arch_ptr, Error &error) 175254721Semaste{ 176254721Semaste lldb::PlatformSP platform_sp; 177254721Semaste if (arch.IsValid()) 178254721Semaste { 179254721Semaste uint32_t idx; 180254721Semaste PlatformCreateInstance create_callback; 181254721Semaste // First try exact arch matches across all platform plug-ins 182254721Semaste bool exact = true; 183254721Semaste for (idx = 0; (create_callback = PluginManager::GetPlatformCreateCallbackAtIndex (idx)); ++idx) 184254721Semaste { 185254721Semaste if (create_callback) 186254721Semaste { 187254721Semaste platform_sp.reset(create_callback(false, &arch)); 188254721Semaste if (platform_sp && platform_sp->IsCompatibleArchitecture(arch, exact, platform_arch_ptr)) 189254721Semaste return platform_sp; 190254721Semaste } 191254721Semaste } 192254721Semaste // Next try compatible arch matches across all platform plug-ins 193254721Semaste exact = false; 194254721Semaste for (idx = 0; (create_callback = PluginManager::GetPlatformCreateCallbackAtIndex (idx)); ++idx) 195254721Semaste { 196254721Semaste if (create_callback) 197254721Semaste { 198254721Semaste platform_sp.reset(create_callback(false, &arch)); 199254721Semaste if (platform_sp && platform_sp->IsCompatibleArchitecture(arch, exact, platform_arch_ptr)) 200254721Semaste return platform_sp; 201254721Semaste } 202254721Semaste } 203254721Semaste } 204254721Semaste else 205254721Semaste error.SetErrorString ("invalid platform name"); 206254721Semaste if (platform_arch_ptr) 207254721Semaste platform_arch_ptr->Clear(); 208254721Semaste platform_sp.reset(); 209254721Semaste return platform_sp; 210254721Semaste} 211254721Semaste 212254721Semasteuint32_t 213254721SemastePlatform::GetNumConnectedRemotePlatforms () 214254721Semaste{ 215254721Semaste Mutex::Locker locker (GetConnectedPlatformListMutex ()); 216254721Semaste return GetConnectedPlatformList().size(); 217254721Semaste} 218254721Semaste 219254721SemastePlatformSP 220254721SemastePlatform::GetConnectedRemotePlatformAtIndex (uint32_t idx) 221254721Semaste{ 222254721Semaste PlatformSP platform_sp; 223254721Semaste { 224254721Semaste Mutex::Locker locker (GetConnectedPlatformListMutex ()); 225254721Semaste if (idx < GetConnectedPlatformList().size()) 226254721Semaste platform_sp = GetConnectedPlatformList ()[idx]; 227254721Semaste } 228254721Semaste return platform_sp; 229254721Semaste} 230254721Semaste 231254721Semaste//------------------------------------------------------------------ 232254721Semaste/// Default Constructor 233254721Semaste//------------------------------------------------------------------ 234254721SemastePlatform::Platform (bool is_host) : 235254721Semaste m_is_host (is_host), 236254721Semaste m_os_version_set_while_connected (false), 237254721Semaste m_system_arch_set_while_connected (false), 238254721Semaste m_sdk_sysroot (), 239254721Semaste m_sdk_build (), 240263367Semaste m_working_dir (), 241254721Semaste m_remote_url (), 242254721Semaste m_name (), 243254721Semaste m_major_os_version (UINT32_MAX), 244254721Semaste m_minor_os_version (UINT32_MAX), 245254721Semaste m_update_os_version (UINT32_MAX), 246254721Semaste m_system_arch(), 247254721Semaste m_uid_map_mutex (Mutex::eMutexTypeNormal), 248254721Semaste m_gid_map_mutex (Mutex::eMutexTypeNormal), 249254721Semaste m_uid_map(), 250254721Semaste m_gid_map(), 251254721Semaste m_max_uid_name_len (0), 252263363Semaste m_max_gid_name_len (0), 253263363Semaste m_supports_rsync (false), 254263363Semaste m_rsync_opts (), 255263363Semaste m_rsync_prefix (), 256263363Semaste m_supports_ssh (false), 257263363Semaste m_ssh_opts (), 258269024Semaste m_ignores_remote_hostname (false), 259269024Semaste m_trap_handlers(), 260269024Semaste m_calculated_trap_handlers (false) 261254721Semaste{ 262254721Semaste Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_OBJECT)); 263254721Semaste if (log) 264254721Semaste log->Printf ("%p Platform::Platform()", this); 265254721Semaste} 266254721Semaste 267254721Semaste//------------------------------------------------------------------ 268254721Semaste/// Destructor. 269254721Semaste/// 270254721Semaste/// The destructor is virtual since this class is designed to be 271254721Semaste/// inherited from by the plug-in instance. 272254721Semaste//------------------------------------------------------------------ 273254721SemastePlatform::~Platform() 274254721Semaste{ 275254721Semaste Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_OBJECT)); 276254721Semaste if (log) 277254721Semaste log->Printf ("%p Platform::~Platform()", this); 278254721Semaste} 279254721Semaste 280254721Semastevoid 281254721SemastePlatform::GetStatus (Stream &strm) 282254721Semaste{ 283254721Semaste uint32_t major = UINT32_MAX; 284254721Semaste uint32_t minor = UINT32_MAX; 285254721Semaste uint32_t update = UINT32_MAX; 286254721Semaste std::string s; 287254721Semaste strm.Printf (" Platform: %s\n", GetPluginName().GetCString()); 288254721Semaste 289254721Semaste ArchSpec arch (GetSystemArchitecture()); 290254721Semaste if (arch.IsValid()) 291254721Semaste { 292254721Semaste if (!arch.GetTriple().str().empty()) 293254721Semaste strm.Printf(" Triple: %s\n", arch.GetTriple().str().c_str()); 294254721Semaste } 295254721Semaste 296254721Semaste if (GetOSVersion(major, minor, update)) 297254721Semaste { 298254721Semaste strm.Printf("OS Version: %u", major); 299254721Semaste if (minor != UINT32_MAX) 300254721Semaste strm.Printf(".%u", minor); 301254721Semaste if (update != UINT32_MAX) 302254721Semaste strm.Printf(".%u", update); 303254721Semaste 304254721Semaste if (GetOSBuildString (s)) 305254721Semaste strm.Printf(" (%s)", s.c_str()); 306254721Semaste 307254721Semaste strm.EOL(); 308254721Semaste } 309254721Semaste 310254721Semaste if (GetOSKernelDescription (s)) 311254721Semaste strm.Printf(" Kernel: %s\n", s.c_str()); 312254721Semaste 313254721Semaste if (IsHost()) 314254721Semaste { 315254721Semaste strm.Printf(" Hostname: %s\n", GetHostname()); 316254721Semaste } 317254721Semaste else 318254721Semaste { 319254721Semaste const bool is_connected = IsConnected(); 320254721Semaste if (is_connected) 321254721Semaste strm.Printf(" Hostname: %s\n", GetHostname()); 322254721Semaste strm.Printf(" Connected: %s\n", is_connected ? "yes" : "no"); 323254721Semaste } 324263363Semaste 325263367Semaste if (GetWorkingDirectory()) 326263367Semaste { 327263367Semaste strm.Printf("WorkingDir: %s\n", GetWorkingDirectory().GetCString()); 328263367Semaste } 329263363Semaste if (!IsConnected()) 330263363Semaste return; 331263363Semaste 332263363Semaste std::string specific_info(GetPlatformSpecificConnectionInformation()); 333263363Semaste 334263363Semaste if (specific_info.empty() == false) 335263363Semaste strm.Printf("Platform-specific connection: %s\n", specific_info.c_str()); 336254721Semaste} 337254721Semaste 338254721Semaste 339254721Semastebool 340254721SemastePlatform::GetOSVersion (uint32_t &major, 341254721Semaste uint32_t &minor, 342254721Semaste uint32_t &update) 343254721Semaste{ 344254721Semaste bool success = m_major_os_version != UINT32_MAX; 345254721Semaste if (IsHost()) 346254721Semaste { 347254721Semaste if (!success) 348254721Semaste { 349254721Semaste // We have a local host platform 350254721Semaste success = Host::GetOSVersion (m_major_os_version, 351254721Semaste m_minor_os_version, 352254721Semaste m_update_os_version); 353254721Semaste m_os_version_set_while_connected = success; 354254721Semaste } 355254721Semaste } 356254721Semaste else 357254721Semaste { 358254721Semaste // We have a remote platform. We can only fetch the remote 359254721Semaste // OS version if we are connected, and we don't want to do it 360254721Semaste // more than once. 361254721Semaste 362254721Semaste const bool is_connected = IsConnected(); 363254721Semaste 364254721Semaste bool fetch = false; 365254721Semaste if (success) 366254721Semaste { 367254721Semaste // We have valid OS version info, check to make sure it wasn't 368254721Semaste // manually set prior to connecting. If it was manually set prior 369254721Semaste // to connecting, then lets fetch the actual OS version info 370254721Semaste // if we are now connected. 371254721Semaste if (is_connected && !m_os_version_set_while_connected) 372254721Semaste fetch = true; 373254721Semaste } 374254721Semaste else 375254721Semaste { 376254721Semaste // We don't have valid OS version info, fetch it if we are connected 377254721Semaste fetch = is_connected; 378254721Semaste } 379254721Semaste 380254721Semaste if (fetch) 381254721Semaste { 382254721Semaste success = GetRemoteOSVersion (); 383254721Semaste m_os_version_set_while_connected = success; 384254721Semaste } 385254721Semaste } 386254721Semaste 387254721Semaste if (success) 388254721Semaste { 389254721Semaste major = m_major_os_version; 390254721Semaste minor = m_minor_os_version; 391254721Semaste update = m_update_os_version; 392254721Semaste } 393254721Semaste return success; 394254721Semaste} 395254721Semaste 396254721Semastebool 397254721SemastePlatform::GetOSBuildString (std::string &s) 398254721Semaste{ 399254721Semaste if (IsHost()) 400254721Semaste return Host::GetOSBuildString (s); 401254721Semaste else 402254721Semaste return GetRemoteOSBuildString (s); 403254721Semaste} 404254721Semaste 405254721Semastebool 406254721SemastePlatform::GetOSKernelDescription (std::string &s) 407254721Semaste{ 408254721Semaste if (IsHost()) 409254721Semaste return Host::GetOSKernelDescription (s); 410254721Semaste else 411254721Semaste return GetRemoteOSKernelDescription (s); 412254721Semaste} 413254721Semaste 414254721SemasteConstString 415263367SemastePlatform::GetWorkingDirectory () 416263367Semaste{ 417263367Semaste if (IsHost()) 418263367Semaste { 419263367Semaste char cwd[PATH_MAX]; 420263367Semaste if (getcwd(cwd, sizeof(cwd))) 421263367Semaste return ConstString(cwd); 422263367Semaste else 423263367Semaste return ConstString(); 424263367Semaste } 425263367Semaste else 426263367Semaste { 427263367Semaste if (!m_working_dir) 428263367Semaste m_working_dir = GetRemoteWorkingDirectory(); 429263367Semaste return m_working_dir; 430263367Semaste } 431263367Semaste} 432263367Semaste 433263367Semaste 434263367Semastestruct RecurseCopyBaton 435263367Semaste{ 436263367Semaste const FileSpec& dst; 437263367Semaste Platform *platform_ptr; 438263367Semaste Error error; 439263367Semaste}; 440263367Semaste 441263367Semaste 442263367Semastestatic FileSpec::EnumerateDirectoryResult 443263367SemasteRecurseCopy_Callback (void *baton, 444263367Semaste FileSpec::FileType file_type, 445263367Semaste const FileSpec &src) 446263367Semaste{ 447263367Semaste RecurseCopyBaton* rc_baton = (RecurseCopyBaton*)baton; 448263367Semaste switch (file_type) 449263367Semaste { 450263367Semaste case FileSpec::eFileTypePipe: 451263367Semaste case FileSpec::eFileTypeSocket: 452263367Semaste // we have no way to copy pipes and sockets - ignore them and continue 453263367Semaste return FileSpec::eEnumerateDirectoryResultNext; 454263367Semaste break; 455263367Semaste 456263367Semaste case FileSpec::eFileTypeDirectory: 457263367Semaste { 458263367Semaste // make the new directory and get in there 459263367Semaste FileSpec dst_dir = rc_baton->dst; 460263367Semaste if (!dst_dir.GetFilename()) 461263367Semaste dst_dir.GetFilename() = src.GetLastPathComponent(); 462263367Semaste std::string dst_dir_path (dst_dir.GetPath()); 463263367Semaste Error error = rc_baton->platform_ptr->MakeDirectory(dst_dir_path.c_str(), lldb::eFilePermissionsDirectoryDefault); 464263367Semaste if (error.Fail()) 465263367Semaste { 466263367Semaste rc_baton->error.SetErrorStringWithFormat("unable to setup directory %s on remote end", dst_dir_path.c_str()); 467263367Semaste return FileSpec::eEnumerateDirectoryResultQuit; // got an error, bail out 468263367Semaste } 469263367Semaste 470263367Semaste // now recurse 471263367Semaste std::string src_dir_path (src.GetPath()); 472263367Semaste 473263367Semaste // Make a filespec that only fills in the directory of a FileSpec so 474263367Semaste // when we enumerate we can quickly fill in the filename for dst copies 475263367Semaste FileSpec recurse_dst; 476263367Semaste recurse_dst.GetDirectory().SetCString(dst_dir.GetPath().c_str()); 477263367Semaste RecurseCopyBaton rc_baton2 = { recurse_dst, rc_baton->platform_ptr, Error() }; 478263367Semaste FileSpec::EnumerateDirectory(src_dir_path.c_str(), true, true, true, RecurseCopy_Callback, &rc_baton2); 479263367Semaste if (rc_baton2.error.Fail()) 480263367Semaste { 481263367Semaste rc_baton->error.SetErrorString(rc_baton2.error.AsCString()); 482263367Semaste return FileSpec::eEnumerateDirectoryResultQuit; // got an error, bail out 483263367Semaste } 484263367Semaste return FileSpec::eEnumerateDirectoryResultNext; 485263367Semaste } 486263367Semaste break; 487263367Semaste 488263367Semaste case FileSpec::eFileTypeSymbolicLink: 489263367Semaste { 490263367Semaste // copy the file and keep going 491263367Semaste FileSpec dst_file = rc_baton->dst; 492263367Semaste if (!dst_file.GetFilename()) 493263367Semaste dst_file.GetFilename() = src.GetFilename(); 494263367Semaste 495263367Semaste char buf[PATH_MAX]; 496263367Semaste 497263367Semaste rc_baton->error = Host::Readlink (src.GetPath().c_str(), buf, sizeof(buf)); 498263367Semaste 499263367Semaste if (rc_baton->error.Fail()) 500263367Semaste return FileSpec::eEnumerateDirectoryResultQuit; // got an error, bail out 501263367Semaste 502263367Semaste rc_baton->error = rc_baton->platform_ptr->CreateSymlink(dst_file.GetPath().c_str(), buf); 503263367Semaste 504263367Semaste if (rc_baton->error.Fail()) 505263367Semaste return FileSpec::eEnumerateDirectoryResultQuit; // got an error, bail out 506263367Semaste 507263367Semaste return FileSpec::eEnumerateDirectoryResultNext; 508263367Semaste } 509263367Semaste break; 510263367Semaste case FileSpec::eFileTypeRegular: 511263367Semaste { 512263367Semaste // copy the file and keep going 513263367Semaste FileSpec dst_file = rc_baton->dst; 514263367Semaste if (!dst_file.GetFilename()) 515263367Semaste dst_file.GetFilename() = src.GetFilename(); 516263367Semaste Error err = rc_baton->platform_ptr->PutFile(src, dst_file); 517263367Semaste if (err.Fail()) 518263367Semaste { 519263367Semaste rc_baton->error.SetErrorString(err.AsCString()); 520263367Semaste return FileSpec::eEnumerateDirectoryResultQuit; // got an error, bail out 521263367Semaste } 522263367Semaste return FileSpec::eEnumerateDirectoryResultNext; 523263367Semaste } 524263367Semaste break; 525263367Semaste 526263367Semaste case FileSpec::eFileTypeInvalid: 527263367Semaste case FileSpec::eFileTypeOther: 528263367Semaste case FileSpec::eFileTypeUnknown: 529263367Semaste rc_baton->error.SetErrorStringWithFormat("invalid file detected during copy: %s", src.GetPath().c_str()); 530263367Semaste return FileSpec::eEnumerateDirectoryResultQuit; // got an error, bail out 531263367Semaste break; 532263367Semaste } 533263367Semaste} 534263367Semaste 535263367SemasteError 536263367SemastePlatform::Install (const FileSpec& src, const FileSpec& dst) 537263367Semaste{ 538263367Semaste Error error; 539263367Semaste 540263367Semaste Log *log = GetLogIfAnyCategoriesSet(LIBLLDB_LOG_PLATFORM); 541263367Semaste if (log) 542263367Semaste log->Printf ("Platform::Install (src='%s', dst='%s')", src.GetPath().c_str(), dst.GetPath().c_str()); 543263367Semaste FileSpec fixed_dst(dst); 544263367Semaste 545263367Semaste if (!fixed_dst.GetFilename()) 546263367Semaste fixed_dst.GetFilename() = src.GetFilename(); 547263367Semaste 548263367Semaste ConstString working_dir = GetWorkingDirectory(); 549263367Semaste 550263367Semaste if (dst) 551263367Semaste { 552263367Semaste if (dst.GetDirectory()) 553263367Semaste { 554263367Semaste const char first_dst_dir_char = dst.GetDirectory().GetCString()[0]; 555263367Semaste if (first_dst_dir_char == '/' || first_dst_dir_char == '\\') 556263367Semaste { 557263367Semaste fixed_dst.GetDirectory() = dst.GetDirectory(); 558263367Semaste } 559263367Semaste // If the fixed destination file doesn't have a directory yet, 560263367Semaste // then we must have a relative path. We will resolve this relative 561263367Semaste // path against the platform's working directory 562263367Semaste if (!fixed_dst.GetDirectory()) 563263367Semaste { 564263367Semaste FileSpec relative_spec; 565263367Semaste std::string path; 566263367Semaste if (working_dir) 567263367Semaste { 568263367Semaste relative_spec.SetFile(working_dir.GetCString(), false); 569263367Semaste relative_spec.AppendPathComponent(dst.GetPath().c_str()); 570263367Semaste fixed_dst.GetDirectory() = relative_spec.GetDirectory(); 571263367Semaste } 572263367Semaste else 573263367Semaste { 574263367Semaste error.SetErrorStringWithFormat("platform working directory must be valid for relative path '%s'", dst.GetPath().c_str()); 575263367Semaste return error; 576263367Semaste } 577263367Semaste } 578263367Semaste } 579263367Semaste else 580263367Semaste { 581263367Semaste if (working_dir) 582263367Semaste { 583263367Semaste fixed_dst.GetDirectory() = working_dir; 584263367Semaste } 585263367Semaste else 586263367Semaste { 587263367Semaste error.SetErrorStringWithFormat("platform working directory must be valid for relative path '%s'", dst.GetPath().c_str()); 588263367Semaste return error; 589263367Semaste } 590263367Semaste } 591263367Semaste } 592263367Semaste else 593263367Semaste { 594263367Semaste if (working_dir) 595263367Semaste { 596263367Semaste fixed_dst.GetDirectory() = working_dir; 597263367Semaste } 598263367Semaste else 599263367Semaste { 600263367Semaste error.SetErrorStringWithFormat("platform working directory must be valid when destination directory is empty"); 601263367Semaste return error; 602263367Semaste } 603263367Semaste } 604263367Semaste 605263367Semaste if (log) 606263367Semaste log->Printf ("Platform::Install (src='%s', dst='%s') fixed_dst='%s'", src.GetPath().c_str(), dst.GetPath().c_str(), fixed_dst.GetPath().c_str()); 607263367Semaste 608263367Semaste if (GetSupportsRSync()) 609263367Semaste { 610263367Semaste error = PutFile(src, dst); 611263367Semaste } 612263367Semaste else 613263367Semaste { 614263367Semaste switch (src.GetFileType()) 615263367Semaste { 616263367Semaste case FileSpec::eFileTypeDirectory: 617263367Semaste { 618263367Semaste if (GetFileExists (fixed_dst)) 619263367Semaste Unlink (fixed_dst.GetPath().c_str()); 620263367Semaste uint32_t permissions = src.GetPermissions(); 621263367Semaste if (permissions == 0) 622263367Semaste permissions = eFilePermissionsDirectoryDefault; 623263367Semaste std::string dst_dir_path(fixed_dst.GetPath()); 624263367Semaste error = MakeDirectory(dst_dir_path.c_str(), permissions); 625263367Semaste if (error.Success()) 626263367Semaste { 627263367Semaste // Make a filespec that only fills in the directory of a FileSpec so 628263367Semaste // when we enumerate we can quickly fill in the filename for dst copies 629263367Semaste FileSpec recurse_dst; 630263367Semaste recurse_dst.GetDirectory().SetCString(dst_dir_path.c_str()); 631263367Semaste std::string src_dir_path (src.GetPath()); 632263367Semaste RecurseCopyBaton baton = { recurse_dst, this, Error() }; 633263367Semaste FileSpec::EnumerateDirectory(src_dir_path.c_str(), true, true, true, RecurseCopy_Callback, &baton); 634263367Semaste return baton.error; 635263367Semaste } 636263367Semaste } 637263367Semaste break; 638263367Semaste 639263367Semaste case FileSpec::eFileTypeRegular: 640263367Semaste if (GetFileExists (fixed_dst)) 641263367Semaste Unlink (fixed_dst.GetPath().c_str()); 642263367Semaste error = PutFile(src, fixed_dst); 643263367Semaste break; 644263367Semaste 645263367Semaste case FileSpec::eFileTypeSymbolicLink: 646263367Semaste { 647263367Semaste if (GetFileExists (fixed_dst)) 648263367Semaste Unlink (fixed_dst.GetPath().c_str()); 649263367Semaste char buf[PATH_MAX]; 650263367Semaste error = Host::Readlink(src.GetPath().c_str(), buf, sizeof(buf)); 651263367Semaste if (error.Success()) 652263367Semaste error = CreateSymlink(dst.GetPath().c_str(), buf); 653263367Semaste } 654263367Semaste break; 655263367Semaste case FileSpec::eFileTypePipe: 656263367Semaste error.SetErrorString("platform install doesn't handle pipes"); 657263367Semaste break; 658263367Semaste case FileSpec::eFileTypeSocket: 659263367Semaste error.SetErrorString("platform install doesn't handle sockets"); 660263367Semaste break; 661263367Semaste case FileSpec::eFileTypeInvalid: 662263367Semaste case FileSpec::eFileTypeUnknown: 663263367Semaste case FileSpec::eFileTypeOther: 664263367Semaste error.SetErrorString("platform install doesn't handle non file or directory items"); 665263367Semaste break; 666263367Semaste } 667263367Semaste } 668263367Semaste return error; 669263367Semaste} 670263367Semaste 671263367Semastebool 672263367SemastePlatform::SetWorkingDirectory (const ConstString &path) 673263367Semaste{ 674263367Semaste if (IsHost()) 675263367Semaste { 676263367Semaste Log *log = GetLogIfAnyCategoriesSet(LIBLLDB_LOG_PLATFORM); 677263367Semaste if (log) 678263367Semaste log->Printf("Platform::SetWorkingDirectory('%s')", path.GetCString()); 679263367Semaste#ifdef _WIN32 680263367Semaste // Not implemented on Windows 681263367Semaste return false; 682263367Semaste#else 683263367Semaste if (path) 684263367Semaste { 685263367Semaste if (chdir(path.GetCString()) == 0) 686263367Semaste return true; 687263367Semaste } 688263367Semaste return false; 689263367Semaste#endif 690263367Semaste } 691263367Semaste else 692263367Semaste { 693263367Semaste m_working_dir.Clear(); 694263367Semaste return SetRemoteWorkingDirectory(path); 695263367Semaste } 696263367Semaste} 697263367Semaste 698263367SemasteError 699263367SemastePlatform::MakeDirectory (const char *path, uint32_t permissions) 700263367Semaste{ 701263367Semaste if (IsHost()) 702263367Semaste return Host::MakeDirectory (path, permissions); 703263367Semaste else 704263367Semaste { 705263367Semaste Error error; 706263367Semaste error.SetErrorStringWithFormat("remote platform %s doesn't support %s", GetPluginName().GetCString(), __PRETTY_FUNCTION__); 707263367Semaste return error; 708263367Semaste } 709263367Semaste} 710263367Semaste 711263367SemasteError 712263367SemastePlatform::GetFilePermissions (const char *path, uint32_t &file_permissions) 713263367Semaste{ 714263367Semaste if (IsHost()) 715263367Semaste return Host::GetFilePermissions(path, file_permissions); 716263367Semaste else 717263367Semaste { 718263367Semaste Error error; 719263367Semaste error.SetErrorStringWithFormat("remote platform %s doesn't support %s", GetPluginName().GetCString(), __PRETTY_FUNCTION__); 720263367Semaste return error; 721263367Semaste } 722263367Semaste} 723263367Semaste 724263367SemasteError 725263367SemastePlatform::SetFilePermissions (const char *path, uint32_t file_permissions) 726263367Semaste{ 727263367Semaste if (IsHost()) 728263367Semaste return Host::SetFilePermissions(path, file_permissions); 729263367Semaste else 730263367Semaste { 731263367Semaste Error error; 732263367Semaste error.SetErrorStringWithFormat("remote platform %s doesn't support %s", GetPluginName().GetCString(), __PRETTY_FUNCTION__); 733263367Semaste return error; 734263367Semaste } 735263367Semaste} 736263367Semaste 737263367SemasteConstString 738254721SemastePlatform::GetName () 739254721Semaste{ 740263367Semaste return GetPluginName(); 741254721Semaste} 742254721Semaste 743254721Semasteconst char * 744254721SemastePlatform::GetHostname () 745254721Semaste{ 746254721Semaste if (IsHost()) 747254721Semaste return "localhost"; 748254721Semaste 749254721Semaste if (m_name.empty()) 750254721Semaste return NULL; 751254721Semaste return m_name.c_str(); 752254721Semaste} 753254721Semaste 754263367Semastebool 755263367SemastePlatform::SetRemoteWorkingDirectory(const ConstString &path) 756263367Semaste{ 757263367Semaste Log *log = GetLogIfAnyCategoriesSet(LIBLLDB_LOG_PLATFORM); 758263367Semaste if (log) 759263367Semaste log->Printf("Platform::SetRemoteWorkingDirectory('%s')", path.GetCString()); 760263367Semaste m_working_dir = path; 761263367Semaste return true; 762263367Semaste} 763263367Semaste 764254721Semasteconst char * 765254721SemastePlatform::GetUserName (uint32_t uid) 766254721Semaste{ 767254721Semaste const char *user_name = GetCachedUserName(uid); 768254721Semaste if (user_name) 769254721Semaste return user_name; 770254721Semaste if (IsHost()) 771254721Semaste { 772254721Semaste std::string name; 773254721Semaste if (Host::GetUserName(uid, name)) 774254721Semaste return SetCachedUserName (uid, name.c_str(), name.size()); 775254721Semaste } 776254721Semaste return NULL; 777254721Semaste} 778254721Semaste 779254721Semasteconst char * 780254721SemastePlatform::GetGroupName (uint32_t gid) 781254721Semaste{ 782254721Semaste const char *group_name = GetCachedGroupName(gid); 783254721Semaste if (group_name) 784254721Semaste return group_name; 785254721Semaste if (IsHost()) 786254721Semaste { 787254721Semaste std::string name; 788254721Semaste if (Host::GetGroupName(gid, name)) 789254721Semaste return SetCachedGroupName (gid, name.c_str(), name.size()); 790254721Semaste } 791254721Semaste return NULL; 792254721Semaste} 793254721Semaste 794254721Semastebool 795254721SemastePlatform::SetOSVersion (uint32_t major, 796254721Semaste uint32_t minor, 797254721Semaste uint32_t update) 798254721Semaste{ 799254721Semaste if (IsHost()) 800254721Semaste { 801254721Semaste // We don't need anyone setting the OS version for the host platform, 802254721Semaste // we should be able to figure it out by calling Host::GetOSVersion(...). 803254721Semaste return false; 804254721Semaste } 805254721Semaste else 806254721Semaste { 807254721Semaste // We have a remote platform, allow setting the target OS version if 808254721Semaste // we aren't connected, since if we are connected, we should be able to 809254721Semaste // request the remote OS version from the connected platform. 810254721Semaste if (IsConnected()) 811254721Semaste return false; 812254721Semaste else 813254721Semaste { 814254721Semaste // We aren't connected and we might want to set the OS version 815254721Semaste // ahead of time before we connect so we can peruse files and 816254721Semaste // use a local SDK or PDK cache of support files to disassemble 817254721Semaste // or do other things. 818254721Semaste m_major_os_version = major; 819254721Semaste m_minor_os_version = minor; 820254721Semaste m_update_os_version = update; 821254721Semaste return true; 822254721Semaste } 823254721Semaste } 824254721Semaste return false; 825254721Semaste} 826254721Semaste 827254721Semaste 828254721SemasteError 829254721SemastePlatform::ResolveExecutable (const FileSpec &exe_file, 830254721Semaste const ArchSpec &exe_arch, 831254721Semaste lldb::ModuleSP &exe_module_sp, 832254721Semaste const FileSpecList *module_search_paths_ptr) 833254721Semaste{ 834254721Semaste Error error; 835254721Semaste if (exe_file.Exists()) 836254721Semaste { 837254721Semaste ModuleSpec module_spec (exe_file, exe_arch); 838254721Semaste if (module_spec.GetArchitecture().IsValid()) 839254721Semaste { 840254721Semaste error = ModuleList::GetSharedModule (module_spec, 841254721Semaste exe_module_sp, 842254721Semaste module_search_paths_ptr, 843254721Semaste NULL, 844254721Semaste NULL); 845254721Semaste } 846254721Semaste else 847254721Semaste { 848254721Semaste // No valid architecture was specified, ask the platform for 849254721Semaste // the architectures that we should be using (in the correct order) 850254721Semaste // and see if we can find a match that way 851254721Semaste for (uint32_t idx = 0; GetSupportedArchitectureAtIndex (idx, module_spec.GetArchitecture()); ++idx) 852254721Semaste { 853254721Semaste error = ModuleList::GetSharedModule (module_spec, 854254721Semaste exe_module_sp, 855254721Semaste module_search_paths_ptr, 856254721Semaste NULL, 857254721Semaste NULL); 858254721Semaste // Did we find an executable using one of the 859254721Semaste if (error.Success() && exe_module_sp) 860254721Semaste break; 861254721Semaste } 862254721Semaste } 863254721Semaste } 864254721Semaste else 865254721Semaste { 866254721Semaste error.SetErrorStringWithFormat ("'%s' does not exist", 867254721Semaste exe_file.GetPath().c_str()); 868254721Semaste } 869254721Semaste return error; 870254721Semaste} 871254721Semaste 872254721SemasteError 873254721SemastePlatform::ResolveSymbolFile (Target &target, 874254721Semaste const ModuleSpec &sym_spec, 875254721Semaste FileSpec &sym_file) 876254721Semaste{ 877254721Semaste Error error; 878254721Semaste if (sym_spec.GetSymbolFileSpec().Exists()) 879254721Semaste sym_file = sym_spec.GetSymbolFileSpec(); 880254721Semaste else 881254721Semaste error.SetErrorString("unable to resolve symbol file"); 882254721Semaste return error; 883254721Semaste 884254721Semaste} 885254721Semaste 886254721Semaste 887254721Semaste 888254721Semastebool 889254721SemastePlatform::ResolveRemotePath (const FileSpec &platform_path, 890254721Semaste FileSpec &resolved_platform_path) 891254721Semaste{ 892254721Semaste resolved_platform_path = platform_path; 893254721Semaste return resolved_platform_path.ResolvePath(); 894254721Semaste} 895254721Semaste 896254721Semaste 897254721Semasteconst ArchSpec & 898254721SemastePlatform::GetSystemArchitecture() 899254721Semaste{ 900254721Semaste if (IsHost()) 901254721Semaste { 902254721Semaste if (!m_system_arch.IsValid()) 903254721Semaste { 904254721Semaste // We have a local host platform 905254721Semaste m_system_arch = Host::GetArchitecture(); 906254721Semaste m_system_arch_set_while_connected = m_system_arch.IsValid(); 907254721Semaste } 908254721Semaste } 909254721Semaste else 910254721Semaste { 911254721Semaste // We have a remote platform. We can only fetch the remote 912254721Semaste // system architecture if we are connected, and we don't want to do it 913254721Semaste // more than once. 914254721Semaste 915254721Semaste const bool is_connected = IsConnected(); 916254721Semaste 917254721Semaste bool fetch = false; 918254721Semaste if (m_system_arch.IsValid()) 919254721Semaste { 920254721Semaste // We have valid OS version info, check to make sure it wasn't 921254721Semaste // manually set prior to connecting. If it was manually set prior 922254721Semaste // to connecting, then lets fetch the actual OS version info 923254721Semaste // if we are now connected. 924254721Semaste if (is_connected && !m_system_arch_set_while_connected) 925254721Semaste fetch = true; 926254721Semaste } 927254721Semaste else 928254721Semaste { 929254721Semaste // We don't have valid OS version info, fetch it if we are connected 930254721Semaste fetch = is_connected; 931254721Semaste } 932254721Semaste 933254721Semaste if (fetch) 934254721Semaste { 935254721Semaste m_system_arch = GetRemoteSystemArchitecture (); 936254721Semaste m_system_arch_set_while_connected = m_system_arch.IsValid(); 937254721Semaste } 938254721Semaste } 939254721Semaste return m_system_arch; 940254721Semaste} 941254721Semaste 942254721Semaste 943254721SemasteError 944254721SemastePlatform::ConnectRemote (Args& args) 945254721Semaste{ 946254721Semaste Error error; 947254721Semaste if (IsHost()) 948254721Semaste error.SetErrorStringWithFormat ("The currently selected platform (%s) is the host platform and is always connected.", GetPluginName().GetCString()); 949254721Semaste else 950254721Semaste error.SetErrorStringWithFormat ("Platform::ConnectRemote() is not supported by %s", GetPluginName().GetCString()); 951254721Semaste return error; 952254721Semaste} 953254721Semaste 954254721SemasteError 955254721SemastePlatform::DisconnectRemote () 956254721Semaste{ 957254721Semaste Error error; 958254721Semaste if (IsHost()) 959254721Semaste error.SetErrorStringWithFormat ("The currently selected platform (%s) is the host platform and is always connected.", GetPluginName().GetCString()); 960254721Semaste else 961254721Semaste error.SetErrorStringWithFormat ("Platform::DisconnectRemote() is not supported by %s", GetPluginName().GetCString()); 962254721Semaste return error; 963254721Semaste} 964254721Semaste 965254721Semastebool 966254721SemastePlatform::GetProcessInfo (lldb::pid_t pid, ProcessInstanceInfo &process_info) 967254721Semaste{ 968254721Semaste // Take care of the host case so that each subclass can just 969254721Semaste // call this function to get the host functionality. 970254721Semaste if (IsHost()) 971254721Semaste return Host::GetProcessInfo (pid, process_info); 972254721Semaste return false; 973254721Semaste} 974254721Semaste 975254721Semasteuint32_t 976254721SemastePlatform::FindProcesses (const ProcessInstanceInfoMatch &match_info, 977254721Semaste ProcessInstanceInfoList &process_infos) 978254721Semaste{ 979254721Semaste // Take care of the host case so that each subclass can just 980254721Semaste // call this function to get the host functionality. 981254721Semaste uint32_t match_count = 0; 982254721Semaste if (IsHost()) 983254721Semaste match_count = Host::FindProcesses (match_info, process_infos); 984254721Semaste return match_count; 985254721Semaste} 986254721Semaste 987254721Semaste 988254721SemasteError 989254721SemastePlatform::LaunchProcess (ProcessLaunchInfo &launch_info) 990254721Semaste{ 991254721Semaste Error error; 992254721Semaste // Take care of the host case so that each subclass can just 993254721Semaste // call this function to get the host functionality. 994254721Semaste if (IsHost()) 995254721Semaste { 996254721Semaste if (::getenv ("LLDB_LAUNCH_FLAG_LAUNCH_IN_TTY")) 997254721Semaste launch_info.GetFlags().Set (eLaunchFlagLaunchInTTY); 998254721Semaste 999254721Semaste if (launch_info.GetFlags().Test (eLaunchFlagLaunchInShell)) 1000254721Semaste { 1001254721Semaste const bool is_localhost = true; 1002254721Semaste const bool will_debug = launch_info.GetFlags().Test(eLaunchFlagDebug); 1003254721Semaste const bool first_arg_is_full_shell_command = false; 1004263363Semaste uint32_t num_resumes = GetResumeCountForLaunchInfo (launch_info); 1005254721Semaste if (!launch_info.ConvertArgumentsForLaunchingInShell (error, 1006254721Semaste is_localhost, 1007254721Semaste will_debug, 1008263363Semaste first_arg_is_full_shell_command, 1009263363Semaste num_resumes)) 1010254721Semaste return error; 1011254721Semaste } 1012254721Semaste 1013254721Semaste error = Host::LaunchProcess (launch_info); 1014254721Semaste } 1015254721Semaste else 1016254721Semaste error.SetErrorString ("base lldb_private::Platform class can't launch remote processes"); 1017254721Semaste return error; 1018254721Semaste} 1019254721Semaste 1020254721Semastelldb::ProcessSP 1021254721SemastePlatform::DebugProcess (ProcessLaunchInfo &launch_info, 1022254721Semaste Debugger &debugger, 1023254721Semaste Target *target, // Can be NULL, if NULL create a new target, else use existing one 1024254721Semaste Listener &listener, 1025254721Semaste Error &error) 1026254721Semaste{ 1027254721Semaste ProcessSP process_sp; 1028254721Semaste // Make sure we stop at the entry point 1029254721Semaste launch_info.GetFlags ().Set (eLaunchFlagDebug); 1030254721Semaste // We always launch the process we are going to debug in a separate process 1031254721Semaste // group, since then we can handle ^C interrupts ourselves w/o having to worry 1032254721Semaste // about the target getting them as well. 1033254721Semaste launch_info.SetLaunchInSeparateProcessGroup(true); 1034254721Semaste 1035254721Semaste error = LaunchProcess (launch_info); 1036254721Semaste if (error.Success()) 1037254721Semaste { 1038254721Semaste if (launch_info.GetProcessID() != LLDB_INVALID_PROCESS_ID) 1039254721Semaste { 1040254721Semaste ProcessAttachInfo attach_info (launch_info); 1041254721Semaste process_sp = Attach (attach_info, debugger, target, listener, error); 1042254721Semaste if (process_sp) 1043254721Semaste { 1044269024Semaste launch_info.SetHijackListener(attach_info.GetHijackListener()); 1045269024Semaste 1046254721Semaste // Since we attached to the process, it will think it needs to detach 1047254721Semaste // if the process object just goes away without an explicit call to 1048254721Semaste // Process::Kill() or Process::Detach(), so let it know to kill the 1049254721Semaste // process if this happens. 1050254721Semaste process_sp->SetShouldDetach (false); 1051254721Semaste 1052254721Semaste // If we didn't have any file actions, the pseudo terminal might 1053254721Semaste // have been used where the slave side was given as the file to 1054254721Semaste // open for stdin/out/err after we have already opened the master 1055254721Semaste // so we can read/write stdin/out/err. 1056254721Semaste int pty_fd = launch_info.GetPTY().ReleaseMasterFileDescriptor(); 1057254721Semaste if (pty_fd != lldb_utility::PseudoTerminal::invalid_fd) 1058254721Semaste { 1059254721Semaste process_sp->SetSTDIOFileDescriptor(pty_fd); 1060254721Semaste } 1061254721Semaste } 1062254721Semaste } 1063254721Semaste } 1064254721Semaste return process_sp; 1065254721Semaste} 1066254721Semaste 1067254721Semaste 1068254721Semastelldb::PlatformSP 1069254721SemastePlatform::GetPlatformForArchitecture (const ArchSpec &arch, ArchSpec *platform_arch_ptr) 1070254721Semaste{ 1071254721Semaste lldb::PlatformSP platform_sp; 1072254721Semaste Error error; 1073254721Semaste if (arch.IsValid()) 1074254721Semaste platform_sp = Platform::Create (arch, platform_arch_ptr, error); 1075254721Semaste return platform_sp; 1076254721Semaste} 1077254721Semaste 1078254721Semaste 1079254721Semaste//------------------------------------------------------------------ 1080254721Semaste/// Lets a platform answer if it is compatible with a given 1081254721Semaste/// architecture and the target triple contained within. 1082254721Semaste//------------------------------------------------------------------ 1083254721Semastebool 1084254721SemastePlatform::IsCompatibleArchitecture (const ArchSpec &arch, bool exact_arch_match, ArchSpec *compatible_arch_ptr) 1085254721Semaste{ 1086254721Semaste // If the architecture is invalid, we must answer true... 1087254721Semaste if (arch.IsValid()) 1088254721Semaste { 1089254721Semaste ArchSpec platform_arch; 1090254721Semaste // Try for an exact architecture match first. 1091254721Semaste if (exact_arch_match) 1092254721Semaste { 1093254721Semaste for (uint32_t arch_idx=0; GetSupportedArchitectureAtIndex (arch_idx, platform_arch); ++arch_idx) 1094254721Semaste { 1095254721Semaste if (arch.IsExactMatch(platform_arch)) 1096254721Semaste { 1097254721Semaste if (compatible_arch_ptr) 1098254721Semaste *compatible_arch_ptr = platform_arch; 1099254721Semaste return true; 1100254721Semaste } 1101254721Semaste } 1102254721Semaste } 1103254721Semaste else 1104254721Semaste { 1105254721Semaste for (uint32_t arch_idx=0; GetSupportedArchitectureAtIndex (arch_idx, platform_arch); ++arch_idx) 1106254721Semaste { 1107254721Semaste if (arch.IsCompatibleMatch(platform_arch)) 1108254721Semaste { 1109254721Semaste if (compatible_arch_ptr) 1110254721Semaste *compatible_arch_ptr = platform_arch; 1111254721Semaste return true; 1112254721Semaste } 1113254721Semaste } 1114254721Semaste } 1115254721Semaste } 1116254721Semaste if (compatible_arch_ptr) 1117254721Semaste compatible_arch_ptr->Clear(); 1118254721Semaste return false; 1119263363Semaste} 1120263363Semaste 1121263363SemasteError 1122263363SemastePlatform::PutFile (const FileSpec& source, 1123263363Semaste const FileSpec& destination, 1124263363Semaste uint32_t uid, 1125263363Semaste uint32_t gid) 1126263363Semaste{ 1127263363Semaste Error error("unimplemented"); 1128263363Semaste return error; 1129263363Semaste} 1130263363Semaste 1131263363SemasteError 1132263363SemastePlatform::GetFile (const FileSpec& source, 1133263363Semaste const FileSpec& destination) 1134263363Semaste{ 1135263363Semaste Error error("unimplemented"); 1136263363Semaste return error; 1137263363Semaste} 1138263363Semaste 1139263367SemasteError 1140263367SemastePlatform::CreateSymlink (const char *src, // The name of the link is in src 1141263367Semaste const char *dst)// The symlink points to dst 1142263367Semaste{ 1143263367Semaste Error error("unimplemented"); 1144263367Semaste return error; 1145263367Semaste} 1146263367Semaste 1147263363Semastebool 1148263363SemastePlatform::GetFileExists (const lldb_private::FileSpec& file_spec) 1149263363Semaste{ 1150263363Semaste return false; 1151263363Semaste} 1152263363Semaste 1153263367SemasteError 1154263367SemastePlatform::Unlink (const char *path) 1155263367Semaste{ 1156263367Semaste Error error("unimplemented"); 1157263367Semaste return error; 1158263367Semaste} 1159263367Semaste 1160263367Semaste 1161263367Semaste 1162263363Semastelldb_private::Error 1163263363SemastePlatform::RunShellCommand (const char *command, // Shouldn't be NULL 1164263363Semaste const char *working_dir, // Pass NULL to use the current working directory 1165263363Semaste int *status_ptr, // Pass NULL if you don't want the process exit status 1166263363Semaste int *signo_ptr, // Pass NULL if you don't want the signal that caused the process to exit 1167263363Semaste std::string *command_output, // Pass NULL if you don't want the command output 1168263363Semaste uint32_t timeout_sec) // Timeout in seconds to wait for shell program to finish 1169263363Semaste{ 1170263363Semaste if (IsHost()) 1171263363Semaste return Host::RunShellCommand (command, working_dir, status_ptr, signo_ptr, command_output, timeout_sec); 1172263363Semaste else 1173263363Semaste return Error("unimplemented"); 1174263363Semaste} 1175263363Semaste 1176263363Semaste 1177263363Semastebool 1178263363SemastePlatform::CalculateMD5 (const FileSpec& file_spec, 1179263363Semaste uint64_t &low, 1180263363Semaste uint64_t &high) 1181263363Semaste{ 1182263363Semaste if (IsHost()) 1183263363Semaste return Host::CalculateMD5(file_spec, low, high); 1184263363Semaste else 1185263363Semaste return false; 1186263363Semaste} 1187263363Semaste 1188263363Semastevoid 1189263363SemastePlatform::SetLocalCacheDirectory (const char* local) 1190263363Semaste{ 1191263363Semaste m_local_cache_directory.assign(local); 1192263363Semaste} 1193263363Semaste 1194263363Semasteconst char* 1195263363SemastePlatform::GetLocalCacheDirectory () 1196263363Semaste{ 1197263363Semaste return m_local_cache_directory.c_str(); 1198263363Semaste} 1199263363Semaste 1200263363Semastestatic OptionDefinition 1201263363Semasteg_rsync_option_table[] = 1202263363Semaste{ 1203263363Semaste { LLDB_OPT_SET_ALL, false, "rsync" , 'r', OptionParser::eNoArgument, NULL, 0, eArgTypeNone , "Enable rsync." }, 1204263363Semaste { LLDB_OPT_SET_ALL, false, "rsync-opts" , 'R', OptionParser::eRequiredArgument, NULL, 0, eArgTypeCommandName , "Platform-specific options required for rsync to work." }, 1205263363Semaste { LLDB_OPT_SET_ALL, false, "rsync-prefix" , 'P', OptionParser::eRequiredArgument, NULL, 0, eArgTypeCommandName , "Platform-specific rsync prefix put before the remote path." }, 1206263363Semaste { LLDB_OPT_SET_ALL, false, "ignore-remote-hostname" , 'i', OptionParser::eNoArgument, NULL, 0, eArgTypeNone , "Do not automatically fill in the remote hostname when composing the rsync command." }, 1207263363Semaste}; 1208263363Semaste 1209263363Semastestatic OptionDefinition 1210263363Semasteg_ssh_option_table[] = 1211263363Semaste{ 1212263363Semaste { LLDB_OPT_SET_ALL, false, "ssh" , 's', OptionParser::eNoArgument, NULL, 0, eArgTypeNone , "Enable SSH." }, 1213263363Semaste { LLDB_OPT_SET_ALL, false, "ssh-opts" , 'S', OptionParser::eRequiredArgument, NULL, 0, eArgTypeCommandName , "Platform-specific options required for SSH to work." }, 1214263363Semaste}; 1215263363Semaste 1216263363Semastestatic OptionDefinition 1217263363Semasteg_caching_option_table[] = 1218263363Semaste{ 1219263363Semaste { LLDB_OPT_SET_ALL, false, "local-cache-dir" , 'c', OptionParser::eRequiredArgument, NULL, 0, eArgTypePath , "Path in which to store local copies of files." }, 1220263363Semaste}; 1221263363Semaste 1222263363SemasteOptionGroupPlatformRSync::OptionGroupPlatformRSync () 1223263363Semaste{ 1224263363Semaste} 1225263363Semaste 1226263363SemasteOptionGroupPlatformRSync::~OptionGroupPlatformRSync () 1227263363Semaste{ 1228263363Semaste} 1229263363Semaste 1230263363Semasteconst lldb_private::OptionDefinition* 1231263363SemasteOptionGroupPlatformRSync::GetDefinitions () 1232263363Semaste{ 1233263363Semaste return g_rsync_option_table; 1234263363Semaste} 1235263363Semaste 1236263363Semastevoid 1237263363SemasteOptionGroupPlatformRSync::OptionParsingStarting (CommandInterpreter &interpreter) 1238263363Semaste{ 1239263363Semaste m_rsync = false; 1240263363Semaste m_rsync_opts.clear(); 1241263363Semaste m_rsync_prefix.clear(); 1242263363Semaste m_ignores_remote_hostname = false; 1243263363Semaste} 1244263363Semaste 1245263363Semastelldb_private::Error 1246263363SemasteOptionGroupPlatformRSync::SetOptionValue (CommandInterpreter &interpreter, 1247263363Semaste uint32_t option_idx, 1248263363Semaste const char *option_arg) 1249263363Semaste{ 1250263363Semaste Error error; 1251263363Semaste char short_option = (char) GetDefinitions()[option_idx].short_option; 1252263363Semaste switch (short_option) 1253263363Semaste { 1254263363Semaste case 'r': 1255263363Semaste m_rsync = true; 1256263363Semaste break; 1257263363Semaste 1258263363Semaste case 'R': 1259263363Semaste m_rsync_opts.assign(option_arg); 1260263363Semaste break; 1261263363Semaste 1262263363Semaste case 'P': 1263263363Semaste m_rsync_prefix.assign(option_arg); 1264263363Semaste break; 1265263363Semaste 1266263363Semaste case 'i': 1267263363Semaste m_ignores_remote_hostname = true; 1268263363Semaste break; 1269263363Semaste 1270263363Semaste default: 1271263363Semaste error.SetErrorStringWithFormat ("unrecognized option '%c'", short_option); 1272263363Semaste break; 1273263363Semaste } 1274254721Semaste 1275263363Semaste return error; 1276254721Semaste} 1277254721Semaste 1278263363Semasteuint32_t 1279263363SemasteOptionGroupPlatformRSync::GetNumDefinitions () 1280263363Semaste{ 1281263363Semaste return llvm::array_lengthof(g_rsync_option_table); 1282263363Semaste} 1283254721Semaste 1284254721Semastelldb::BreakpointSP 1285254721SemastePlatform::SetThreadCreationBreakpoint (lldb_private::Target &target) 1286254721Semaste{ 1287254721Semaste return lldb::BreakpointSP(); 1288254721Semaste} 1289254721Semaste 1290263363SemasteOptionGroupPlatformSSH::OptionGroupPlatformSSH () 1291263363Semaste{ 1292263363Semaste} 1293263363Semaste 1294263363SemasteOptionGroupPlatformSSH::~OptionGroupPlatformSSH () 1295263363Semaste{ 1296263363Semaste} 1297263363Semaste 1298263363Semasteconst lldb_private::OptionDefinition* 1299263363SemasteOptionGroupPlatformSSH::GetDefinitions () 1300263363Semaste{ 1301263363Semaste return g_ssh_option_table; 1302263363Semaste} 1303263363Semaste 1304263363Semastevoid 1305263363SemasteOptionGroupPlatformSSH::OptionParsingStarting (CommandInterpreter &interpreter) 1306263363Semaste{ 1307263363Semaste m_ssh = false; 1308263363Semaste m_ssh_opts.clear(); 1309263363Semaste} 1310263363Semaste 1311263363Semastelldb_private::Error 1312263363SemasteOptionGroupPlatformSSH::SetOptionValue (CommandInterpreter &interpreter, 1313263363Semaste uint32_t option_idx, 1314263363Semaste const char *option_arg) 1315263363Semaste{ 1316263363Semaste Error error; 1317263363Semaste char short_option = (char) GetDefinitions()[option_idx].short_option; 1318263363Semaste switch (short_option) 1319263363Semaste { 1320263363Semaste case 's': 1321263363Semaste m_ssh = true; 1322263363Semaste break; 1323263363Semaste 1324263363Semaste case 'S': 1325263363Semaste m_ssh_opts.assign(option_arg); 1326263363Semaste break; 1327263363Semaste 1328263363Semaste default: 1329263363Semaste error.SetErrorStringWithFormat ("unrecognized option '%c'", short_option); 1330263363Semaste break; 1331263363Semaste } 1332263363Semaste 1333263363Semaste return error; 1334263363Semaste} 1335263363Semaste 1336263363Semasteuint32_t 1337263363SemasteOptionGroupPlatformSSH::GetNumDefinitions () 1338263363Semaste{ 1339263363Semaste return llvm::array_lengthof(g_ssh_option_table); 1340263363Semaste} 1341263363Semaste 1342263363SemasteOptionGroupPlatformCaching::OptionGroupPlatformCaching () 1343263363Semaste{ 1344263363Semaste} 1345263363Semaste 1346263363SemasteOptionGroupPlatformCaching::~OptionGroupPlatformCaching () 1347263363Semaste{ 1348263363Semaste} 1349263363Semaste 1350263363Semasteconst lldb_private::OptionDefinition* 1351263363SemasteOptionGroupPlatformCaching::GetDefinitions () 1352263363Semaste{ 1353263363Semaste return g_caching_option_table; 1354263363Semaste} 1355263363Semaste 1356263363Semastevoid 1357263363SemasteOptionGroupPlatformCaching::OptionParsingStarting (CommandInterpreter &interpreter) 1358263363Semaste{ 1359263363Semaste m_cache_dir.clear(); 1360263363Semaste} 1361263363Semaste 1362263363Semastelldb_private::Error 1363263363SemasteOptionGroupPlatformCaching::SetOptionValue (CommandInterpreter &interpreter, 1364263363Semaste uint32_t option_idx, 1365263363Semaste const char *option_arg) 1366263363Semaste{ 1367263363Semaste Error error; 1368263363Semaste char short_option = (char) GetDefinitions()[option_idx].short_option; 1369263363Semaste switch (short_option) 1370263363Semaste { 1371263363Semaste case 'c': 1372263363Semaste m_cache_dir.assign(option_arg); 1373263363Semaste break; 1374263363Semaste 1375263363Semaste default: 1376263363Semaste error.SetErrorStringWithFormat ("unrecognized option '%c'", short_option); 1377263363Semaste break; 1378263363Semaste } 1379263363Semaste 1380263363Semaste return error; 1381263363Semaste} 1382263363Semaste 1383263363Semasteuint32_t 1384263363SemasteOptionGroupPlatformCaching::GetNumDefinitions () 1385263363Semaste{ 1386263363Semaste return llvm::array_lengthof(g_caching_option_table); 1387263363Semaste} 1388263363Semaste 1389254721Semastesize_t 1390254721SemastePlatform::GetEnvironment (StringList &environment) 1391254721Semaste{ 1392254721Semaste environment.Clear(); 1393254721Semaste return false; 1394254721Semaste} 1395269024Semaste 1396269024Semasteconst std::vector<ConstString> & 1397269024SemastePlatform::GetTrapHandlerSymbolNames () 1398269024Semaste{ 1399269024Semaste if (!m_calculated_trap_handlers) 1400269024Semaste { 1401269024Semaste CalculateTrapHandlerSymbolNames(); 1402269024Semaste m_calculated_trap_handlers = true; 1403269024Semaste } 1404269024Semaste return m_trap_handlers; 1405269024Semaste} 1406269024Semaste 1407