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
Initialize()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
Terminate()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
GetDescriptionStatic()89 llvm::StringRef PlatformMacOSX::GetDescriptionStatic() {
90 return "Local Mac OS X user platform plug-in.";
91 }
92
CreateInstance(bool force,const ArchSpec * arch)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
PlatformMacOSX()100 PlatformMacOSX::PlatformMacOSX() : PlatformDarwinDevice(true) {}
101
GetSDKDirectory(lldb_private::Target & target)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>
GetSupportedArchitectures(const ArchSpec & process_host_arch)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
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)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
GetDeviceSupportDirectoryName()222 llvm::StringRef PlatformMacOSX::GetDeviceSupportDirectoryName() {
223 return "macOS DeviceSupport";
224 }
225
GetPlatformName()226 llvm::StringRef PlatformMacOSX::GetPlatformName() { return "MacOSX.platform"; }
227