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