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

source code of lldb/source/Plugins/Platform/MacOSX/PlatformMacOSX.cpp