1 //===-- PlatformMacOSX.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 "PlatformMacOSX.h" 10 #include "PlatformRemoteMacOSX.h" 11 #include "PlatformRemoteiOS.h" 12 #if defined(__APPLE__) 13 #include "PlatformAppleSimulator.h" 14 #include "PlatformDarwinKernel.h" 15 #include "PlatformRemoteAppleBridge.h" 16 #include "PlatformRemoteAppleTV.h" 17 #include "PlatformRemoteAppleWatch.h" 18 #endif 19 #include "lldb/Breakpoint/BreakpointLocation.h" 20 #include "lldb/Core/Module.h" 21 #include "lldb/Core/ModuleList.h" 22 #include "lldb/Core/ModuleSpec.h" 23 #include "lldb/Core/PluginManager.h" 24 #include "lldb/Host/Config.h" 25 #include "lldb/Host/Host.h" 26 #include "lldb/Host/HostInfo.h" 27 #include "lldb/Symbol/ObjectFile.h" 28 #include "lldb/Target/Process.h" 29 #include "lldb/Target/Target.h" 30 #include "lldb/Utility/DataBufferHeap.h" 31 #include "lldb/Utility/FileSpec.h" 32 #include "lldb/Utility/Log.h" 33 #include "lldb/Utility/Status.h" 34 #include "lldb/Utility/StreamString.h" 35 36 #include <sstream> 37 38 using namespace lldb; 39 using namespace lldb_private; 40 41 LLDB_PLUGIN_DEFINE(PlatformMacOSX) 42 43 static uint32_t g_initialize_count = 0; 44 45 void PlatformMacOSX::Initialize() { 46 PlatformDarwin::Initialize(); 47 PlatformRemoteiOS::Initialize(); 48 PlatformRemoteMacOSX::Initialize(); 49 #if defined(__APPLE__) 50 PlatformAppleSimulator::Initialize(); 51 PlatformDarwinKernel::Initialize(); 52 PlatformRemoteAppleTV::Initialize(); 53 PlatformRemoteAppleWatch::Initialize(); 54 PlatformRemoteAppleBridge::Initialize(); 55 #endif 56 57 if (g_initialize_count++ == 0) { 58 #if defined(__APPLE__) 59 PlatformSP default_platform_sp(new PlatformMacOSX()); 60 default_platform_sp->SetSystemArchitecture(HostInfo::GetArchitecture()); 61 Platform::SetHostPlatform(default_platform_sp); 62 #endif 63 PluginManager::RegisterPlugin(PlatformMacOSX::GetPluginNameStatic(), 64 PlatformMacOSX::GetDescriptionStatic(), 65 PlatformMacOSX::CreateInstance); 66 } 67 } 68 69 void PlatformMacOSX::Terminate() { 70 if (g_initialize_count > 0) { 71 if (--g_initialize_count == 0) { 72 PluginManager::UnregisterPlugin(PlatformMacOSX::CreateInstance); 73 } 74 } 75 76 #if defined(__APPLE__) 77 PlatformRemoteAppleBridge::Terminate(); 78 PlatformRemoteAppleWatch::Terminate(); 79 PlatformRemoteAppleTV::Terminate(); 80 PlatformDarwinKernel::Terminate(); 81 PlatformAppleSimulator::Terminate(); 82 #endif 83 PlatformRemoteMacOSX::Initialize(); 84 PlatformRemoteiOS::Terminate(); 85 PlatformDarwin::Terminate(); 86 } 87 88 lldb_private::ConstString PlatformMacOSX::GetPluginNameStatic() { 89 static ConstString g_host_name(Platform::GetHostPlatformName()); 90 return g_host_name; 91 } 92 93 const char *PlatformMacOSX::GetDescriptionStatic() { 94 return "Local Mac OS X user platform plug-in."; 95 } 96 97 PlatformSP PlatformMacOSX::CreateInstance(bool force, const ArchSpec *arch) { 98 // The only time we create an instance is when we are creating a remote 99 // macosx platform which is handled by PlatformRemoteMacOSX. 100 return PlatformSP(); 101 } 102 103 /// Default Constructor 104 PlatformMacOSX::PlatformMacOSX() : PlatformDarwin(true) {} 105 106 ConstString PlatformMacOSX::GetSDKDirectory(lldb_private::Target &target) { 107 ModuleSP exe_module_sp(target.GetExecutableModule()); 108 if (!exe_module_sp) 109 return {}; 110 111 ObjectFile *objfile = exe_module_sp->GetObjectFile(); 112 if (!objfile) 113 return {}; 114 115 llvm::VersionTuple version = objfile->GetSDKVersion(); 116 if (version.empty()) 117 return {}; 118 119 // First try to find an SDK that matches the given SDK version. 120 if (FileSpec fspec = HostInfo::GetXcodeContentsDirectory()) { 121 StreamString sdk_path; 122 sdk_path.Printf("%s/Developer/Platforms/MacOSX.platform/Developer/" 123 "SDKs/MacOSX%u.%u.sdk", 124 fspec.GetPath().c_str(), version.getMajor(), 125 version.getMinor().getValue()); 126 if (FileSystem::Instance().Exists(fspec)) 127 return ConstString(sdk_path.GetString()); 128 } 129 130 // Use the default SDK as a fallback. 131 FileSpec fspec( 132 HostInfo::GetXcodeSDKPath(lldb_private::XcodeSDK::GetAnyMacOS())); 133 if (fspec) { 134 if (FileSystem::Instance().Exists(fspec)) 135 return ConstString(fspec.GetPath()); 136 } 137 138 return {}; 139 } 140 141 bool PlatformMacOSX::GetSupportedArchitectureAtIndex(uint32_t idx, 142 ArchSpec &arch) { 143 #if defined(__arm__) || defined(__arm64__) || defined(__aarch64__) 144 // macOS for ARM64 support both native and translated x86_64 processes 145 if (!m_num_arm_arches || idx < m_num_arm_arches) { 146 bool res = ARMGetSupportedArchitectureAtIndex(idx, arch); 147 if (res) 148 return true; 149 if (!m_num_arm_arches) 150 m_num_arm_arches = idx; 151 } 152 153 // We can't use x86GetSupportedArchitectureAtIndex() because it uses 154 // the system architecture for some of its return values and also 155 // has a 32bits variant. 156 if (idx == m_num_arm_arches) { 157 arch.SetTriple("x86_64-apple-macosx"); 158 return true; 159 } else if (idx == m_num_arm_arches + 1) { 160 arch.SetTriple("x86_64-apple-ios-macabi"); 161 return true; 162 } else if (idx == m_num_arm_arches + 2) { 163 arch.SetTriple("arm64-apple-ios"); 164 return true; 165 } else if (idx == m_num_arm_arches + 3) { 166 arch.SetTriple("arm64e-apple-ios"); 167 return true; 168 } 169 170 return false; 171 #else 172 return x86GetSupportedArchitectureAtIndex(idx, arch); 173 #endif 174 } 175 176 lldb_private::Status PlatformMacOSX::GetSharedModule( 177 const lldb_private::ModuleSpec &module_spec, Process *process, 178 lldb::ModuleSP &module_sp, 179 const lldb_private::FileSpecList *module_search_paths_ptr, 180 llvm::SmallVectorImpl<lldb::ModuleSP> *old_modules, bool *did_create_ptr) { 181 Status error = GetSharedModuleWithLocalCache(module_spec, module_sp, 182 module_search_paths_ptr, 183 old_modules, did_create_ptr); 184 185 if (module_sp) { 186 if (module_spec.GetArchitecture().GetCore() == 187 ArchSpec::eCore_x86_64_x86_64h) { 188 ObjectFile *objfile = module_sp->GetObjectFile(); 189 if (objfile == nullptr) { 190 // We didn't find an x86_64h slice, fall back to a x86_64 slice 191 ModuleSpec module_spec_x86_64(module_spec); 192 module_spec_x86_64.GetArchitecture() = ArchSpec("x86_64-apple-macosx"); 193 lldb::ModuleSP x86_64_module_sp; 194 llvm::SmallVector<lldb::ModuleSP, 1> old_x86_64_modules; 195 bool did_create = false; 196 Status x86_64_error = GetSharedModuleWithLocalCache( 197 module_spec_x86_64, x86_64_module_sp, module_search_paths_ptr, 198 &old_x86_64_modules, &did_create); 199 if (x86_64_module_sp && x86_64_module_sp->GetObjectFile()) { 200 module_sp = x86_64_module_sp; 201 if (old_modules) 202 old_modules->append(old_x86_64_modules.begin(), 203 old_x86_64_modules.end()); 204 if (did_create_ptr) 205 *did_create_ptr = did_create; 206 return x86_64_error; 207 } 208 } 209 } 210 } 211 212 if (!module_sp) { 213 error = FindBundleBinaryInExecSearchPaths(module_spec, process, module_sp, 214 module_search_paths_ptr, 215 old_modules, did_create_ptr); 216 } 217 return error; 218 } 219