1 //===-- PlatformRemoteMacOSX.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 <memory> 10 #include <string> 11 #include <vector> 12 13 #include "PlatformRemoteMacOSX.h" 14 15 #include "lldb/Breakpoint/BreakpointLocation.h" 16 #include "lldb/Core/Module.h" 17 #include "lldb/Core/ModuleList.h" 18 #include "lldb/Core/ModuleSpec.h" 19 #include "lldb/Core/PluginManager.h" 20 #include "lldb/Host/Host.h" 21 #include "lldb/Host/HostInfo.h" 22 #include "lldb/Target/Process.h" 23 #include "lldb/Target/Target.h" 24 #include "lldb/Utility/ArchSpec.h" 25 #include "lldb/Utility/FileSpec.h" 26 #include "lldb/Utility/Log.h" 27 #include "lldb/Utility/StreamString.h" 28 29 using namespace lldb; 30 using namespace lldb_private; 31 32 /// Default Constructor 33 PlatformRemoteMacOSX::PlatformRemoteMacOSX() : PlatformRemoteDarwinDevice() {} 34 35 // Static Variables 36 static uint32_t g_initialize_count = 0; 37 38 // Static Functions 39 void PlatformRemoteMacOSX::Initialize() { 40 PlatformDarwin::Initialize(); 41 42 if (g_initialize_count++ == 0) { 43 PluginManager::RegisterPlugin(PlatformRemoteMacOSX::GetPluginNameStatic(), 44 PlatformRemoteMacOSX::GetDescriptionStatic(), 45 PlatformRemoteMacOSX::CreateInstance); 46 } 47 } 48 49 void PlatformRemoteMacOSX::Terminate() { 50 if (g_initialize_count > 0) { 51 if (--g_initialize_count == 0) { 52 PluginManager::UnregisterPlugin(PlatformRemoteMacOSX::CreateInstance); 53 } 54 } 55 56 PlatformDarwin::Terminate(); 57 } 58 59 PlatformSP PlatformRemoteMacOSX::CreateInstance(bool force, 60 const ArchSpec *arch) { 61 Log *log(GetLogIfAllCategoriesSet(LIBLLDB_LOG_PLATFORM)); 62 if (log) { 63 const char *arch_name; 64 if (arch && arch->GetArchitectureName()) 65 arch_name = arch->GetArchitectureName(); 66 else 67 arch_name = "<null>"; 68 69 const char *triple_cstr = 70 arch ? arch->GetTriple().getTriple().c_str() : "<null>"; 71 72 LLDB_LOGF(log, "PlatformMacOSX::%s(force=%s, arch={%s,%s})", __FUNCTION__, 73 force ? "true" : "false", arch_name, triple_cstr); 74 } 75 76 bool create = force; 77 if (!create && arch && arch->IsValid()) { 78 const llvm::Triple &triple = arch->GetTriple(); 79 switch (triple.getVendor()) { 80 case llvm::Triple::Apple: 81 create = true; 82 break; 83 84 #if defined(__APPLE__) 85 // Only accept "unknown" for vendor if the host is Apple and it "unknown" 86 // wasn't specified (it was just returned because it was NOT specified) 87 case llvm::Triple::UnknownVendor: 88 create = !arch->TripleVendorWasSpecified(); 89 break; 90 #endif 91 default: 92 break; 93 } 94 95 if (create) { 96 switch (triple.getOS()) { 97 case llvm::Triple::Darwin: // Deprecated, but still support Darwin for 98 // historical reasons 99 case llvm::Triple::MacOSX: 100 break; 101 #if defined(__APPLE__) 102 // Only accept "vendor" for vendor if the host is Apple and it "unknown" 103 // wasn't specified (it was just returned because it was NOT specified) 104 case llvm::Triple::UnknownOS: 105 create = !arch->TripleOSWasSpecified(); 106 break; 107 #endif 108 default: 109 create = false; 110 break; 111 } 112 } 113 } 114 115 if (create) { 116 LLDB_LOGF(log, "PlatformRemoteMacOSX::%s() creating platform", 117 __FUNCTION__); 118 return std::make_shared<PlatformRemoteMacOSX>(); 119 } 120 121 LLDB_LOGF(log, "PlatformRemoteMacOSX::%s() aborting creation of platform", 122 __FUNCTION__); 123 124 return PlatformSP(); 125 } 126 127 std::vector<ArchSpec> PlatformRemoteMacOSX::GetSupportedArchitectures() { 128 // macOS for ARM64 support both native and translated x86_64 processes 129 std::vector<ArchSpec> result; 130 ARMGetSupportedArchitectures(result, llvm::Triple::MacOSX); 131 132 // We can't use x86GetSupportedArchitectures() because it uses 133 // the system architecture for some of its return values and also 134 // has a 32bits variant. 135 result.push_back(ArchSpec("x86_64-apple-macosx")); 136 result.push_back(ArchSpec("x86_64-apple-ios-macabi")); 137 result.push_back(ArchSpec("arm64-apple-ios")); 138 result.push_back(ArchSpec("arm64e-apple-ios")); 139 return result; 140 } 141 142 lldb_private::Status PlatformRemoteMacOSX::GetFileWithUUID( 143 const lldb_private::FileSpec &platform_file, 144 const lldb_private::UUID *uuid_ptr, lldb_private::FileSpec &local_file) { 145 if (m_remote_platform_sp) { 146 std::string local_os_build; 147 #if !defined(__linux__) 148 local_os_build = HostInfo::GetOSBuildString().getValueOr(""); 149 #endif 150 llvm::Optional<std::string> remote_os_build = 151 m_remote_platform_sp->GetOSBuildString(); 152 if (local_os_build == remote_os_build) { 153 // same OS version: the local file is good enough 154 local_file = platform_file; 155 return Status(); 156 } else { 157 // try to find the file in the cache 158 std::string cache_path(GetLocalCacheDirectory()); 159 std::string module_path(platform_file.GetPath()); 160 cache_path.append(module_path); 161 FileSpec module_cache_spec(cache_path); 162 if (FileSystem::Instance().Exists(module_cache_spec)) { 163 local_file = module_cache_spec; 164 return Status(); 165 } 166 // bring in the remote module file 167 FileSpec module_cache_folder = 168 module_cache_spec.CopyByRemovingLastPathComponent(); 169 // try to make the local directory first 170 Status err( 171 llvm::sys::fs::create_directory(module_cache_folder.GetPath())); 172 if (err.Fail()) 173 return err; 174 err = GetFile(platform_file, module_cache_spec); 175 if (err.Fail()) 176 return err; 177 if (FileSystem::Instance().Exists(module_cache_spec)) { 178 local_file = module_cache_spec; 179 return Status(); 180 } else 181 return Status("unable to obtain valid module file"); 182 } 183 } 184 local_file = platform_file; 185 return Status(); 186 } 187 188 llvm::StringRef PlatformRemoteMacOSX::GetDescriptionStatic() { 189 return "Remote Mac OS X user platform plug-in."; 190 } 191 192 llvm::StringRef PlatformRemoteMacOSX::GetDeviceSupportDirectoryName() { 193 return "macOS DeviceSupport"; 194 } 195 196 llvm::StringRef PlatformRemoteMacOSX::GetPlatformName() { 197 return "MacOSX.platform"; 198 } 199