1 //===-- Platform.cpp ------------------------------------------------------===// 2 // 3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 4 // See https://llvm.org/LICENSE.txt for license information. 5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 6 // 7 //===----------------------------------------------------------------------===// 8 9 #include <algorithm> 10 #include <csignal> 11 #include <fstream> 12 #include <memory> 13 #include <vector> 14 15 #include "lldb/Breakpoint/BreakpointIDList.h" 16 #include "lldb/Breakpoint/BreakpointLocation.h" 17 #include "lldb/Core/Debugger.h" 18 #include "lldb/Core/Module.h" 19 #include "lldb/Core/ModuleSpec.h" 20 #include "lldb/Core/PluginManager.h" 21 #include "lldb/Core/StreamFile.h" 22 #include "lldb/Host/FileCache.h" 23 #include "lldb/Host/FileSystem.h" 24 #include "lldb/Host/Host.h" 25 #include "lldb/Host/HostInfo.h" 26 #include "lldb/Host/OptionParser.h" 27 #include "lldb/Interpreter/OptionValueFileSpec.h" 28 #include "lldb/Interpreter/OptionValueProperties.h" 29 #include "lldb/Interpreter/Property.h" 30 #include "lldb/Symbol/ObjectFile.h" 31 #include "lldb/Target/ModuleCache.h" 32 #include "lldb/Target/Platform.h" 33 #include "lldb/Target/Process.h" 34 #include "lldb/Target/Target.h" 35 #include "lldb/Target/UnixSignals.h" 36 #include "lldb/Utility/DataBufferHeap.h" 37 #include "lldb/Utility/FileSpec.h" 38 #include "lldb/Utility/LLDBLog.h" 39 #include "lldb/Utility/Log.h" 40 #include "lldb/Utility/Status.h" 41 #include "lldb/Utility/StructuredData.h" 42 #include "llvm/ADT/STLExtras.h" 43 #include "llvm/Support/FileSystem.h" 44 #include "llvm/Support/Path.h" 45 46 // Define these constants from POSIX mman.h rather than include the file so 47 // that they will be correct even when compiled on Linux. 48 #define MAP_PRIVATE 2 49 #define MAP_ANON 0x1000 50 51 using namespace lldb; 52 using namespace lldb_private; 53 54 // Use a singleton function for g_local_platform_sp to avoid init constructors 55 // since LLDB is often part of a shared library 56 static PlatformSP &GetHostPlatformSP() { 57 static PlatformSP g_platform_sp; 58 return g_platform_sp; 59 } 60 61 const char *Platform::GetHostPlatformName() { return "host"; } 62 63 namespace { 64 65 #define LLDB_PROPERTIES_platform 66 #include "TargetProperties.inc" 67 68 enum { 69 #define LLDB_PROPERTIES_platform 70 #include "TargetPropertiesEnum.inc" 71 }; 72 73 } // namespace 74 75 ConstString PlatformProperties::GetSettingName() { 76 static ConstString g_setting_name("platform"); 77 return g_setting_name; 78 } 79 80 PlatformProperties::PlatformProperties() { 81 m_collection_sp = std::make_shared<OptionValueProperties>(GetSettingName()); 82 m_collection_sp->Initialize(g_platform_properties); 83 84 auto module_cache_dir = GetModuleCacheDirectory(); 85 if (module_cache_dir) 86 return; 87 88 llvm::SmallString<64> user_home_dir; 89 if (!FileSystem::Instance().GetHomeDirectory(user_home_dir)) 90 return; 91 92 module_cache_dir = FileSpec(user_home_dir.c_str()); 93 module_cache_dir.AppendPathComponent(".lldb"); 94 module_cache_dir.AppendPathComponent("module_cache"); 95 SetDefaultModuleCacheDirectory(module_cache_dir); 96 SetModuleCacheDirectory(module_cache_dir); 97 } 98 99 bool PlatformProperties::GetUseModuleCache() const { 100 const auto idx = ePropertyUseModuleCache; 101 return m_collection_sp->GetPropertyAtIndexAsBoolean( 102 nullptr, idx, g_platform_properties[idx].default_uint_value != 0); 103 } 104 105 bool PlatformProperties::SetUseModuleCache(bool use_module_cache) { 106 return m_collection_sp->SetPropertyAtIndexAsBoolean( 107 nullptr, ePropertyUseModuleCache, use_module_cache); 108 } 109 110 FileSpec PlatformProperties::GetModuleCacheDirectory() const { 111 return m_collection_sp->GetPropertyAtIndexAsFileSpec( 112 nullptr, ePropertyModuleCacheDirectory); 113 } 114 115 bool PlatformProperties::SetModuleCacheDirectory(const FileSpec &dir_spec) { 116 return m_collection_sp->SetPropertyAtIndexAsFileSpec( 117 nullptr, ePropertyModuleCacheDirectory, dir_spec); 118 } 119 120 void PlatformProperties::SetDefaultModuleCacheDirectory( 121 const FileSpec &dir_spec) { 122 auto f_spec_opt = m_collection_sp->GetPropertyAtIndexAsOptionValueFileSpec( 123 nullptr, false, ePropertyModuleCacheDirectory); 124 assert(f_spec_opt); 125 f_spec_opt->SetDefaultValue(dir_spec); 126 } 127 128 /// Get the native host platform plug-in. 129 /// 130 /// There should only be one of these for each host that LLDB runs 131 /// upon that should be statically compiled in and registered using 132 /// preprocessor macros or other similar build mechanisms. 133 /// 134 /// This platform will be used as the default platform when launching 135 /// or attaching to processes unless another platform is specified. 136 PlatformSP Platform::GetHostPlatform() { return GetHostPlatformSP(); } 137 138 void Platform::Initialize() {} 139 140 void Platform::Terminate() {} 141 142 PlatformProperties &Platform::GetGlobalPlatformProperties() { 143 static PlatformProperties g_settings; 144 return g_settings; 145 } 146 147 void Platform::SetHostPlatform(const lldb::PlatformSP &platform_sp) { 148 // The native platform should use its static void Platform::Initialize() 149 // function to register itself as the native platform. 150 GetHostPlatformSP() = platform_sp; 151 } 152 153 Status Platform::GetFileWithUUID(const FileSpec &platform_file, 154 const UUID *uuid_ptr, FileSpec &local_file) { 155 // Default to the local case 156 local_file = platform_file; 157 return Status(); 158 } 159 160 FileSpecList 161 Platform::LocateExecutableScriptingResources(Target *target, Module &module, 162 Stream *feedback_stream) { 163 return FileSpecList(); 164 } 165 166 // PlatformSP 167 // Platform::FindPlugin (Process *process, ConstString plugin_name) 168 //{ 169 // PlatformCreateInstance create_callback = nullptr; 170 // if (plugin_name) 171 // { 172 // create_callback = 173 // PluginManager::GetPlatformCreateCallbackForPluginName (plugin_name); 174 // if (create_callback) 175 // { 176 // ArchSpec arch; 177 // if (process) 178 // { 179 // arch = process->GetTarget().GetArchitecture(); 180 // } 181 // PlatformSP platform_sp(create_callback(process, &arch)); 182 // if (platform_sp) 183 // return platform_sp; 184 // } 185 // } 186 // else 187 // { 188 // for (uint32_t idx = 0; (create_callback = 189 // PluginManager::GetPlatformCreateCallbackAtIndex(idx)) != nullptr; 190 // ++idx) 191 // { 192 // PlatformSP platform_sp(create_callback(process, nullptr)); 193 // if (platform_sp) 194 // return platform_sp; 195 // } 196 // } 197 // return PlatformSP(); 198 //} 199 200 Status Platform::GetSharedModule( 201 const ModuleSpec &module_spec, Process *process, ModuleSP &module_sp, 202 const FileSpecList *module_search_paths_ptr, 203 llvm::SmallVectorImpl<lldb::ModuleSP> *old_modules, bool *did_create_ptr) { 204 if (IsHost()) 205 return ModuleList::GetSharedModule(module_spec, module_sp, 206 module_search_paths_ptr, old_modules, 207 did_create_ptr, false); 208 209 // Module resolver lambda. 210 auto resolver = [&](const ModuleSpec &spec) { 211 Status error(eErrorTypeGeneric); 212 ModuleSpec resolved_spec; 213 // Check if we have sysroot set. 214 if (m_sdk_sysroot) { 215 // Prepend sysroot to module spec. 216 resolved_spec = spec; 217 resolved_spec.GetFileSpec().PrependPathComponent( 218 m_sdk_sysroot.GetStringRef()); 219 // Try to get shared module with resolved spec. 220 error = ModuleList::GetSharedModule(resolved_spec, module_sp, 221 module_search_paths_ptr, old_modules, 222 did_create_ptr, false); 223 } 224 // If we don't have sysroot or it didn't work then 225 // try original module spec. 226 if (!error.Success()) { 227 resolved_spec = spec; 228 error = ModuleList::GetSharedModule(resolved_spec, module_sp, 229 module_search_paths_ptr, old_modules, 230 did_create_ptr, false); 231 } 232 if (error.Success() && module_sp) 233 module_sp->SetPlatformFileSpec(resolved_spec.GetFileSpec()); 234 return error; 235 }; 236 237 return GetRemoteSharedModule(module_spec, process, module_sp, resolver, 238 did_create_ptr); 239 } 240 241 bool Platform::GetModuleSpec(const FileSpec &module_file_spec, 242 const ArchSpec &arch, ModuleSpec &module_spec) { 243 ModuleSpecList module_specs; 244 if (ObjectFile::GetModuleSpecifications(module_file_spec, 0, 0, 245 module_specs) == 0) 246 return false; 247 248 ModuleSpec matched_module_spec; 249 return module_specs.FindMatchingModuleSpec(ModuleSpec(module_file_spec, arch), 250 module_spec); 251 } 252 253 PlatformSP Platform::Create(llvm::StringRef name) { 254 lldb::PlatformSP platform_sp; 255 if (name == GetHostPlatformName()) 256 return GetHostPlatform(); 257 258 if (PlatformCreateInstance create_callback = 259 PluginManager::GetPlatformCreateCallbackForPluginName(name)) 260 return create_callback(true, nullptr); 261 return nullptr; 262 } 263 264 ArchSpec Platform::GetAugmentedArchSpec(Platform *platform, llvm::StringRef triple) { 265 if (platform) 266 return platform->GetAugmentedArchSpec(triple); 267 return HostInfo::GetAugmentedArchSpec(triple); 268 } 269 270 /// Default Constructor 271 Platform::Platform(bool is_host) 272 : m_is_host(is_host), m_os_version_set_while_connected(false), 273 m_system_arch_set_while_connected(false), m_max_uid_name_len(0), 274 m_max_gid_name_len(0), m_supports_rsync(false), m_rsync_opts(), 275 m_rsync_prefix(), m_supports_ssh(false), m_ssh_opts(), 276 m_ignores_remote_hostname(false), m_trap_handlers(), 277 m_calculated_trap_handlers(false), 278 m_module_cache(std::make_unique<ModuleCache>()) { 279 Log *log = GetLog(LLDBLog::Object); 280 LLDB_LOGF(log, "%p Platform::Platform()", static_cast<void *>(this)); 281 } 282 283 Platform::~Platform() = default; 284 285 void Platform::GetStatus(Stream &strm) { 286 strm.Format(" Platform: {0}\n", GetPluginName()); 287 288 ArchSpec arch(GetSystemArchitecture()); 289 if (arch.IsValid()) { 290 if (!arch.GetTriple().str().empty()) { 291 strm.Printf(" Triple: "); 292 arch.DumpTriple(strm.AsRawOstream()); 293 strm.EOL(); 294 } 295 } 296 297 llvm::VersionTuple os_version = GetOSVersion(); 298 if (!os_version.empty()) { 299 strm.Format("OS Version: {0}", os_version.getAsString()); 300 301 if (llvm::Optional<std::string> s = GetOSBuildString()) 302 strm.Format(" ({0})", *s); 303 304 strm.EOL(); 305 } 306 307 if (IsHost()) { 308 strm.Printf(" Hostname: %s\n", GetHostname()); 309 } else { 310 const bool is_connected = IsConnected(); 311 if (is_connected) 312 strm.Printf(" Hostname: %s\n", GetHostname()); 313 strm.Printf(" Connected: %s\n", is_connected ? "yes" : "no"); 314 } 315 316 if (GetSDKRootDirectory()) { 317 strm.Format(" Sysroot: {0}\n", GetSDKRootDirectory()); 318 } 319 if (GetWorkingDirectory()) { 320 strm.Printf("WorkingDir: %s\n", GetWorkingDirectory().GetCString()); 321 } 322 if (!IsConnected()) 323 return; 324 325 std::string specific_info(GetPlatformSpecificConnectionInformation()); 326 327 if (!specific_info.empty()) 328 strm.Printf("Platform-specific connection: %s\n", specific_info.c_str()); 329 330 if (llvm::Optional<std::string> s = GetOSKernelDescription()) 331 strm.Format(" Kernel: {0}\n", *s); 332 } 333 334 llvm::VersionTuple Platform::GetOSVersion(Process *process) { 335 std::lock_guard<std::mutex> guard(m_mutex); 336 337 if (IsHost()) { 338 if (m_os_version.empty()) { 339 // We have a local host platform 340 m_os_version = HostInfo::GetOSVersion(); 341 m_os_version_set_while_connected = !m_os_version.empty(); 342 } 343 } else { 344 // We have a remote platform. We can only fetch the remote 345 // OS version if we are connected, and we don't want to do it 346 // more than once. 347 348 const bool is_connected = IsConnected(); 349 350 bool fetch = false; 351 if (!m_os_version.empty()) { 352 // We have valid OS version info, check to make sure it wasn't manually 353 // set prior to connecting. If it was manually set prior to connecting, 354 // then lets fetch the actual OS version info if we are now connected. 355 if (is_connected && !m_os_version_set_while_connected) 356 fetch = true; 357 } else { 358 // We don't have valid OS version info, fetch it if we are connected 359 fetch = is_connected; 360 } 361 362 if (fetch) 363 m_os_version_set_while_connected = GetRemoteOSVersion(); 364 } 365 366 if (!m_os_version.empty()) 367 return m_os_version; 368 if (process) { 369 // Check with the process in case it can answer the question if a process 370 // was provided 371 return process->GetHostOSVersion(); 372 } 373 return llvm::VersionTuple(); 374 } 375 376 llvm::Optional<std::string> Platform::GetOSBuildString() { 377 if (IsHost()) 378 return HostInfo::GetOSBuildString(); 379 return GetRemoteOSBuildString(); 380 } 381 382 llvm::Optional<std::string> Platform::GetOSKernelDescription() { 383 if (IsHost()) 384 return HostInfo::GetOSKernelDescription(); 385 return GetRemoteOSKernelDescription(); 386 } 387 388 void Platform::AddClangModuleCompilationOptions( 389 Target *target, std::vector<std::string> &options) { 390 std::vector<std::string> default_compilation_options = { 391 "-x", "c++", "-Xclang", "-nostdsysteminc", "-Xclang", "-nostdsysteminc"}; 392 393 options.insert(options.end(), default_compilation_options.begin(), 394 default_compilation_options.end()); 395 } 396 397 FileSpec Platform::GetWorkingDirectory() { 398 if (IsHost()) { 399 llvm::SmallString<64> cwd; 400 if (llvm::sys::fs::current_path(cwd)) 401 return {}; 402 else { 403 FileSpec file_spec(cwd); 404 FileSystem::Instance().Resolve(file_spec); 405 return file_spec; 406 } 407 } else { 408 if (!m_working_dir) 409 m_working_dir = GetRemoteWorkingDirectory(); 410 return m_working_dir; 411 } 412 } 413 414 struct RecurseCopyBaton { 415 const FileSpec &dst; 416 Platform *platform_ptr; 417 Status error; 418 }; 419 420 static FileSystem::EnumerateDirectoryResult 421 RecurseCopy_Callback(void *baton, llvm::sys::fs::file_type ft, 422 llvm::StringRef path) { 423 RecurseCopyBaton *rc_baton = (RecurseCopyBaton *)baton; 424 FileSpec src(path); 425 namespace fs = llvm::sys::fs; 426 switch (ft) { 427 case fs::file_type::fifo_file: 428 case fs::file_type::socket_file: 429 // we have no way to copy pipes and sockets - ignore them and continue 430 return FileSystem::eEnumerateDirectoryResultNext; 431 break; 432 433 case fs::file_type::directory_file: { 434 // make the new directory and get in there 435 FileSpec dst_dir = rc_baton->dst; 436 if (!dst_dir.GetFilename()) 437 dst_dir.GetFilename() = src.GetLastPathComponent(); 438 Status error = rc_baton->platform_ptr->MakeDirectory( 439 dst_dir, lldb::eFilePermissionsDirectoryDefault); 440 if (error.Fail()) { 441 rc_baton->error.SetErrorStringWithFormat( 442 "unable to setup directory %s on remote end", dst_dir.GetCString()); 443 return FileSystem::eEnumerateDirectoryResultQuit; // got an error, bail out 444 } 445 446 // now recurse 447 std::string src_dir_path(src.GetPath()); 448 449 // Make a filespec that only fills in the directory of a FileSpec so when 450 // we enumerate we can quickly fill in the filename for dst copies 451 FileSpec recurse_dst; 452 recurse_dst.GetDirectory().SetCString(dst_dir.GetPath().c_str()); 453 RecurseCopyBaton rc_baton2 = {recurse_dst, rc_baton->platform_ptr, 454 Status()}; 455 FileSystem::Instance().EnumerateDirectory(src_dir_path, true, true, true, 456 RecurseCopy_Callback, &rc_baton2); 457 if (rc_baton2.error.Fail()) { 458 rc_baton->error.SetErrorString(rc_baton2.error.AsCString()); 459 return FileSystem::eEnumerateDirectoryResultQuit; // got an error, bail out 460 } 461 return FileSystem::eEnumerateDirectoryResultNext; 462 } break; 463 464 case fs::file_type::symlink_file: { 465 // copy the file and keep going 466 FileSpec dst_file = rc_baton->dst; 467 if (!dst_file.GetFilename()) 468 dst_file.GetFilename() = src.GetFilename(); 469 470 FileSpec src_resolved; 471 472 rc_baton->error = FileSystem::Instance().Readlink(src, src_resolved); 473 474 if (rc_baton->error.Fail()) 475 return FileSystem::eEnumerateDirectoryResultQuit; // got an error, bail out 476 477 rc_baton->error = 478 rc_baton->platform_ptr->CreateSymlink(dst_file, src_resolved); 479 480 if (rc_baton->error.Fail()) 481 return FileSystem::eEnumerateDirectoryResultQuit; // got an error, bail out 482 483 return FileSystem::eEnumerateDirectoryResultNext; 484 } break; 485 486 case fs::file_type::regular_file: { 487 // copy the file and keep going 488 FileSpec dst_file = rc_baton->dst; 489 if (!dst_file.GetFilename()) 490 dst_file.GetFilename() = src.GetFilename(); 491 Status err = rc_baton->platform_ptr->PutFile(src, dst_file); 492 if (err.Fail()) { 493 rc_baton->error.SetErrorString(err.AsCString()); 494 return FileSystem::eEnumerateDirectoryResultQuit; // got an error, bail out 495 } 496 return FileSystem::eEnumerateDirectoryResultNext; 497 } break; 498 499 default: 500 rc_baton->error.SetErrorStringWithFormat( 501 "invalid file detected during copy: %s", src.GetPath().c_str()); 502 return FileSystem::eEnumerateDirectoryResultQuit; // got an error, bail out 503 break; 504 } 505 llvm_unreachable("Unhandled file_type!"); 506 } 507 508 Status Platform::Install(const FileSpec &src, const FileSpec &dst) { 509 Status error; 510 511 Log *log = GetLog(LLDBLog::Platform); 512 LLDB_LOGF(log, "Platform::Install (src='%s', dst='%s')", 513 src.GetPath().c_str(), dst.GetPath().c_str()); 514 FileSpec fixed_dst(dst); 515 516 if (!fixed_dst.GetFilename()) 517 fixed_dst.GetFilename() = src.GetFilename(); 518 519 FileSpec working_dir = GetWorkingDirectory(); 520 521 if (dst) { 522 if (dst.GetDirectory()) { 523 const char first_dst_dir_char = dst.GetDirectory().GetCString()[0]; 524 if (first_dst_dir_char == '/' || first_dst_dir_char == '\\') { 525 fixed_dst.GetDirectory() = dst.GetDirectory(); 526 } 527 // If the fixed destination file doesn't have a directory yet, then we 528 // must have a relative path. We will resolve this relative path against 529 // the platform's working directory 530 if (!fixed_dst.GetDirectory()) { 531 FileSpec relative_spec; 532 std::string path; 533 if (working_dir) { 534 relative_spec = working_dir; 535 relative_spec.AppendPathComponent(dst.GetPath()); 536 fixed_dst.GetDirectory() = relative_spec.GetDirectory(); 537 } else { 538 error.SetErrorStringWithFormat( 539 "platform working directory must be valid for relative path '%s'", 540 dst.GetPath().c_str()); 541 return error; 542 } 543 } 544 } else { 545 if (working_dir) { 546 fixed_dst.GetDirectory().SetCString(working_dir.GetCString()); 547 } else { 548 error.SetErrorStringWithFormat( 549 "platform working directory must be valid for relative path '%s'", 550 dst.GetPath().c_str()); 551 return error; 552 } 553 } 554 } else { 555 if (working_dir) { 556 fixed_dst.GetDirectory().SetCString(working_dir.GetCString()); 557 } else { 558 error.SetErrorStringWithFormat("platform working directory must be valid " 559 "when destination directory is empty"); 560 return error; 561 } 562 } 563 564 LLDB_LOGF(log, "Platform::Install (src='%s', dst='%s') fixed_dst='%s'", 565 src.GetPath().c_str(), dst.GetPath().c_str(), 566 fixed_dst.GetPath().c_str()); 567 568 if (GetSupportsRSync()) { 569 error = PutFile(src, dst); 570 } else { 571 namespace fs = llvm::sys::fs; 572 switch (fs::get_file_type(src.GetPath(), false)) { 573 case fs::file_type::directory_file: { 574 llvm::sys::fs::remove(fixed_dst.GetPath()); 575 uint32_t permissions = FileSystem::Instance().GetPermissions(src); 576 if (permissions == 0) 577 permissions = eFilePermissionsDirectoryDefault; 578 error = MakeDirectory(fixed_dst, permissions); 579 if (error.Success()) { 580 // Make a filespec that only fills in the directory of a FileSpec so 581 // when we enumerate we can quickly fill in the filename for dst copies 582 FileSpec recurse_dst; 583 recurse_dst.GetDirectory().SetCString(fixed_dst.GetCString()); 584 std::string src_dir_path(src.GetPath()); 585 RecurseCopyBaton baton = {recurse_dst, this, Status()}; 586 FileSystem::Instance().EnumerateDirectory( 587 src_dir_path, true, true, true, RecurseCopy_Callback, &baton); 588 return baton.error; 589 } 590 } break; 591 592 case fs::file_type::regular_file: 593 llvm::sys::fs::remove(fixed_dst.GetPath()); 594 error = PutFile(src, fixed_dst); 595 break; 596 597 case fs::file_type::symlink_file: { 598 llvm::sys::fs::remove(fixed_dst.GetPath()); 599 FileSpec src_resolved; 600 error = FileSystem::Instance().Readlink(src, src_resolved); 601 if (error.Success()) 602 error = CreateSymlink(dst, src_resolved); 603 } break; 604 case fs::file_type::fifo_file: 605 error.SetErrorString("platform install doesn't handle pipes"); 606 break; 607 case fs::file_type::socket_file: 608 error.SetErrorString("platform install doesn't handle sockets"); 609 break; 610 default: 611 error.SetErrorString( 612 "platform install doesn't handle non file or directory items"); 613 break; 614 } 615 } 616 return error; 617 } 618 619 bool Platform::SetWorkingDirectory(const FileSpec &file_spec) { 620 if (IsHost()) { 621 Log *log = GetLog(LLDBLog::Platform); 622 LLDB_LOG(log, "{0}", file_spec); 623 if (std::error_code ec = llvm::sys::fs::set_current_path(file_spec.GetPath())) { 624 LLDB_LOG(log, "error: {0}", ec.message()); 625 return false; 626 } 627 return true; 628 } else { 629 m_working_dir.Clear(); 630 return SetRemoteWorkingDirectory(file_spec); 631 } 632 } 633 634 Status Platform::MakeDirectory(const FileSpec &file_spec, 635 uint32_t permissions) { 636 if (IsHost()) 637 return llvm::sys::fs::create_directory(file_spec.GetPath(), permissions); 638 else { 639 Status error; 640 error.SetErrorStringWithFormatv("remote platform {0} doesn't support {1}", 641 GetPluginName(), LLVM_PRETTY_FUNCTION); 642 return error; 643 } 644 } 645 646 Status Platform::GetFilePermissions(const FileSpec &file_spec, 647 uint32_t &file_permissions) { 648 if (IsHost()) { 649 auto Value = llvm::sys::fs::getPermissions(file_spec.GetPath()); 650 if (Value) 651 file_permissions = Value.get(); 652 return Status(Value.getError()); 653 } else { 654 Status error; 655 error.SetErrorStringWithFormatv("remote platform {0} doesn't support {1}", 656 GetPluginName(), LLVM_PRETTY_FUNCTION); 657 return error; 658 } 659 } 660 661 Status Platform::SetFilePermissions(const FileSpec &file_spec, 662 uint32_t file_permissions) { 663 if (IsHost()) { 664 auto Perms = static_cast<llvm::sys::fs::perms>(file_permissions); 665 return llvm::sys::fs::setPermissions(file_spec.GetPath(), Perms); 666 } else { 667 Status error; 668 error.SetErrorStringWithFormatv("remote platform {0} doesn't support {1}", 669 GetPluginName(), LLVM_PRETTY_FUNCTION); 670 return error; 671 } 672 } 673 674 user_id_t Platform::OpenFile(const FileSpec &file_spec, 675 File::OpenOptions flags, uint32_t mode, 676 Status &error) { 677 if (IsHost()) 678 return FileCache::GetInstance().OpenFile(file_spec, flags, mode, error); 679 return UINT64_MAX; 680 } 681 682 bool Platform::CloseFile(user_id_t fd, Status &error) { 683 if (IsHost()) 684 return FileCache::GetInstance().CloseFile(fd, error); 685 return false; 686 } 687 688 user_id_t Platform::GetFileSize(const FileSpec &file_spec) { 689 if (!IsHost()) 690 return UINT64_MAX; 691 692 uint64_t Size; 693 if (llvm::sys::fs::file_size(file_spec.GetPath(), Size)) 694 return 0; 695 return Size; 696 } 697 698 uint64_t Platform::ReadFile(lldb::user_id_t fd, uint64_t offset, void *dst, 699 uint64_t dst_len, Status &error) { 700 if (IsHost()) 701 return FileCache::GetInstance().ReadFile(fd, offset, dst, dst_len, error); 702 error.SetErrorStringWithFormatv( 703 "Platform::ReadFile() is not supported in the {0} platform", 704 GetPluginName()); 705 return -1; 706 } 707 708 uint64_t Platform::WriteFile(lldb::user_id_t fd, uint64_t offset, 709 const void *src, uint64_t src_len, Status &error) { 710 if (IsHost()) 711 return FileCache::GetInstance().WriteFile(fd, offset, src, src_len, error); 712 error.SetErrorStringWithFormatv( 713 "Platform::WriteFile() is not supported in the {0} platform", 714 GetPluginName()); 715 return -1; 716 } 717 718 UserIDResolver &Platform::GetUserIDResolver() { 719 if (IsHost()) 720 return HostInfo::GetUserIDResolver(); 721 return UserIDResolver::GetNoopResolver(); 722 } 723 724 const char *Platform::GetHostname() { 725 if (IsHost()) 726 return "127.0.0.1"; 727 728 if (m_hostname.empty()) 729 return nullptr; 730 return m_hostname.c_str(); 731 } 732 733 ConstString Platform::GetFullNameForDylib(ConstString basename) { 734 return basename; 735 } 736 737 bool Platform::SetRemoteWorkingDirectory(const FileSpec &working_dir) { 738 Log *log = GetLog(LLDBLog::Platform); 739 LLDB_LOGF(log, "Platform::SetRemoteWorkingDirectory('%s')", 740 working_dir.GetCString()); 741 m_working_dir = working_dir; 742 return true; 743 } 744 745 bool Platform::SetOSVersion(llvm::VersionTuple version) { 746 if (IsHost()) { 747 // We don't need anyone setting the OS version for the host platform, we 748 // should be able to figure it out by calling HostInfo::GetOSVersion(...). 749 return false; 750 } else { 751 // We have a remote platform, allow setting the target OS version if we 752 // aren't connected, since if we are connected, we should be able to 753 // request the remote OS version from the connected platform. 754 if (IsConnected()) 755 return false; 756 else { 757 // We aren't connected and we might want to set the OS version ahead of 758 // time before we connect so we can peruse files and use a local SDK or 759 // PDK cache of support files to disassemble or do other things. 760 m_os_version = version; 761 return true; 762 } 763 } 764 return false; 765 } 766 767 Status 768 Platform::ResolveExecutable(const ModuleSpec &module_spec, 769 lldb::ModuleSP &exe_module_sp, 770 const FileSpecList *module_search_paths_ptr) { 771 Status error; 772 773 if (FileSystem::Instance().Exists(module_spec.GetFileSpec())) { 774 if (module_spec.GetArchitecture().IsValid()) { 775 error = ModuleList::GetSharedModule(module_spec, exe_module_sp, 776 module_search_paths_ptr, nullptr, 777 nullptr); 778 } else { 779 // No valid architecture was specified, ask the platform for the 780 // architectures that we should be using (in the correct order) and see 781 // if we can find a match that way 782 ModuleSpec arch_module_spec(module_spec); 783 ArchSpec process_host_arch; 784 for (const ArchSpec &arch : 785 GetSupportedArchitectures(process_host_arch)) { 786 arch_module_spec.GetArchitecture() = arch; 787 error = ModuleList::GetSharedModule(arch_module_spec, exe_module_sp, 788 module_search_paths_ptr, nullptr, 789 nullptr); 790 // Did we find an executable using one of the 791 if (error.Success() && exe_module_sp) 792 break; 793 } 794 } 795 } else { 796 error.SetErrorStringWithFormat( 797 "'%s' does not exist", module_spec.GetFileSpec().GetPath().c_str()); 798 } 799 return error; 800 } 801 802 Status 803 Platform::ResolveRemoteExecutable(const ModuleSpec &module_spec, 804 lldb::ModuleSP &exe_module_sp, 805 const FileSpecList *module_search_paths_ptr) { 806 Status error; 807 808 // We may connect to a process and use the provided executable (Don't use 809 // local $PATH). 810 ModuleSpec resolved_module_spec(module_spec); 811 812 // Resolve any executable within a bundle on MacOSX 813 Host::ResolveExecutableInBundle(resolved_module_spec.GetFileSpec()); 814 815 if (FileSystem::Instance().Exists(resolved_module_spec.GetFileSpec()) || 816 module_spec.GetUUID().IsValid()) { 817 if (resolved_module_spec.GetArchitecture().IsValid() || 818 resolved_module_spec.GetUUID().IsValid()) { 819 error = ModuleList::GetSharedModule(resolved_module_spec, exe_module_sp, 820 module_search_paths_ptr, nullptr, 821 nullptr); 822 823 if (exe_module_sp && exe_module_sp->GetObjectFile()) 824 return error; 825 exe_module_sp.reset(); 826 } 827 // No valid architecture was specified or the exact arch wasn't found so 828 // ask the platform for the architectures that we should be using (in the 829 // correct order) and see if we can find a match that way 830 StreamString arch_names; 831 llvm::ListSeparator LS; 832 ArchSpec process_host_arch; 833 for (const ArchSpec &arch : GetSupportedArchitectures(process_host_arch)) { 834 resolved_module_spec.GetArchitecture() = arch; 835 error = ModuleList::GetSharedModule(resolved_module_spec, exe_module_sp, 836 module_search_paths_ptr, nullptr, 837 nullptr); 838 // Did we find an executable using one of the 839 if (error.Success()) { 840 if (exe_module_sp && exe_module_sp->GetObjectFile()) 841 break; 842 else 843 error.SetErrorToGenericError(); 844 } 845 846 arch_names << LS << arch.GetArchitectureName(); 847 } 848 849 if (error.Fail() || !exe_module_sp) { 850 if (FileSystem::Instance().Readable(resolved_module_spec.GetFileSpec())) { 851 error.SetErrorStringWithFormatv( 852 "'{0}' doesn't contain any '{1}' platform architectures: {2}", 853 resolved_module_spec.GetFileSpec(), GetPluginName(), 854 arch_names.GetData()); 855 } else { 856 error.SetErrorStringWithFormatv("'{0}' is not readable", 857 resolved_module_spec.GetFileSpec()); 858 } 859 } 860 } else { 861 error.SetErrorStringWithFormatv("'{0}' does not exist", 862 resolved_module_spec.GetFileSpec()); 863 } 864 865 return error; 866 } 867 868 Status Platform::ResolveSymbolFile(Target &target, const ModuleSpec &sym_spec, 869 FileSpec &sym_file) { 870 Status error; 871 if (FileSystem::Instance().Exists(sym_spec.GetSymbolFileSpec())) 872 sym_file = sym_spec.GetSymbolFileSpec(); 873 else 874 error.SetErrorString("unable to resolve symbol file"); 875 return error; 876 } 877 878 bool Platform::ResolveRemotePath(const FileSpec &platform_path, 879 FileSpec &resolved_platform_path) { 880 resolved_platform_path = platform_path; 881 FileSystem::Instance().Resolve(resolved_platform_path); 882 return true; 883 } 884 885 const ArchSpec &Platform::GetSystemArchitecture() { 886 if (IsHost()) { 887 if (!m_system_arch.IsValid()) { 888 // We have a local host platform 889 m_system_arch = HostInfo::GetArchitecture(); 890 m_system_arch_set_while_connected = m_system_arch.IsValid(); 891 } 892 } else { 893 // We have a remote platform. We can only fetch the remote system 894 // architecture if we are connected, and we don't want to do it more than 895 // once. 896 897 const bool is_connected = IsConnected(); 898 899 bool fetch = false; 900 if (m_system_arch.IsValid()) { 901 // We have valid OS version info, check to make sure it wasn't manually 902 // set prior to connecting. If it was manually set prior to connecting, 903 // then lets fetch the actual OS version info if we are now connected. 904 if (is_connected && !m_system_arch_set_while_connected) 905 fetch = true; 906 } else { 907 // We don't have valid OS version info, fetch it if we are connected 908 fetch = is_connected; 909 } 910 911 if (fetch) { 912 m_system_arch = GetRemoteSystemArchitecture(); 913 m_system_arch_set_while_connected = m_system_arch.IsValid(); 914 } 915 } 916 return m_system_arch; 917 } 918 919 ArchSpec Platform::GetAugmentedArchSpec(llvm::StringRef triple) { 920 if (triple.empty()) 921 return ArchSpec(); 922 llvm::Triple normalized_triple(llvm::Triple::normalize(triple)); 923 if (!ArchSpec::ContainsOnlyArch(normalized_triple)) 924 return ArchSpec(triple); 925 926 if (auto kind = HostInfo::ParseArchitectureKind(triple)) 927 return HostInfo::GetArchitecture(*kind); 928 929 ArchSpec compatible_arch; 930 ArchSpec raw_arch(triple); 931 if (!IsCompatibleArchitecture(raw_arch, {}, false, &compatible_arch)) 932 return raw_arch; 933 934 if (!compatible_arch.IsValid()) 935 return ArchSpec(normalized_triple); 936 937 const llvm::Triple &compatible_triple = compatible_arch.GetTriple(); 938 if (normalized_triple.getVendorName().empty()) 939 normalized_triple.setVendor(compatible_triple.getVendor()); 940 if (normalized_triple.getOSName().empty()) 941 normalized_triple.setOS(compatible_triple.getOS()); 942 if (normalized_triple.getEnvironmentName().empty()) 943 normalized_triple.setEnvironment(compatible_triple.getEnvironment()); 944 return ArchSpec(normalized_triple); 945 } 946 947 Status Platform::ConnectRemote(Args &args) { 948 Status error; 949 if (IsHost()) 950 error.SetErrorStringWithFormatv( 951 "The currently selected platform ({0}) is " 952 "the host platform and is always connected.", 953 GetPluginName()); 954 else 955 error.SetErrorStringWithFormatv( 956 "Platform::ConnectRemote() is not supported by {0}", GetPluginName()); 957 return error; 958 } 959 960 Status Platform::DisconnectRemote() { 961 Status error; 962 if (IsHost()) 963 error.SetErrorStringWithFormatv( 964 "The currently selected platform ({0}) is " 965 "the host platform and is always connected.", 966 GetPluginName()); 967 else 968 error.SetErrorStringWithFormatv( 969 "Platform::DisconnectRemote() is not supported by {0}", 970 GetPluginName()); 971 return error; 972 } 973 974 bool Platform::GetProcessInfo(lldb::pid_t pid, 975 ProcessInstanceInfo &process_info) { 976 // Take care of the host case so that each subclass can just call this 977 // function to get the host functionality. 978 if (IsHost()) 979 return Host::GetProcessInfo(pid, process_info); 980 return false; 981 } 982 983 uint32_t Platform::FindProcesses(const ProcessInstanceInfoMatch &match_info, 984 ProcessInstanceInfoList &process_infos) { 985 // Take care of the host case so that each subclass can just call this 986 // function to get the host functionality. 987 uint32_t match_count = 0; 988 if (IsHost()) 989 match_count = Host::FindProcesses(match_info, process_infos); 990 return match_count; 991 } 992 993 Status Platform::LaunchProcess(ProcessLaunchInfo &launch_info) { 994 Status error; 995 Log *log = GetLog(LLDBLog::Platform); 996 LLDB_LOGF(log, "Platform::%s()", __FUNCTION__); 997 998 // Take care of the host case so that each subclass can just call this 999 // function to get the host functionality. 1000 if (IsHost()) { 1001 if (::getenv("LLDB_LAUNCH_FLAG_LAUNCH_IN_TTY")) 1002 launch_info.GetFlags().Set(eLaunchFlagLaunchInTTY); 1003 1004 if (launch_info.GetFlags().Test(eLaunchFlagLaunchInShell)) { 1005 const bool will_debug = launch_info.GetFlags().Test(eLaunchFlagDebug); 1006 const bool first_arg_is_full_shell_command = false; 1007 uint32_t num_resumes = GetResumeCountForLaunchInfo(launch_info); 1008 if (log) { 1009 const FileSpec &shell = launch_info.GetShell(); 1010 std::string shell_str = (shell) ? shell.GetPath() : "<null>"; 1011 LLDB_LOGF(log, 1012 "Platform::%s GetResumeCountForLaunchInfo() returned %" PRIu32 1013 ", shell is '%s'", 1014 __FUNCTION__, num_resumes, shell_str.c_str()); 1015 } 1016 1017 if (!launch_info.ConvertArgumentsForLaunchingInShell( 1018 error, will_debug, first_arg_is_full_shell_command, num_resumes)) 1019 return error; 1020 } else if (launch_info.GetFlags().Test(eLaunchFlagShellExpandArguments)) { 1021 error = ShellExpandArguments(launch_info); 1022 if (error.Fail()) { 1023 error.SetErrorStringWithFormat("shell expansion failed (reason: %s). " 1024 "consider launching with 'process " 1025 "launch'.", 1026 error.AsCString("unknown")); 1027 return error; 1028 } 1029 } 1030 1031 LLDB_LOGF(log, "Platform::%s final launch_info resume count: %" PRIu32, 1032 __FUNCTION__, launch_info.GetResumeCount()); 1033 1034 error = Host::LaunchProcess(launch_info); 1035 } else 1036 error.SetErrorString( 1037 "base lldb_private::Platform class can't launch remote processes"); 1038 return error; 1039 } 1040 1041 Status Platform::ShellExpandArguments(ProcessLaunchInfo &launch_info) { 1042 if (IsHost()) 1043 return Host::ShellExpandArguments(launch_info); 1044 return Status("base lldb_private::Platform class can't expand arguments"); 1045 } 1046 1047 Status Platform::KillProcess(const lldb::pid_t pid) { 1048 Log *log = GetLog(LLDBLog::Platform); 1049 LLDB_LOGF(log, "Platform::%s, pid %" PRIu64, __FUNCTION__, pid); 1050 1051 if (!IsHost()) { 1052 return Status( 1053 "base lldb_private::Platform class can't kill remote processes"); 1054 } 1055 Host::Kill(pid, SIGKILL); 1056 return Status(); 1057 } 1058 1059 lldb::ProcessSP Platform::DebugProcess(ProcessLaunchInfo &launch_info, 1060 Debugger &debugger, Target &target, 1061 Status &error) { 1062 Log *log = GetLog(LLDBLog::Platform); 1063 LLDB_LOG(log, "target = {0})", &target); 1064 1065 ProcessSP process_sp; 1066 // Make sure we stop at the entry point 1067 launch_info.GetFlags().Set(eLaunchFlagDebug); 1068 // We always launch the process we are going to debug in a separate process 1069 // group, since then we can handle ^C interrupts ourselves w/o having to 1070 // worry about the target getting them as well. 1071 launch_info.SetLaunchInSeparateProcessGroup(true); 1072 1073 // Allow any StructuredData process-bound plugins to adjust the launch info 1074 // if needed 1075 size_t i = 0; 1076 bool iteration_complete = false; 1077 // Note iteration can't simply go until a nullptr callback is returned, as it 1078 // is valid for a plugin to not supply a filter. 1079 auto get_filter_func = PluginManager::GetStructuredDataFilterCallbackAtIndex; 1080 for (auto filter_callback = get_filter_func(i, iteration_complete); 1081 !iteration_complete; 1082 filter_callback = get_filter_func(++i, iteration_complete)) { 1083 if (filter_callback) { 1084 // Give this ProcessLaunchInfo filter a chance to adjust the launch info. 1085 error = (*filter_callback)(launch_info, &target); 1086 if (!error.Success()) { 1087 LLDB_LOGF(log, 1088 "Platform::%s() StructuredDataPlugin launch " 1089 "filter failed.", 1090 __FUNCTION__); 1091 return process_sp; 1092 } 1093 } 1094 } 1095 1096 error = LaunchProcess(launch_info); 1097 if (error.Success()) { 1098 LLDB_LOGF(log, 1099 "Platform::%s LaunchProcess() call succeeded (pid=%" PRIu64 ")", 1100 __FUNCTION__, launch_info.GetProcessID()); 1101 if (launch_info.GetProcessID() != LLDB_INVALID_PROCESS_ID) { 1102 ProcessAttachInfo attach_info(launch_info); 1103 process_sp = Attach(attach_info, debugger, &target, error); 1104 if (process_sp) { 1105 LLDB_LOG(log, "Attach() succeeded, Process plugin: {0}", 1106 process_sp->GetPluginName()); 1107 launch_info.SetHijackListener(attach_info.GetHijackListener()); 1108 1109 // Since we attached to the process, it will think it needs to detach 1110 // if the process object just goes away without an explicit call to 1111 // Process::Kill() or Process::Detach(), so let it know to kill the 1112 // process if this happens. 1113 process_sp->SetShouldDetach(false); 1114 1115 // If we didn't have any file actions, the pseudo terminal might have 1116 // been used where the secondary side was given as the file to open for 1117 // stdin/out/err after we have already opened the primary so we can 1118 // read/write stdin/out/err. 1119 int pty_fd = launch_info.GetPTY().ReleasePrimaryFileDescriptor(); 1120 if (pty_fd != PseudoTerminal::invalid_fd) { 1121 process_sp->SetSTDIOFileDescriptor(pty_fd); 1122 } 1123 } else { 1124 LLDB_LOGF(log, "Platform::%s Attach() failed: %s", __FUNCTION__, 1125 error.AsCString()); 1126 } 1127 } else { 1128 LLDB_LOGF(log, 1129 "Platform::%s LaunchProcess() returned launch_info with " 1130 "invalid process id", 1131 __FUNCTION__); 1132 } 1133 } else { 1134 LLDB_LOGF(log, "Platform::%s LaunchProcess() failed: %s", __FUNCTION__, 1135 error.AsCString()); 1136 } 1137 1138 return process_sp; 1139 } 1140 1141 std::vector<ArchSpec> 1142 Platform::CreateArchList(llvm::ArrayRef<llvm::Triple::ArchType> archs, 1143 llvm::Triple::OSType os) { 1144 std::vector<ArchSpec> list; 1145 for(auto arch : archs) { 1146 llvm::Triple triple; 1147 triple.setArch(arch); 1148 triple.setOS(os); 1149 list.push_back(ArchSpec(triple)); 1150 } 1151 return list; 1152 } 1153 1154 /// Lets a platform answer if it is compatible with a given 1155 /// architecture and the target triple contained within. 1156 bool Platform::IsCompatibleArchitecture(const ArchSpec &arch, 1157 const ArchSpec &process_host_arch, 1158 bool exact_arch_match, 1159 ArchSpec *compatible_arch_ptr) { 1160 // If the architecture is invalid, we must answer true... 1161 if (arch.IsValid()) { 1162 ArchSpec platform_arch; 1163 auto match = exact_arch_match ? &ArchSpec::IsExactMatch 1164 : &ArchSpec::IsCompatibleMatch; 1165 for (const ArchSpec &platform_arch : 1166 GetSupportedArchitectures(process_host_arch)) { 1167 if ((arch.*match)(platform_arch)) { 1168 if (compatible_arch_ptr) 1169 *compatible_arch_ptr = platform_arch; 1170 return true; 1171 } 1172 } 1173 } 1174 if (compatible_arch_ptr) 1175 compatible_arch_ptr->Clear(); 1176 return false; 1177 } 1178 1179 Status Platform::PutFile(const FileSpec &source, const FileSpec &destination, 1180 uint32_t uid, uint32_t gid) { 1181 Log *log = GetLog(LLDBLog::Platform); 1182 LLDB_LOGF(log, "[PutFile] Using block by block transfer....\n"); 1183 1184 auto source_open_options = 1185 File::eOpenOptionReadOnly | File::eOpenOptionCloseOnExec; 1186 namespace fs = llvm::sys::fs; 1187 if (fs::is_symlink_file(source.GetPath())) 1188 source_open_options |= File::eOpenOptionDontFollowSymlinks; 1189 1190 auto source_file = FileSystem::Instance().Open(source, source_open_options, 1191 lldb::eFilePermissionsUserRW); 1192 if (!source_file) 1193 return Status(source_file.takeError()); 1194 Status error; 1195 uint32_t permissions = source_file.get()->GetPermissions(error); 1196 if (permissions == 0) 1197 permissions = lldb::eFilePermissionsFileDefault; 1198 1199 lldb::user_id_t dest_file = OpenFile( 1200 destination, File::eOpenOptionCanCreate | File::eOpenOptionWriteOnly | 1201 File::eOpenOptionTruncate | File::eOpenOptionCloseOnExec, 1202 permissions, error); 1203 LLDB_LOGF(log, "dest_file = %" PRIu64 "\n", dest_file); 1204 1205 if (error.Fail()) 1206 return error; 1207 if (dest_file == UINT64_MAX) 1208 return Status("unable to open target file"); 1209 lldb::WritableDataBufferSP buffer_sp(new DataBufferHeap(1024 * 16, 0)); 1210 uint64_t offset = 0; 1211 for (;;) { 1212 size_t bytes_read = buffer_sp->GetByteSize(); 1213 error = source_file.get()->Read(buffer_sp->GetBytes(), bytes_read); 1214 if (error.Fail() || bytes_read == 0) 1215 break; 1216 1217 const uint64_t bytes_written = 1218 WriteFile(dest_file, offset, buffer_sp->GetBytes(), bytes_read, error); 1219 if (error.Fail()) 1220 break; 1221 1222 offset += bytes_written; 1223 if (bytes_written != bytes_read) { 1224 // We didn't write the correct number of bytes, so adjust the file 1225 // position in the source file we are reading from... 1226 source_file.get()->SeekFromStart(offset); 1227 } 1228 } 1229 CloseFile(dest_file, error); 1230 1231 if (uid == UINT32_MAX && gid == UINT32_MAX) 1232 return error; 1233 1234 // TODO: ChownFile? 1235 1236 return error; 1237 } 1238 1239 Status Platform::GetFile(const FileSpec &source, const FileSpec &destination) { 1240 Status error("unimplemented"); 1241 return error; 1242 } 1243 1244 Status 1245 Platform::CreateSymlink(const FileSpec &src, // The name of the link is in src 1246 const FileSpec &dst) // The symlink points to dst 1247 { 1248 if (IsHost()) 1249 return FileSystem::Instance().Symlink(src, dst); 1250 return Status("unimplemented"); 1251 } 1252 1253 bool Platform::GetFileExists(const lldb_private::FileSpec &file_spec) { 1254 if (IsHost()) 1255 return FileSystem::Instance().Exists(file_spec); 1256 return false; 1257 } 1258 1259 Status Platform::Unlink(const FileSpec &path) { 1260 if (IsHost()) 1261 return llvm::sys::fs::remove(path.GetPath()); 1262 return Status("unimplemented"); 1263 } 1264 1265 MmapArgList Platform::GetMmapArgumentList(const ArchSpec &arch, addr_t addr, 1266 addr_t length, unsigned prot, 1267 unsigned flags, addr_t fd, 1268 addr_t offset) { 1269 uint64_t flags_platform = 0; 1270 if (flags & eMmapFlagsPrivate) 1271 flags_platform |= MAP_PRIVATE; 1272 if (flags & eMmapFlagsAnon) 1273 flags_platform |= MAP_ANON; 1274 1275 MmapArgList args({addr, length, prot, flags_platform, fd, offset}); 1276 return args; 1277 } 1278 1279 lldb_private::Status Platform::RunShellCommand( 1280 llvm::StringRef command, 1281 const FileSpec & 1282 working_dir, // Pass empty FileSpec to use the current working directory 1283 int *status_ptr, // Pass nullptr if you don't want the process exit status 1284 int *signo_ptr, // Pass nullptr if you don't want the signal that caused the 1285 // process to exit 1286 std::string 1287 *command_output, // Pass nullptr if you don't want the command output 1288 const Timeout<std::micro> &timeout) { 1289 return RunShellCommand(llvm::StringRef(), command, working_dir, status_ptr, 1290 signo_ptr, command_output, timeout); 1291 } 1292 1293 lldb_private::Status Platform::RunShellCommand( 1294 llvm::StringRef shell, // Pass empty if you want to use the default 1295 // shell interpreter 1296 llvm::StringRef command, // Shouldn't be empty 1297 const FileSpec & 1298 working_dir, // Pass empty FileSpec to use the current working directory 1299 int *status_ptr, // Pass nullptr if you don't want the process exit status 1300 int *signo_ptr, // Pass nullptr if you don't want the signal that caused the 1301 // process to exit 1302 std::string 1303 *command_output, // Pass nullptr if you don't want the command output 1304 const Timeout<std::micro> &timeout) { 1305 if (IsHost()) 1306 return Host::RunShellCommand(shell, command, working_dir, status_ptr, 1307 signo_ptr, command_output, timeout); 1308 return Status("unable to run a remote command without a platform"); 1309 } 1310 1311 bool Platform::CalculateMD5(const FileSpec &file_spec, uint64_t &low, 1312 uint64_t &high) { 1313 if (!IsHost()) 1314 return false; 1315 auto Result = llvm::sys::fs::md5_contents(file_spec.GetPath()); 1316 if (!Result) 1317 return false; 1318 std::tie(high, low) = Result->words(); 1319 return true; 1320 } 1321 1322 void Platform::SetLocalCacheDirectory(const char *local) { 1323 m_local_cache_directory.assign(local); 1324 } 1325 1326 const char *Platform::GetLocalCacheDirectory() { 1327 return m_local_cache_directory.c_str(); 1328 } 1329 1330 static constexpr OptionDefinition g_rsync_option_table[] = { 1331 {LLDB_OPT_SET_ALL, false, "rsync", 'r', OptionParser::eNoArgument, nullptr, 1332 {}, 0, eArgTypeNone, "Enable rsync."}, 1333 {LLDB_OPT_SET_ALL, false, "rsync-opts", 'R', 1334 OptionParser::eRequiredArgument, nullptr, {}, 0, eArgTypeCommandName, 1335 "Platform-specific options required for rsync to work."}, 1336 {LLDB_OPT_SET_ALL, false, "rsync-prefix", 'P', 1337 OptionParser::eRequiredArgument, nullptr, {}, 0, eArgTypeCommandName, 1338 "Platform-specific rsync prefix put before the remote path."}, 1339 {LLDB_OPT_SET_ALL, false, "ignore-remote-hostname", 'i', 1340 OptionParser::eNoArgument, nullptr, {}, 0, eArgTypeNone, 1341 "Do not automatically fill in the remote hostname when composing the " 1342 "rsync command."}, 1343 }; 1344 1345 static constexpr OptionDefinition g_ssh_option_table[] = { 1346 {LLDB_OPT_SET_ALL, false, "ssh", 's', OptionParser::eNoArgument, nullptr, 1347 {}, 0, eArgTypeNone, "Enable SSH."}, 1348 {LLDB_OPT_SET_ALL, false, "ssh-opts", 'S', OptionParser::eRequiredArgument, 1349 nullptr, {}, 0, eArgTypeCommandName, 1350 "Platform-specific options required for SSH to work."}, 1351 }; 1352 1353 static constexpr OptionDefinition g_caching_option_table[] = { 1354 {LLDB_OPT_SET_ALL, false, "local-cache-dir", 'c', 1355 OptionParser::eRequiredArgument, nullptr, {}, 0, eArgTypePath, 1356 "Path in which to store local copies of files."}, 1357 }; 1358 1359 llvm::ArrayRef<OptionDefinition> OptionGroupPlatformRSync::GetDefinitions() { 1360 return llvm::makeArrayRef(g_rsync_option_table); 1361 } 1362 1363 void OptionGroupPlatformRSync::OptionParsingStarting( 1364 ExecutionContext *execution_context) { 1365 m_rsync = false; 1366 m_rsync_opts.clear(); 1367 m_rsync_prefix.clear(); 1368 m_ignores_remote_hostname = false; 1369 } 1370 1371 lldb_private::Status 1372 OptionGroupPlatformRSync::SetOptionValue(uint32_t option_idx, 1373 llvm::StringRef option_arg, 1374 ExecutionContext *execution_context) { 1375 Status error; 1376 char short_option = (char)GetDefinitions()[option_idx].short_option; 1377 switch (short_option) { 1378 case 'r': 1379 m_rsync = true; 1380 break; 1381 1382 case 'R': 1383 m_rsync_opts.assign(std::string(option_arg)); 1384 break; 1385 1386 case 'P': 1387 m_rsync_prefix.assign(std::string(option_arg)); 1388 break; 1389 1390 case 'i': 1391 m_ignores_remote_hostname = true; 1392 break; 1393 1394 default: 1395 error.SetErrorStringWithFormat("unrecognized option '%c'", short_option); 1396 break; 1397 } 1398 1399 return error; 1400 } 1401 1402 lldb::BreakpointSP 1403 Platform::SetThreadCreationBreakpoint(lldb_private::Target &target) { 1404 return lldb::BreakpointSP(); 1405 } 1406 1407 llvm::ArrayRef<OptionDefinition> OptionGroupPlatformSSH::GetDefinitions() { 1408 return llvm::makeArrayRef(g_ssh_option_table); 1409 } 1410 1411 void OptionGroupPlatformSSH::OptionParsingStarting( 1412 ExecutionContext *execution_context) { 1413 m_ssh = false; 1414 m_ssh_opts.clear(); 1415 } 1416 1417 lldb_private::Status 1418 OptionGroupPlatformSSH::SetOptionValue(uint32_t option_idx, 1419 llvm::StringRef option_arg, 1420 ExecutionContext *execution_context) { 1421 Status error; 1422 char short_option = (char)GetDefinitions()[option_idx].short_option; 1423 switch (short_option) { 1424 case 's': 1425 m_ssh = true; 1426 break; 1427 1428 case 'S': 1429 m_ssh_opts.assign(std::string(option_arg)); 1430 break; 1431 1432 default: 1433 error.SetErrorStringWithFormat("unrecognized option '%c'", short_option); 1434 break; 1435 } 1436 1437 return error; 1438 } 1439 1440 llvm::ArrayRef<OptionDefinition> OptionGroupPlatformCaching::GetDefinitions() { 1441 return llvm::makeArrayRef(g_caching_option_table); 1442 } 1443 1444 void OptionGroupPlatformCaching::OptionParsingStarting( 1445 ExecutionContext *execution_context) { 1446 m_cache_dir.clear(); 1447 } 1448 1449 lldb_private::Status OptionGroupPlatformCaching::SetOptionValue( 1450 uint32_t option_idx, llvm::StringRef option_arg, 1451 ExecutionContext *execution_context) { 1452 Status error; 1453 char short_option = (char)GetDefinitions()[option_idx].short_option; 1454 switch (short_option) { 1455 case 'c': 1456 m_cache_dir.assign(std::string(option_arg)); 1457 break; 1458 1459 default: 1460 error.SetErrorStringWithFormat("unrecognized option '%c'", short_option); 1461 break; 1462 } 1463 1464 return error; 1465 } 1466 1467 Environment Platform::GetEnvironment() { 1468 if (IsHost()) 1469 return Host::GetEnvironment(); 1470 return Environment(); 1471 } 1472 1473 const std::vector<ConstString> &Platform::GetTrapHandlerSymbolNames() { 1474 if (!m_calculated_trap_handlers) { 1475 std::lock_guard<std::mutex> guard(m_mutex); 1476 if (!m_calculated_trap_handlers) { 1477 CalculateTrapHandlerSymbolNames(); 1478 m_calculated_trap_handlers = true; 1479 } 1480 } 1481 return m_trap_handlers; 1482 } 1483 1484 Status 1485 Platform::GetCachedExecutable(ModuleSpec &module_spec, 1486 lldb::ModuleSP &module_sp, 1487 const FileSpecList *module_search_paths_ptr) { 1488 FileSpec platform_spec = module_spec.GetFileSpec(); 1489 Status error = GetRemoteSharedModule( 1490 module_spec, nullptr, module_sp, 1491 [&](const ModuleSpec &spec) { 1492 return ResolveRemoteExecutable(spec, module_sp, 1493 module_search_paths_ptr); 1494 }, 1495 nullptr); 1496 if (error.Success()) { 1497 module_spec.GetFileSpec() = module_sp->GetFileSpec(); 1498 module_spec.GetPlatformFileSpec() = platform_spec; 1499 } 1500 1501 return error; 1502 } 1503 1504 Status Platform::GetRemoteSharedModule(const ModuleSpec &module_spec, 1505 Process *process, 1506 lldb::ModuleSP &module_sp, 1507 const ModuleResolver &module_resolver, 1508 bool *did_create_ptr) { 1509 // Get module information from a target. 1510 ModuleSpec resolved_module_spec; 1511 ArchSpec process_host_arch; 1512 bool got_module_spec = false; 1513 if (process) { 1514 process_host_arch = process->GetSystemArchitecture(); 1515 // Try to get module information from the process 1516 if (process->GetModuleSpec(module_spec.GetFileSpec(), 1517 module_spec.GetArchitecture(), 1518 resolved_module_spec)) { 1519 if (!module_spec.GetUUID().IsValid() || 1520 module_spec.GetUUID() == resolved_module_spec.GetUUID()) { 1521 got_module_spec = true; 1522 } 1523 } 1524 } 1525 1526 if (!module_spec.GetArchitecture().IsValid()) { 1527 Status error; 1528 // No valid architecture was specified, ask the platform for the 1529 // architectures that we should be using (in the correct order) and see if 1530 // we can find a match that way 1531 ModuleSpec arch_module_spec(module_spec); 1532 for (const ArchSpec &arch : GetSupportedArchitectures(process_host_arch)) { 1533 arch_module_spec.GetArchitecture() = arch; 1534 error = ModuleList::GetSharedModule(arch_module_spec, module_sp, nullptr, 1535 nullptr, nullptr); 1536 // Did we find an executable using one of the 1537 if (error.Success() && module_sp) 1538 break; 1539 } 1540 if (module_sp) { 1541 resolved_module_spec = arch_module_spec; 1542 got_module_spec = true; 1543 } 1544 } 1545 1546 if (!got_module_spec) { 1547 // Get module information from a target. 1548 if (GetModuleSpec(module_spec.GetFileSpec(), module_spec.GetArchitecture(), 1549 resolved_module_spec)) { 1550 if (!module_spec.GetUUID().IsValid() || 1551 module_spec.GetUUID() == resolved_module_spec.GetUUID()) { 1552 got_module_spec = true; 1553 } 1554 } 1555 } 1556 1557 if (!got_module_spec) { 1558 // Fall back to the given module resolver, which may have its own 1559 // search logic. 1560 return module_resolver(module_spec); 1561 } 1562 1563 // If we are looking for a specific UUID, make sure resolved_module_spec has 1564 // the same one before we search. 1565 if (module_spec.GetUUID().IsValid()) { 1566 resolved_module_spec.GetUUID() = module_spec.GetUUID(); 1567 } 1568 1569 // Trying to find a module by UUID on local file system. 1570 const auto error = module_resolver(resolved_module_spec); 1571 if (error.Fail()) { 1572 if (GetCachedSharedModule(resolved_module_spec, module_sp, did_create_ptr)) 1573 return Status(); 1574 } 1575 1576 return error; 1577 } 1578 1579 bool Platform::GetCachedSharedModule(const ModuleSpec &module_spec, 1580 lldb::ModuleSP &module_sp, 1581 bool *did_create_ptr) { 1582 if (IsHost() || !GetGlobalPlatformProperties().GetUseModuleCache() || 1583 !GetGlobalPlatformProperties().GetModuleCacheDirectory()) 1584 return false; 1585 1586 Log *log = GetLog(LLDBLog::Platform); 1587 1588 // Check local cache for a module. 1589 auto error = m_module_cache->GetAndPut( 1590 GetModuleCacheRoot(), GetCacheHostname(), module_spec, 1591 [this](const ModuleSpec &module_spec, 1592 const FileSpec &tmp_download_file_spec) { 1593 return DownloadModuleSlice( 1594 module_spec.GetFileSpec(), module_spec.GetObjectOffset(), 1595 module_spec.GetObjectSize(), tmp_download_file_spec); 1596 1597 }, 1598 [this](const ModuleSP &module_sp, 1599 const FileSpec &tmp_download_file_spec) { 1600 return DownloadSymbolFile(module_sp, tmp_download_file_spec); 1601 }, 1602 module_sp, did_create_ptr); 1603 if (error.Success()) 1604 return true; 1605 1606 LLDB_LOGF(log, "Platform::%s - module %s not found in local cache: %s", 1607 __FUNCTION__, module_spec.GetUUID().GetAsString().c_str(), 1608 error.AsCString()); 1609 return false; 1610 } 1611 1612 Status Platform::DownloadModuleSlice(const FileSpec &src_file_spec, 1613 const uint64_t src_offset, 1614 const uint64_t src_size, 1615 const FileSpec &dst_file_spec) { 1616 Status error; 1617 1618 std::error_code EC; 1619 llvm::raw_fd_ostream dst(dst_file_spec.GetPath(), EC, llvm::sys::fs::OF_None); 1620 if (EC) { 1621 error.SetErrorStringWithFormat("unable to open destination file: %s", 1622 dst_file_spec.GetPath().c_str()); 1623 return error; 1624 } 1625 1626 auto src_fd = OpenFile(src_file_spec, File::eOpenOptionReadOnly, 1627 lldb::eFilePermissionsFileDefault, error); 1628 1629 if (error.Fail()) { 1630 error.SetErrorStringWithFormat("unable to open source file: %s", 1631 error.AsCString()); 1632 return error; 1633 } 1634 1635 std::vector<char> buffer(1024); 1636 auto offset = src_offset; 1637 uint64_t total_bytes_read = 0; 1638 while (total_bytes_read < src_size) { 1639 const auto to_read = std::min(static_cast<uint64_t>(buffer.size()), 1640 src_size - total_bytes_read); 1641 const uint64_t n_read = 1642 ReadFile(src_fd, offset, &buffer[0], to_read, error); 1643 if (error.Fail()) 1644 break; 1645 if (n_read == 0) { 1646 error.SetErrorString("read 0 bytes"); 1647 break; 1648 } 1649 offset += n_read; 1650 total_bytes_read += n_read; 1651 dst.write(&buffer[0], n_read); 1652 } 1653 1654 Status close_error; 1655 CloseFile(src_fd, close_error); // Ignoring close error. 1656 1657 return error; 1658 } 1659 1660 Status Platform::DownloadSymbolFile(const lldb::ModuleSP &module_sp, 1661 const FileSpec &dst_file_spec) { 1662 return Status( 1663 "Symbol file downloading not supported by the default platform."); 1664 } 1665 1666 FileSpec Platform::GetModuleCacheRoot() { 1667 auto dir_spec = GetGlobalPlatformProperties().GetModuleCacheDirectory(); 1668 dir_spec.AppendPathComponent(GetPluginName()); 1669 return dir_spec; 1670 } 1671 1672 const char *Platform::GetCacheHostname() { return GetHostname(); } 1673 1674 const UnixSignalsSP &Platform::GetRemoteUnixSignals() { 1675 static const auto s_default_unix_signals_sp = std::make_shared<UnixSignals>(); 1676 return s_default_unix_signals_sp; 1677 } 1678 1679 UnixSignalsSP Platform::GetUnixSignals() { 1680 if (IsHost()) 1681 return UnixSignals::CreateForHost(); 1682 return GetRemoteUnixSignals(); 1683 } 1684 1685 uint32_t Platform::LoadImage(lldb_private::Process *process, 1686 const lldb_private::FileSpec &local_file, 1687 const lldb_private::FileSpec &remote_file, 1688 lldb_private::Status &error) { 1689 if (local_file && remote_file) { 1690 // Both local and remote file was specified. Install the local file to the 1691 // given location. 1692 if (IsRemote() || local_file != remote_file) { 1693 error = Install(local_file, remote_file); 1694 if (error.Fail()) 1695 return LLDB_INVALID_IMAGE_TOKEN; 1696 } 1697 return DoLoadImage(process, remote_file, nullptr, error); 1698 } 1699 1700 if (local_file) { 1701 // Only local file was specified. Install it to the current working 1702 // directory. 1703 FileSpec target_file = GetWorkingDirectory(); 1704 target_file.AppendPathComponent(local_file.GetFilename().AsCString()); 1705 if (IsRemote() || local_file != target_file) { 1706 error = Install(local_file, target_file); 1707 if (error.Fail()) 1708 return LLDB_INVALID_IMAGE_TOKEN; 1709 } 1710 return DoLoadImage(process, target_file, nullptr, error); 1711 } 1712 1713 if (remote_file) { 1714 // Only remote file was specified so we don't have to do any copying 1715 return DoLoadImage(process, remote_file, nullptr, error); 1716 } 1717 1718 error.SetErrorString("Neither local nor remote file was specified"); 1719 return LLDB_INVALID_IMAGE_TOKEN; 1720 } 1721 1722 uint32_t Platform::DoLoadImage(lldb_private::Process *process, 1723 const lldb_private::FileSpec &remote_file, 1724 const std::vector<std::string> *paths, 1725 lldb_private::Status &error, 1726 lldb_private::FileSpec *loaded_image) { 1727 error.SetErrorString("LoadImage is not supported on the current platform"); 1728 return LLDB_INVALID_IMAGE_TOKEN; 1729 } 1730 1731 uint32_t Platform::LoadImageUsingPaths(lldb_private::Process *process, 1732 const lldb_private::FileSpec &remote_filename, 1733 const std::vector<std::string> &paths, 1734 lldb_private::Status &error, 1735 lldb_private::FileSpec *loaded_path) 1736 { 1737 FileSpec file_to_use; 1738 if (remote_filename.IsAbsolute()) 1739 file_to_use = FileSpec(remote_filename.GetFilename().GetStringRef(), 1740 1741 remote_filename.GetPathStyle()); 1742 else 1743 file_to_use = remote_filename; 1744 1745 return DoLoadImage(process, file_to_use, &paths, error, loaded_path); 1746 } 1747 1748 Status Platform::UnloadImage(lldb_private::Process *process, 1749 uint32_t image_token) { 1750 return Status("UnloadImage is not supported on the current platform"); 1751 } 1752 1753 lldb::ProcessSP Platform::ConnectProcess(llvm::StringRef connect_url, 1754 llvm::StringRef plugin_name, 1755 Debugger &debugger, Target *target, 1756 Status &error) { 1757 return DoConnectProcess(connect_url, plugin_name, debugger, nullptr, target, 1758 error); 1759 } 1760 1761 lldb::ProcessSP Platform::ConnectProcessSynchronous( 1762 llvm::StringRef connect_url, llvm::StringRef plugin_name, 1763 Debugger &debugger, Stream &stream, Target *target, Status &error) { 1764 return DoConnectProcess(connect_url, plugin_name, debugger, &stream, target, 1765 error); 1766 } 1767 1768 lldb::ProcessSP Platform::DoConnectProcess(llvm::StringRef connect_url, 1769 llvm::StringRef plugin_name, 1770 Debugger &debugger, Stream *stream, 1771 Target *target, Status &error) { 1772 error.Clear(); 1773 1774 if (!target) { 1775 ArchSpec arch; 1776 if (target && target->GetArchitecture().IsValid()) 1777 arch = target->GetArchitecture(); 1778 else 1779 arch = Target::GetDefaultArchitecture(); 1780 1781 const char *triple = ""; 1782 if (arch.IsValid()) 1783 triple = arch.GetTriple().getTriple().c_str(); 1784 1785 TargetSP new_target_sp; 1786 error = debugger.GetTargetList().CreateTarget( 1787 debugger, "", triple, eLoadDependentsNo, nullptr, new_target_sp); 1788 target = new_target_sp.get(); 1789 } 1790 1791 if (!target || error.Fail()) 1792 return nullptr; 1793 1794 lldb::ProcessSP process_sp = 1795 target->CreateProcess(debugger.GetListener(), plugin_name, nullptr, true); 1796 1797 if (!process_sp) 1798 return nullptr; 1799 1800 // If this private method is called with a stream we are synchronous. 1801 const bool synchronous = stream != nullptr; 1802 1803 ListenerSP listener_sp( 1804 Listener::MakeListener("lldb.Process.ConnectProcess.hijack")); 1805 if (synchronous) 1806 process_sp->HijackProcessEvents(listener_sp); 1807 1808 error = process_sp->ConnectRemote(connect_url); 1809 if (error.Fail()) { 1810 if (synchronous) 1811 process_sp->RestoreProcessEvents(); 1812 return nullptr; 1813 } 1814 1815 if (synchronous) { 1816 EventSP event_sp; 1817 process_sp->WaitForProcessToStop(llvm::None, &event_sp, true, listener_sp, 1818 nullptr); 1819 process_sp->RestoreProcessEvents(); 1820 bool pop_process_io_handler = false; 1821 Process::HandleProcessStateChangedEvent(event_sp, stream, 1822 pop_process_io_handler); 1823 } 1824 1825 return process_sp; 1826 } 1827 1828 size_t Platform::ConnectToWaitingProcesses(lldb_private::Debugger &debugger, 1829 lldb_private::Status &error) { 1830 error.Clear(); 1831 return 0; 1832 } 1833 1834 size_t Platform::GetSoftwareBreakpointTrapOpcode(Target &target, 1835 BreakpointSite *bp_site) { 1836 ArchSpec arch = target.GetArchitecture(); 1837 assert(arch.IsValid()); 1838 const uint8_t *trap_opcode = nullptr; 1839 size_t trap_opcode_size = 0; 1840 1841 switch (arch.GetMachine()) { 1842 case llvm::Triple::aarch64_32: 1843 case llvm::Triple::aarch64: { 1844 static const uint8_t g_aarch64_opcode[] = {0x00, 0x00, 0x20, 0xd4}; 1845 trap_opcode = g_aarch64_opcode; 1846 trap_opcode_size = sizeof(g_aarch64_opcode); 1847 } break; 1848 1849 case llvm::Triple::arc: { 1850 static const uint8_t g_hex_opcode[] = { 0xff, 0x7f }; 1851 trap_opcode = g_hex_opcode; 1852 trap_opcode_size = sizeof(g_hex_opcode); 1853 } break; 1854 1855 // TODO: support big-endian arm and thumb trap codes. 1856 case llvm::Triple::arm: { 1857 // The ARM reference recommends the use of 0xe7fddefe and 0xdefe but the 1858 // linux kernel does otherwise. 1859 static const uint8_t g_arm_breakpoint_opcode[] = {0xf0, 0x01, 0xf0, 0xe7}; 1860 static const uint8_t g_thumb_breakpoint_opcode[] = {0x01, 0xde}; 1861 1862 lldb::BreakpointLocationSP bp_loc_sp(bp_site->GetOwnerAtIndex(0)); 1863 AddressClass addr_class = AddressClass::eUnknown; 1864 1865 if (bp_loc_sp) { 1866 addr_class = bp_loc_sp->GetAddress().GetAddressClass(); 1867 if (addr_class == AddressClass::eUnknown && 1868 (bp_loc_sp->GetAddress().GetFileAddress() & 1)) 1869 addr_class = AddressClass::eCodeAlternateISA; 1870 } 1871 1872 if (addr_class == AddressClass::eCodeAlternateISA) { 1873 trap_opcode = g_thumb_breakpoint_opcode; 1874 trap_opcode_size = sizeof(g_thumb_breakpoint_opcode); 1875 } else { 1876 trap_opcode = g_arm_breakpoint_opcode; 1877 trap_opcode_size = sizeof(g_arm_breakpoint_opcode); 1878 } 1879 } break; 1880 1881 case llvm::Triple::avr: { 1882 static const uint8_t g_hex_opcode[] = {0x98, 0x95}; 1883 trap_opcode = g_hex_opcode; 1884 trap_opcode_size = sizeof(g_hex_opcode); 1885 } break; 1886 1887 case llvm::Triple::mips: 1888 case llvm::Triple::mips64: { 1889 static const uint8_t g_hex_opcode[] = {0x00, 0x00, 0x00, 0x0d}; 1890 trap_opcode = g_hex_opcode; 1891 trap_opcode_size = sizeof(g_hex_opcode); 1892 } break; 1893 1894 case llvm::Triple::mipsel: 1895 case llvm::Triple::mips64el: { 1896 static const uint8_t g_hex_opcode[] = {0x0d, 0x00, 0x00, 0x00}; 1897 trap_opcode = g_hex_opcode; 1898 trap_opcode_size = sizeof(g_hex_opcode); 1899 } break; 1900 1901 case llvm::Triple::systemz: { 1902 static const uint8_t g_hex_opcode[] = {0x00, 0x01}; 1903 trap_opcode = g_hex_opcode; 1904 trap_opcode_size = sizeof(g_hex_opcode); 1905 } break; 1906 1907 case llvm::Triple::hexagon: { 1908 static const uint8_t g_hex_opcode[] = {0x0c, 0xdb, 0x00, 0x54}; 1909 trap_opcode = g_hex_opcode; 1910 trap_opcode_size = sizeof(g_hex_opcode); 1911 } break; 1912 1913 case llvm::Triple::ppc: 1914 case llvm::Triple::ppc64: { 1915 static const uint8_t g_ppc_opcode[] = {0x7f, 0xe0, 0x00, 0x08}; 1916 trap_opcode = g_ppc_opcode; 1917 trap_opcode_size = sizeof(g_ppc_opcode); 1918 } break; 1919 1920 case llvm::Triple::ppc64le: { 1921 static const uint8_t g_ppc64le_opcode[] = {0x08, 0x00, 0xe0, 0x7f}; // trap 1922 trap_opcode = g_ppc64le_opcode; 1923 trap_opcode_size = sizeof(g_ppc64le_opcode); 1924 } break; 1925 1926 case llvm::Triple::x86: 1927 case llvm::Triple::x86_64: { 1928 static const uint8_t g_i386_opcode[] = {0xCC}; 1929 trap_opcode = g_i386_opcode; 1930 trap_opcode_size = sizeof(g_i386_opcode); 1931 } break; 1932 1933 default: 1934 return 0; 1935 } 1936 1937 assert(bp_site); 1938 if (bp_site->SetTrapOpcode(trap_opcode, trap_opcode_size)) 1939 return trap_opcode_size; 1940 1941 return 0; 1942 } 1943 1944 CompilerType Platform::GetSiginfoType(const llvm::Triple& triple) { 1945 return CompilerType(); 1946 } 1947 1948 Args Platform::GetExtraStartupCommands() { 1949 return {}; 1950 } 1951 1952 PlatformSP PlatformList::GetOrCreate(llvm::StringRef name) { 1953 std::lock_guard<std::recursive_mutex> guard(m_mutex); 1954 for (const PlatformSP &platform_sp : m_platforms) { 1955 if (platform_sp->GetName() == name) 1956 return platform_sp; 1957 } 1958 return Create(name); 1959 } 1960 1961 PlatformSP PlatformList::GetOrCreate(const ArchSpec &arch, 1962 const ArchSpec &process_host_arch, 1963 ArchSpec *platform_arch_ptr, 1964 Status &error) { 1965 std::lock_guard<std::recursive_mutex> guard(m_mutex); 1966 // First try exact arch matches across all platforms already created 1967 for (const auto &platform_sp : m_platforms) { 1968 if (platform_sp->IsCompatibleArchitecture(arch, process_host_arch, true, 1969 platform_arch_ptr)) 1970 return platform_sp; 1971 } 1972 1973 // Next try compatible arch matches across all platforms already created 1974 for (const auto &platform_sp : m_platforms) { 1975 if (platform_sp->IsCompatibleArchitecture(arch, process_host_arch, false, 1976 platform_arch_ptr)) 1977 return platform_sp; 1978 } 1979 1980 PlatformCreateInstance create_callback; 1981 // First try exact arch matches across all platform plug-ins 1982 uint32_t idx; 1983 for (idx = 0; 1984 (create_callback = PluginManager::GetPlatformCreateCallbackAtIndex(idx)); 1985 ++idx) { 1986 PlatformSP platform_sp = create_callback(false, &arch); 1987 if (platform_sp && platform_sp->IsCompatibleArchitecture( 1988 arch, process_host_arch, true, platform_arch_ptr)) { 1989 m_platforms.push_back(platform_sp); 1990 return platform_sp; 1991 } 1992 } 1993 // Next try compatible arch matches across all platform plug-ins 1994 for (idx = 0; 1995 (create_callback = PluginManager::GetPlatformCreateCallbackAtIndex(idx)); 1996 ++idx) { 1997 PlatformSP platform_sp = create_callback(false, &arch); 1998 if (platform_sp && platform_sp->IsCompatibleArchitecture( 1999 arch, process_host_arch, false, platform_arch_ptr)) { 2000 m_platforms.push_back(platform_sp); 2001 return platform_sp; 2002 } 2003 } 2004 if (platform_arch_ptr) 2005 platform_arch_ptr->Clear(); 2006 return nullptr; 2007 } 2008 2009 PlatformSP PlatformList::GetOrCreate(const ArchSpec &arch, 2010 const ArchSpec &process_host_arch, 2011 ArchSpec *platform_arch_ptr) { 2012 Status error; 2013 if (arch.IsValid()) 2014 return GetOrCreate(arch, process_host_arch, platform_arch_ptr, error); 2015 return nullptr; 2016 } 2017 2018 PlatformSP PlatformList::GetOrCreate(llvm::ArrayRef<ArchSpec> archs, 2019 const ArchSpec &process_host_arch, 2020 std::vector<PlatformSP> &candidates) { 2021 candidates.clear(); 2022 candidates.reserve(archs.size()); 2023 2024 if (archs.empty()) 2025 return nullptr; 2026 2027 PlatformSP host_platform_sp = Platform::GetHostPlatform(); 2028 2029 // Prefer the selected platform if it matches at least one architecture. 2030 if (m_selected_platform_sp) { 2031 for (const ArchSpec &arch : archs) { 2032 if (m_selected_platform_sp->IsCompatibleArchitecture( 2033 arch, process_host_arch, false, nullptr)) 2034 return m_selected_platform_sp; 2035 } 2036 } 2037 2038 // Prefer the host platform if it matches at least one architecture. 2039 if (host_platform_sp) { 2040 for (const ArchSpec &arch : archs) { 2041 if (host_platform_sp->IsCompatibleArchitecture(arch, process_host_arch, 2042 false, nullptr)) 2043 return host_platform_sp; 2044 } 2045 } 2046 2047 // Collect a list of candidate platforms for the architectures. 2048 for (const ArchSpec &arch : archs) { 2049 if (PlatformSP platform = GetOrCreate(arch, process_host_arch, nullptr)) 2050 candidates.push_back(platform); 2051 } 2052 2053 // The selected or host platform didn't match any of the architectures. If 2054 // the same platform supports all architectures then that's the obvious next 2055 // best thing. 2056 if (candidates.size() == archs.size()) { 2057 if (std::all_of(candidates.begin(), candidates.end(), 2058 [&](const PlatformSP &p) -> bool { 2059 return p->GetName() == candidates.front()->GetName(); 2060 })) { 2061 return candidates.front(); 2062 } 2063 } 2064 2065 // At this point we either have no platforms that match the given 2066 // architectures or multiple platforms with no good way to disambiguate 2067 // between them. 2068 return nullptr; 2069 } 2070 2071 PlatformSP PlatformList::Create(llvm::StringRef name) { 2072 std::lock_guard<std::recursive_mutex> guard(m_mutex); 2073 PlatformSP platform_sp = Platform::Create(name); 2074 m_platforms.push_back(platform_sp); 2075 return platform_sp; 2076 } 2077