1dda28197Spatrick //===-- PlatformMacOSX.cpp ------------------------------------------------===//
2061da546Spatrick //
3061da546Spatrick // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4061da546Spatrick // See https://llvm.org/LICENSE.txt for license information.
5061da546Spatrick // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6061da546Spatrick //
7061da546Spatrick //===----------------------------------------------------------------------===//
8061da546Spatrick
9061da546Spatrick #include "PlatformMacOSX.h"
10be691f3bSpatrick #include "PlatformRemoteMacOSX.h"
11dda28197Spatrick #include "PlatformRemoteiOS.h"
12dda28197Spatrick #if defined(__APPLE__)
13be691f3bSpatrick #include "PlatformAppleSimulator.h"
14dda28197Spatrick #include "PlatformDarwinKernel.h"
15dda28197Spatrick #include "PlatformRemoteAppleBridge.h"
16dda28197Spatrick #include "PlatformRemoteAppleTV.h"
17dda28197Spatrick #include "PlatformRemoteAppleWatch.h"
18dda28197Spatrick #endif
19061da546Spatrick #include "lldb/Breakpoint/BreakpointLocation.h"
20*f6aab3d8Srobert #include "lldb/Core/Debugger.h"
21061da546Spatrick #include "lldb/Core/Module.h"
22061da546Spatrick #include "lldb/Core/ModuleList.h"
23061da546Spatrick #include "lldb/Core/ModuleSpec.h"
24061da546Spatrick #include "lldb/Core/PluginManager.h"
25dda28197Spatrick #include "lldb/Host/Config.h"
26061da546Spatrick #include "lldb/Host/Host.h"
27061da546Spatrick #include "lldb/Host/HostInfo.h"
28061da546Spatrick #include "lldb/Symbol/ObjectFile.h"
29061da546Spatrick #include "lldb/Target/Process.h"
30061da546Spatrick #include "lldb/Target/Target.h"
31061da546Spatrick #include "lldb/Utility/DataBufferHeap.h"
32061da546Spatrick #include "lldb/Utility/FileSpec.h"
33061da546Spatrick #include "lldb/Utility/Log.h"
34061da546Spatrick #include "lldb/Utility/Status.h"
35061da546Spatrick #include "lldb/Utility/StreamString.h"
36061da546Spatrick
37dda28197Spatrick #include <sstream>
38dda28197Spatrick
39061da546Spatrick using namespace lldb;
40061da546Spatrick using namespace lldb_private;
41061da546Spatrick
42dda28197Spatrick LLDB_PLUGIN_DEFINE(PlatformMacOSX)
43dda28197Spatrick
44061da546Spatrick static uint32_t g_initialize_count = 0;
45061da546Spatrick
Initialize()46061da546Spatrick void PlatformMacOSX::Initialize() {
47061da546Spatrick PlatformDarwin::Initialize();
48dda28197Spatrick PlatformRemoteiOS::Initialize();
49be691f3bSpatrick PlatformRemoteMacOSX::Initialize();
50dda28197Spatrick #if defined(__APPLE__)
51be691f3bSpatrick PlatformAppleSimulator::Initialize();
52dda28197Spatrick PlatformDarwinKernel::Initialize();
53dda28197Spatrick PlatformRemoteAppleTV::Initialize();
54dda28197Spatrick PlatformRemoteAppleWatch::Initialize();
55dda28197Spatrick PlatformRemoteAppleBridge::Initialize();
56dda28197Spatrick #endif
57061da546Spatrick
58061da546Spatrick if (g_initialize_count++ == 0) {
59061da546Spatrick #if defined(__APPLE__)
60be691f3bSpatrick PlatformSP default_platform_sp(new PlatformMacOSX());
61061da546Spatrick default_platform_sp->SetSystemArchitecture(HostInfo::GetArchitecture());
62061da546Spatrick Platform::SetHostPlatform(default_platform_sp);
63061da546Spatrick #endif
64be691f3bSpatrick PluginManager::RegisterPlugin(PlatformMacOSX::GetPluginNameStatic(),
65be691f3bSpatrick PlatformMacOSX::GetDescriptionStatic(),
66061da546Spatrick PlatformMacOSX::CreateInstance);
67061da546Spatrick }
68061da546Spatrick }
69061da546Spatrick
Terminate()70061da546Spatrick void PlatformMacOSX::Terminate() {
71061da546Spatrick if (g_initialize_count > 0) {
72061da546Spatrick if (--g_initialize_count == 0) {
73061da546Spatrick PluginManager::UnregisterPlugin(PlatformMacOSX::CreateInstance);
74061da546Spatrick }
75061da546Spatrick }
76061da546Spatrick
77dda28197Spatrick #if defined(__APPLE__)
78dda28197Spatrick PlatformRemoteAppleBridge::Terminate();
79dda28197Spatrick PlatformRemoteAppleWatch::Terminate();
80dda28197Spatrick PlatformRemoteAppleTV::Terminate();
81dda28197Spatrick PlatformDarwinKernel::Terminate();
82be691f3bSpatrick PlatformAppleSimulator::Terminate();
83dda28197Spatrick #endif
84be691f3bSpatrick PlatformRemoteMacOSX::Initialize();
85dda28197Spatrick PlatformRemoteiOS::Terminate();
86061da546Spatrick PlatformDarwin::Terminate();
87061da546Spatrick }
88061da546Spatrick
GetDescriptionStatic()89*f6aab3d8Srobert llvm::StringRef PlatformMacOSX::GetDescriptionStatic() {
90be691f3bSpatrick return "Local Mac OS X user platform plug-in.";
91be691f3bSpatrick }
92be691f3bSpatrick
CreateInstance(bool force,const ArchSpec * arch)93061da546Spatrick PlatformSP PlatformMacOSX::CreateInstance(bool force, const ArchSpec *arch) {
94061da546Spatrick // The only time we create an instance is when we are creating a remote
95be691f3bSpatrick // macosx platform which is handled by PlatformRemoteMacOSX.
96061da546Spatrick return PlatformSP();
97061da546Spatrick }
98061da546Spatrick
99061da546Spatrick /// Default Constructor
PlatformMacOSX()100*f6aab3d8Srobert PlatformMacOSX::PlatformMacOSX() : PlatformDarwinDevice(true) {}
101061da546Spatrick
GetSDKDirectory(lldb_private::Target & target)102061da546Spatrick ConstString PlatformMacOSX::GetSDKDirectory(lldb_private::Target &target) {
103061da546Spatrick ModuleSP exe_module_sp(target.GetExecutableModule());
104dda28197Spatrick if (!exe_module_sp)
105dda28197Spatrick return {};
106dda28197Spatrick
107061da546Spatrick ObjectFile *objfile = exe_module_sp->GetObjectFile();
108dda28197Spatrick if (!objfile)
109dda28197Spatrick return {};
110dda28197Spatrick
111061da546Spatrick llvm::VersionTuple version = objfile->GetSDKVersion();
112dda28197Spatrick if (version.empty())
113dda28197Spatrick return {};
114061da546Spatrick
115dda28197Spatrick // First try to find an SDK that matches the given SDK version.
116dda28197Spatrick if (FileSpec fspec = HostInfo::GetXcodeContentsDirectory()) {
117061da546Spatrick StreamString sdk_path;
118dda28197Spatrick sdk_path.Printf("%s/Developer/Platforms/MacOSX.platform/Developer/"
119061da546Spatrick "SDKs/MacOSX%u.%u.sdk",
120dda28197Spatrick fspec.GetPath().c_str(), version.getMajor(),
121*f6aab3d8Srobert *version.getMinor());
122061da546Spatrick if (FileSystem::Instance().Exists(fspec))
123061da546Spatrick return ConstString(sdk_path.GetString());
124061da546Spatrick }
125061da546Spatrick
126dda28197Spatrick // Use the default SDK as a fallback.
127*f6aab3d8Srobert auto sdk_path_or_err = HostInfo::GetXcodeSDKPath(XcodeSDK::GetAnyMacOS());
128*f6aab3d8Srobert if (!sdk_path_or_err) {
129*f6aab3d8Srobert Debugger::ReportError("Error while searching for Xcode SDK: " +
130*f6aab3d8Srobert toString(sdk_path_or_err.takeError()));
131*f6aab3d8Srobert return {};
132*f6aab3d8Srobert }
133*f6aab3d8Srobert
134*f6aab3d8Srobert FileSpec fspec(*sdk_path_or_err);
135dda28197Spatrick if (fspec) {
136061da546Spatrick if (FileSystem::Instance().Exists(fspec))
137dda28197Spatrick return ConstString(fspec.GetPath());
138061da546Spatrick }
139dda28197Spatrick
140dda28197Spatrick return {};
141061da546Spatrick }
142061da546Spatrick
143*f6aab3d8Srobert std::vector<ArchSpec>
GetSupportedArchitectures(const ArchSpec & process_host_arch)144*f6aab3d8Srobert PlatformMacOSX::GetSupportedArchitectures(const ArchSpec &process_host_arch) {
145*f6aab3d8Srobert std::vector<ArchSpec> result;
146061da546Spatrick #if defined(__arm__) || defined(__arm64__) || defined(__aarch64__)
147*f6aab3d8Srobert // When cmdline lldb is run on iOS, watchOS, etc, it is still
148*f6aab3d8Srobert // using "PlatformMacOSX".
149*f6aab3d8Srobert llvm::Triple::OSType host_os = GetHostOSType();
150*f6aab3d8Srobert ARMGetSupportedArchitectures(result, host_os);
151be691f3bSpatrick
152*f6aab3d8Srobert if (host_os == llvm::Triple::MacOSX) {
153*f6aab3d8Srobert // We can't use x86GetSupportedArchitectures() because it uses
154be691f3bSpatrick // the system architecture for some of its return values and also
155be691f3bSpatrick // has a 32bits variant.
156*f6aab3d8Srobert result.push_back(ArchSpec("x86_64-apple-macosx"));
157*f6aab3d8Srobert result.push_back(ArchSpec("x86_64-apple-ios-macabi"));
158*f6aab3d8Srobert result.push_back(ArchSpec("arm64-apple-ios-macabi"));
159*f6aab3d8Srobert result.push_back(ArchSpec("arm64e-apple-ios-macabi"));
160be691f3bSpatrick
161*f6aab3d8Srobert // On Apple Silicon, the host platform is compatible with iOS triples to
162*f6aab3d8Srobert // support unmodified "iPhone and iPad Apps on Apple Silicon Macs". Because
163*f6aab3d8Srobert // the binaries are identical, we must rely on the host architecture to
164*f6aab3d8Srobert // tell them apart and mark the host platform as compatible or not.
165*f6aab3d8Srobert if (!process_host_arch ||
166*f6aab3d8Srobert process_host_arch.GetTriple().getOS() == llvm::Triple::MacOSX) {
167*f6aab3d8Srobert result.push_back(ArchSpec("arm64-apple-ios"));
168*f6aab3d8Srobert result.push_back(ArchSpec("arm64e-apple-ios"));
169*f6aab3d8Srobert }
170*f6aab3d8Srobert }
171061da546Spatrick #else
172*f6aab3d8Srobert x86GetSupportedArchitectures(result);
173*f6aab3d8Srobert result.push_back(ArchSpec("x86_64-apple-ios-macabi"));
174061da546Spatrick #endif
175*f6aab3d8Srobert return result;
176061da546Spatrick }
177061da546Spatrick
GetSharedModule(const lldb_private::ModuleSpec & module_spec,Process * process,lldb::ModuleSP & module_sp,const lldb_private::FileSpecList * module_search_paths_ptr,llvm::SmallVectorImpl<lldb::ModuleSP> * old_modules,bool * did_create_ptr)178061da546Spatrick lldb_private::Status PlatformMacOSX::GetSharedModule(
179061da546Spatrick const lldb_private::ModuleSpec &module_spec, Process *process,
180061da546Spatrick lldb::ModuleSP &module_sp,
181061da546Spatrick const lldb_private::FileSpecList *module_search_paths_ptr,
182dda28197Spatrick llvm::SmallVectorImpl<lldb::ModuleSP> *old_modules, bool *did_create_ptr) {
183dda28197Spatrick Status error = GetSharedModuleWithLocalCache(module_spec, module_sp,
184dda28197Spatrick module_search_paths_ptr,
185dda28197Spatrick old_modules, did_create_ptr);
186061da546Spatrick
187061da546Spatrick if (module_sp) {
188061da546Spatrick if (module_spec.GetArchitecture().GetCore() ==
189061da546Spatrick ArchSpec::eCore_x86_64_x86_64h) {
190061da546Spatrick ObjectFile *objfile = module_sp->GetObjectFile();
191061da546Spatrick if (objfile == nullptr) {
192061da546Spatrick // We didn't find an x86_64h slice, fall back to a x86_64 slice
193061da546Spatrick ModuleSpec module_spec_x86_64(module_spec);
194061da546Spatrick module_spec_x86_64.GetArchitecture() = ArchSpec("x86_64-apple-macosx");
195061da546Spatrick lldb::ModuleSP x86_64_module_sp;
196dda28197Spatrick llvm::SmallVector<lldb::ModuleSP, 1> old_x86_64_modules;
197061da546Spatrick bool did_create = false;
198061da546Spatrick Status x86_64_error = GetSharedModuleWithLocalCache(
199061da546Spatrick module_spec_x86_64, x86_64_module_sp, module_search_paths_ptr,
200dda28197Spatrick &old_x86_64_modules, &did_create);
201061da546Spatrick if (x86_64_module_sp && x86_64_module_sp->GetObjectFile()) {
202061da546Spatrick module_sp = x86_64_module_sp;
203dda28197Spatrick if (old_modules)
204dda28197Spatrick old_modules->append(old_x86_64_modules.begin(),
205dda28197Spatrick old_x86_64_modules.end());
206061da546Spatrick if (did_create_ptr)
207061da546Spatrick *did_create_ptr = did_create;
208061da546Spatrick return x86_64_error;
209061da546Spatrick }
210061da546Spatrick }
211061da546Spatrick }
212061da546Spatrick }
213061da546Spatrick
214061da546Spatrick if (!module_sp) {
215dda28197Spatrick error = FindBundleBinaryInExecSearchPaths(module_spec, process, module_sp,
216dda28197Spatrick module_search_paths_ptr,
217dda28197Spatrick old_modules, did_create_ptr);
218061da546Spatrick }
219061da546Spatrick return error;
220061da546Spatrick }
221*f6aab3d8Srobert
GetDeviceSupportDirectoryName()222*f6aab3d8Srobert llvm::StringRef PlatformMacOSX::GetDeviceSupportDirectoryName() {
223*f6aab3d8Srobert return "macOS DeviceSupport";
224*f6aab3d8Srobert }
225*f6aab3d8Srobert
GetPlatformName()226*f6aab3d8Srobert llvm::StringRef PlatformMacOSX::GetPlatformName() { return "MacOSX.platform"; }
227