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 bool PlatformRemoteMacOSX::GetSupportedArchitectureAtIndex(uint32_t idx, 128 ArchSpec &arch) { 129 // macOS for ARM64 support both native and translated x86_64 processes 130 if (!m_num_arm_arches || idx < m_num_arm_arches) { 131 bool res = ARMGetSupportedArchitectureAtIndex(idx, arch); 132 if (res) 133 return true; 134 if (!m_num_arm_arches) 135 m_num_arm_arches = idx; 136 } 137 138 // We can't use x86GetSupportedArchitectureAtIndex() because it uses 139 // the system architecture for some of its return values and also 140 // has a 32bits variant. 141 if (idx == m_num_arm_arches) { 142 arch.SetTriple("x86_64-apple-macosx"); 143 return true; 144 } else if (idx == m_num_arm_arches + 1) { 145 arch.SetTriple("x86_64-apple-ios-macabi"); 146 return true; 147 } else if (idx == m_num_arm_arches + 2) { 148 arch.SetTriple("arm64-apple-ios"); 149 return true; 150 } else if (idx == m_num_arm_arches + 3) { 151 arch.SetTriple("arm64e-apple-ios"); 152 return true; 153 } 154 155 return false; 156 } 157 158 lldb_private::Status PlatformRemoteMacOSX::GetFileWithUUID( 159 const lldb_private::FileSpec &platform_file, 160 const lldb_private::UUID *uuid_ptr, lldb_private::FileSpec &local_file) { 161 if (m_remote_platform_sp) { 162 std::string local_os_build; 163 #if !defined(__linux__) 164 HostInfo::GetOSBuildString(local_os_build); 165 #endif 166 std::string remote_os_build; 167 m_remote_platform_sp->GetOSBuildString(remote_os_build); 168 if (local_os_build == remote_os_build) { 169 // same OS version: the local file is good enough 170 local_file = platform_file; 171 return Status(); 172 } else { 173 // try to find the file in the cache 174 std::string cache_path(GetLocalCacheDirectory()); 175 std::string module_path(platform_file.GetPath()); 176 cache_path.append(module_path); 177 FileSpec module_cache_spec(cache_path); 178 if (FileSystem::Instance().Exists(module_cache_spec)) { 179 local_file = module_cache_spec; 180 return Status(); 181 } 182 // bring in the remote module file 183 FileSpec module_cache_folder = 184 module_cache_spec.CopyByRemovingLastPathComponent(); 185 // try to make the local directory first 186 Status err( 187 llvm::sys::fs::create_directory(module_cache_folder.GetPath())); 188 if (err.Fail()) 189 return err; 190 err = GetFile(platform_file, module_cache_spec); 191 if (err.Fail()) 192 return err; 193 if (FileSystem::Instance().Exists(module_cache_spec)) { 194 local_file = module_cache_spec; 195 return Status(); 196 } else 197 return Status("unable to obtain valid module file"); 198 } 199 } 200 local_file = platform_file; 201 return Status(); 202 } 203 204 lldb_private::ConstString PlatformRemoteMacOSX::GetPluginNameStatic() { 205 static ConstString g_name("remote-macosx"); 206 return g_name; 207 } 208 209 const char *PlatformRemoteMacOSX::GetDescriptionStatic() { 210 return "Remote Mac OS X user platform plug-in."; 211 } 212 213 llvm::StringRef PlatformRemoteMacOSX::GetDeviceSupportDirectoryName() { 214 return "macOS DeviceSupport"; 215 } 216 217 llvm::StringRef PlatformRemoteMacOSX::GetPlatformName() { 218 return "MacOSX.platform"; 219 } 220