xref: /llvm-project/lldb/source/Plugins/Platform/MacOSX/PlatformMacOSX.cpp (revision 3b6a8f823bf873aa74cdb738f517e7333e20de7a)
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 
40 using namespace lldb;
41 using namespace lldb_private;
42 
43 LLDB_PLUGIN_DEFINE(PlatformMacOSX)
44 
45 static uint32_t g_initialize_count = 0;
46 
Initialize()47 void 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(PlatformMacOSX::GetPluginNameStatic(),
67                                   PlatformMacOSX::GetDescriptionStatic(),
68                                   PlatformMacOSX::CreateInstance);
69   }
70 }
71 
Terminate()72 void PlatformMacOSX::Terminate() {
73   if (g_initialize_count > 0) {
74     if (--g_initialize_count == 0) {
75       PluginManager::UnregisterPlugin(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 
GetDescriptionStatic()92 llvm::StringRef PlatformMacOSX::GetDescriptionStatic() {
93   return "Local Mac OS X user platform plug-in.";
94 }
95 
CreateInstance(bool force,const ArchSpec * arch)96 PlatformSP 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
PlatformMacOSX()103 PlatformMacOSX::PlatformMacOSX() : PlatformDarwinDevice(true) {}
104 
GetSDKDirectory(lldb_private::Target & target)105 ConstString 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("%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(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(HostInfo::SDKOptions{XcodeSDK::GetAnyMacOS()});
132   if (!sdk_path_or_err) {
133     Debugger::ReportError("Error while searching for Xcode SDK: " +
134                           toString(sdk_path_or_err.takeError()));
135     return {};
136   }
137 
138   FileSpec fspec(*sdk_path_or_err);
139   if (fspec) {
140     if (FileSystem::Instance().Exists(fspec))
141       return ConstString(fspec.GetPath());
142   }
143 
144   return {};
145 }
146 
147 std::vector<ArchSpec>
GetSupportedArchitectures(const ArchSpec & process_host_arch)148 PlatformMacOSX::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(result);
177   result.push_back(ArchSpec("x86_64-apple-ios-macabi"));
178 #endif
179   return result;
180 }
181 
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)182 lldb_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_x86_64, x86_64_module_sp, module_search_paths_ptr,
204             &old_x86_64_modules, &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(old_x86_64_modules.begin(),
209                                 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 
GetDeviceSupportDirectoryName()226 llvm::StringRef PlatformMacOSX::GetDeviceSupportDirectoryName() {
227   return "macOS DeviceSupport";
228 }
229 
GetPlatformName()230 llvm::StringRef PlatformMacOSX::GetPlatformName() { return "MacOSX.platform"; }
231